#!/bin/sh
VERSION='0.7'
#
#    Copyright (C) 2002-2010 Ola Lundqvist <ola@inguza.com>
#    Copyright (C) 2002      Paul Sladen   <vserver@paul.sladen.org>
#    Copyright (C) 2002      Mark Lawrence <nomad@null.net>
#
# This is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free
# Software Foundation; either version 2, or (at your option) any later
# version.
# 
# This is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
# 
# You should have received a copy of the GNU General Public License with
# the source package as the file COPYING.  If not, write to the Free
# Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
# MA 02110-1301, USA.

VSERVERS_ROOT=/etc/vservers/.defaults/vdirbase

if [ -r /etc/vservers.conf ] ; then
    . /etc/vservers.conf
fi

symlinkdest()
{
    ls -l $* | sed -e "s|.*->[[:space:]]||;"
}

usage ()
{
    cat << EOF 1>&2
usage:	${0##*/} [OPTIONS] --ip n --from from --to to
	(see --help for more information)
EOF
}
full_usage ()
{
    cat << EOF
Usage:	${0##*/} [OPTIONS] --ip n --from from --to to
Copy an old Debian vserver to a new name

Copyright (C) 2002-2008 Ola Lundqvist <ola@inguza.com>
Copyright (C) 2002      Paul Sladen   <vserver@paul.sladen.org>
Copyright (C) 2002      Mark Lawrence <nomad@null.net>

Options:
        -h, --help		this help
        -V, --version		copyright and version information
	-v, --verbose		show extra output during setup
	--vsroot		location of "/vserver/" directory
	--dev			The network device to use for the new server.
	--force			Force duplication even if the new one eists.
Required:
	--from			hostname for old vserver (eg. "alpha")
	--to			hostname for new vserver (eg. "beta")
	--ip			IPv4 address for new vserver

EOF
}
full_version ()
{
    cat << EOF
${0##*/} version $VERSION
Copyright (C) 2002-2008 Ola Lundqvist <ola@inguza.com>
Copyright (C) 2002 Mark Lawrence <nomad@null.net>
Copyright (C) 2002 Paul Sladen   <vserver@paul.sladen.org>

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.

EOF
}
parse_args ()
{
    while [ $# -gt 0 ] ; do
	#echo "parse_args() doing :$#: :$1: :$*:"
	case "$1" in
	    --help|-h)
		full_usage
		shift
		exit 0
		;;
	    --version|-V)
		full_version
		shift
		exit 0
		;;
	    --dev)
		TODEV="$2"
		shift 2
		;;
	    --force)
		FORCE=yes
		shift
		;;
	    --from)
		FROM="$2"
		shift 2
		if [ ! -r "/etc/vservers/$FROM.conf" ] && [ ! -d "/etc/vservers/$FROM" ] ; then
		    echo "ERROR: Vserver config for $FROM do not exist."
		    exit 1
		fi
		if [ -r "/etc/vservers/$FROM.conf" ] ; then
		    . /etc/vservers/$FROM.conf
		    FROMNAME=$S_HOSTNAME
		    FROMIP=$IPROOT
		    FROMDEV=$IPROOTDEV
		fi
		if [ -d "/etc/vservers/$FROM" ] ; then
		    FROMNAME=$(cat /etc/vservers/$FROM/name)
		    FROMIP=$(cat /etc/vservers/$FROM/interfaces/0/ip)
		    FROMDEV=$(cat /etc/vservers/$FROM/interfaces/0/dev)
		fi
		;;
	    --to)
		TO="$2"
		shift 2
		;;
	    --ip)
	        # This does for an octet: ([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]) ;-)
	        case "$2" in
		    [0-9]*.[0-9]*.[0-9]*.[0-9]*)
		        TOIP="$2"
			;;
		    *)
			echo "${0##*/} error: $1 requires a single IPv4  e.g. \"192.168.100.1\"" 1>&2
			exit 1
			;;
		esac
		shift 2
		;;
	    --verbose|-v)
		export verbose="true"
		shift
		;;
	    --vsroot)
	        if [ -d "$2" ]; then
		    VSERVERS_ROOT="$2"
		else
		    echo "${0##*/} error: $1 needs a valid absolute directory"  1>&2
		    echo 'e.g. "/vservers or /etc/vservers/.defaults/vdirbase"' 1>&2
		    exit 1
		fi
		shift 2
		;;
	    -*)
	        usage
	        exit 1
		;;
	    ?*)
	        usage
		exit 1
	    ;;
	esac
    done
}

parse_args $@

if ! [ -n "$FROM" -a -n "$TO" -a -n "$TOIP" ]; then
    echo "${0##*/} error: --from, --to and --ip are required" 1>&2
    usage
    exit 1
fi

if [ ! -d $VSERVERS_ROOT/$TO -o "$FORCE" = "yes" ] ; then
    mkdir -p $VSERVERS_ROOT/$TO
    rsync -a --delete \
	--exclude=/proc --exclude=/dev/pts\
	$VSERVERS_ROOT/$FROM/ $VSERVERS_ROOT/$TO
    mkdir -p $VSERVERS_ROOT/$TO/proc
    mkdir -p $VSERVERS_ROOT/$TO/dev/pts
    FINDTOREPNAME="$VSERVERS_ROOT/$TO/etc/hostname $VSERVERS_ROOT/$TO/etc/hosts $VSERVERS_ROOT/$TO/etc/motd"
    perl -pi -e "s#$FROM#$TO#g;" \
	$FINDTOREPNAME
    if [ "$FROMIP" != "$TOIP" -o "$FORCE" = "yes" ] ; then
	FINDTOREPIP=$(rgrep -I "$FROMIP" $VSERVERS_ROOT/$TO/etc/ 2>&1 | sed -e "s/:.*//;" | grep -v "^grep$" | sort -u)
	if [ -n "$FINDTOREPIP" ] ; then
	    perl -pi -e "s#$FROMIP#$TOIP#g;" \
		$FINDTOREPIP
	fi
    fi
    echo "Changed the following files:"
    echo "$FINDTOREPNAME
$FINDTOREPIP" | sort -u
fi

if [ -r /etc/vservers/$FROM.conf ] ; then
    if [ ! -r /etc/vservers/$TO.conf ] || [ "$FORCE" = "yes" ] ; then
	cp /etc/vservers/$FROM.conf /etc/vservers/$TO.conf
	perl -pi -e "s#$FROM#$TO#g;" \
	    /etc/vservers/$TO.conf
	if [ "$FROMIP" != "$TOIP" ] ; then
	    perl -pi -e "s#$FROMIP#$TOIP#g;" \
		/etc/vservers/$TO.conf
	fi
	if [ "$FROMDEV" != "$TODEV" -a -n "$TODEV" ] ; then
	    perl -pi -e "s#$FROMDEV#$TODEV#g;" \
		/etc/vservers/$TO.conf
	fi
    fi
fi
if [ -d /etc/vservers/$FROM ] ; then
    if [ ! -d /etc/vservers/$TO ] || [ "$FORCE" = "yes" ] ; then
	mkdir -p /etc/vservers/$TO
	rsync -a --delete \
	    /etc/vservers/$FROM/ /etc/vservers/$TO
	# Replace run
	if [ -L /etc/vservers/$TO/run ] ; then
	    NEWRUN=$(symlinkdest /etc/vservers/$TO/run | sed -e "s|$FROM|$TO|;")
	    rm -f /etc/vservers/$TO/run
	    ln -s $NEWRUN /etc/vservers/$TO/run
	fi
	# Replace vdir
	if [ -L /etc/vservers/$TO/vdir ] ; then
	    NEWVDIR=$(symlinkdest /etc/vservers/$TO/vdir | sed -e "s|$FROM|$TO|;")
	    rm -f /etc/vservers/$TO/vdir
	    ln -s $NEWVDIR /etc/vservers/$TO/vdir
	fi
	# Replace cache
	if [ -L /etc/vservers/$TO/cache ] ; then
	    NEWCACHE=$(symlinkdest /etc/vservers/$TO/cache | sed -e "s|$FROM|$TO|;")
	    rm -f /etc/vservers/$TO/cache
	    ln -s $NEWCACHE /etc/vservers/$TO/cache
	fi
	# Replace some more
	echo $TO > /etc/vservers/$TO/name
	echo $TO > /etc/vservers/$TO/uts/nodename
	TT=$(find /etc/vservers/$TO/interfaces -type f -name name)
	if [ -n "$TT" ] ; then
	    perl -pi -e "s#$FROM#$TO#g;" $TT
	fi
	if [ "$FROMIP" != "$TOIP" ] && [ -n "$FROMIP" ] && [ -n "$TOIP" ] ; then
	    TT=$(find /etc/vservers/$TO/interfaces/ -type f -name ip)
	    if [ -n "$TT" ] ; then
		perl -pi -e "s#$FROMIP#$TOIP#g;" $TT
	    fi
	fi
	if [ "$FROMDEV" != "$TODEV" ] && [ -n "$FROMDEV" ] && [ -n "$TODEV" ] ; then
	    TT=$(find /etc/vservers/$TO/interfaces/ -type f -name dev)
	    perl -pi -e "s#$FROMDEV#$TODEV#g;" $TT
	fi
    fi
fi
