#! /bin/sh
# BLURB gpl
# 
#                            Coda File System
#                               Release 6
# 
#           Copyright (c) 1987-2003 Carnegie Mellon University
#                   Additional copyrights listed below
# 
# This  code  is  distributed "AS IS" without warranty of any kind under
# the terms of the GNU General Public Licence Version 2, as shown in the
# file  LICENSE.  The  technical and financial  contributors to Coda are
# listed in the file CREDITS.
# 
#                         Additional copyrights
#                            none currently
# 
#*/

prefix=/usr/local
exec_prefix=${prefix}

echon() {
    if [ "`echo -n`" ] ; then
        echo "$@"\c
    else
        echo -n "$@"
    fi
}

PATH=$PATH:${prefix}/sbin
export PATH

# load the server configuration file
vicedir=/vice
. "`${exec_prefix}/sbin/codaconfedit server.conf`"

if [ ! -f ${vicedir}/hostname -o ! -f ${vicedir}/db/scm ] ; then
   echo "Coda server configuration error.  Could not find needed files."
   exit 1
fi

# Ensure that this is the SCM
if [ `cat ${vicedir}/hostname` != `cat ${vicedir}/db/scm` ]; then
	echo "This must be run from the scm (`cat ${vicedir}/db/scm`)"
	exit 1
fi

# Parse arguments
if  [ $# -lt 2 ]; then
	echo "bad args:  createvol_rep <volname> <server>[/<partition>] [<server>[/<partition>]]* [groupid]"
	exit 1
fi

# Initialize local variables
SERVERS=
PARTITIONS=
NSERVERS=0
MAXSERVERS=8

# deal with Parameters 
VOLNAME="$1"

# The maximum volume name length is really 32 characters, but we have to allow
# for the trailing \0 and we append '.N' to the individual replica names.
MAXVOLNAMELEN=29
VOLNAMELENGTH=${#VOLNAME}

if [ "$VOLNAMELENGTH" -gt "$MAXVOLNAMELEN" ]; then
    echo "Volume name \"$VOLNAME\" too long."
    echo "  it should be at most $MAXVOLNAMELEN characters"
    exit 1
fi

# Hmm, we sometimes need to use the volumename in regular expressions
# As a result we can't use a lot of special characters, but having at
# least '/' would be nice.
_VOLNAME=`echo ${VOLNAME} | sed 's&/&\\\/&g'`

#
# Create these files if they don't already exist.

# VRList was moved from vice/vol to vice/db in Coda 5.3.11
if [ ! -f "${vicedir}/db/VRList" -a -f "${vicedir}/vol/VRList" ] ; then
  echo "Moving ${vicedir}/vol/VRList to ${vicedir}/db"
  cp "${vicedir}/vol/VRList" "${vicedir}/db/VRList" && rm ${vicedir}/vol/VRList
  # Need to replicate VRList and maxgroupid too
  echo VRList >> "${vicedir}/db/files"
  echo maxgroupid >> "${vicedir}/db/files"
fi
touch "${vicedir}/db/VRList"

# Dump the VRDB from RVM into a temporary VRList list
rm -f "${vicedir}/db/VRList.new"
volutil -h `cat ${vicedir}/db/scm` dumpvrdb "${vicedir}/db/VRList.new" 2>/dev/null
if [ $? -ne 0 ]; then
    echo "Failed to dump the current VRDB into ${vicedir}/db/VRList.new"
    exit 1
fi

if [ x$VOLNAME = "x`awk ' $1 ~ /^'${_VOLNAME}'$/  {print $1}' ${vicedir}/db/VRList.new`" ]; then
	echo "Volume $VOLNAME already exists in ${vicedir}/db/VRList"
	exit 1
fi

while [ $# -gt 1 ]; do
	shift
	PRE=`echo $1 | sed 's/\(..\).*/\1/'`
	if [ "$PRE" = "7f" -o "$PRE" = "7F" ] ; then
	    GROUPID="$1"
	    break
	fi
	SERVER="`echo "$1" | sed 's/\([^\/]*\).*/\1/'`"
	PART="`echo "$1" | sed 's/[^\/]*\(.*\)/\1/'`"

	# Validate the server
	grep $SERVER ${vicedir}/db/servers > /dev/null 
	if [ $? -ne 0 ];  then
		echo Server $SERVER not in servers file
		exit 1
	fi

	volutil -h "$SERVER" getvolumelist "/tmp/vollist.$$" 2>/dev/null

	# Validate the <volname> parameter
	egrep '^[WRB]'"${_VOLNAME}"' ' "/tmp/vollist.$$" >/dev/null
	if [ $? -eq 0 ] ; then
	    echo "$VOLNAME already exists as a non replicated volume on $SERVER"
	    exit 1
	fi

	egrep '^[WRB]'"${_VOLNAME}"'\.[0-7] ' "/tmp/vollist.$$" >/dev/null
	if [ $? -eq 0 ] ; then
	    echo "$VOLNAME already exists as a replica on $SERVER"
	    exit 1
	fi

	grep "^P" "/tmp/vollist.$$" | sed 's/^P\(.*\) H.*/\1/' > "/tmp/part.$$"
	np=`cat "/tmp/part.$$" | wc -w`
	if [ $np -eq 0 ]; then
	    echo Found no partitions for server $SERVER.
	    exit 1
	fi 
        if [ -z "$PART" ]; then
	    if [ $np -gt 1 ]; then
		echo Found 2 or more partitions for server $SERVER.   You
		echo must specify a partition.
		exit 1
	    fi
	    PART="`cat /tmp/part.$$`"
	fi
	grep "^$PART\$" "/tmp/part.$$" >/dev/null
	if [ $? -ne 0 ] ; then
	    echo Partition $PART not found on server $SERVER.
	    exit 1;
	fi
	rm -f "/tmp/vollist.$$" "/tmp/part.$$"

	NSERVERS=`expr $NSERVERS + 1`
	SERVERS="$SERVERS $SERVER"
	PARTS="$PARTS $PART"
done

if [ $NSERVERS -eq 0 -o $NSERVERS -gt $MAXSERVERS ]; then
	echo Specify 1 - $MAXSERVERS servers
	exit 1
fi 

# Allocate a new groupid if necessary
if  [ -z "$GROUPID" ]; then
# New location for maxgroupid -- move it.
        if  [ -f ${vicedir}/vol/maxgroupid ]; then
		mv ${vicedir}/vol/maxgroupid ${vicedir}/db/maxgroupid
	fi
	if  [ -f ${vicedir}/db/maxgroupid ]; then
		MAXGROUPID=`cat ${vicedir}/db/maxgroupid`
		GROUPID=`printf %x $MAXGROUPID`
		MAXGROUPID=`expr $MAXGROUPID + 1`
		echo $MAXGROUPID > ${vicedir}/db/maxgroupid
	else
		echo ${vicedir}/db/maxgroupid not found
		exit 1
	fi
fi

echo "Replicated volumeid is $GROUPID"

# strip leading whitespace
PARTS=${PARTS#* }

# Create the new volumes
N=0
ENTRY="$VOLNAME $GROUPID $NSERVERS"
for SERVER in $SERVERS ; do
        PART=${PARTS%% *}
	PARTS=${PARTS#* }

	echo "creating volume $VOLNAME.$N on $SERVER (partition $PART)" 
	volutil -h $SERVER create_rep $PART $VOLNAME.$N $GROUPID > "/tmp/out.$$"
	if [ $? -ne 0 ]; then 
		echo "Failure to make volume on $SERVER!. Abort.".
		exit 1
	fi

	# grab the volume number.
	volnum=`cut -d' ' -f2 "/tmp/out.$$"`
	ENTRY="$ENTRY $volnum"
	N=`expr $N + 1`
done
rm -f "/tmp/out.$$"

# HACK, disable resolution on singly replicated volumes. The server should
# really be doing this.
if [ $NSERVERS -eq 1 ] ; then
    volutil -h $SERVERS setlogparms $volnum reson 0
fi

# Rebuild the VLDB
bldvldb.sh $SERVERS

# Update the VRList and rebuild the VRDB
# We already got the replica id's.
# add nulentries
while [ $N -lt 8 ] ; do
        ENTRY="$ENTRY 0"
	N=`expr $N + 1`
done

echo "<echo $ENTRY >> ${vicedir}/db/VRList.new>"
echo $ENTRY >> ${vicedir}/db/VRList.new
volutil makevrdb ${vicedir}/db/VRList.new

if [ $? -ne 0 ]; then
    echo "Failed to create a new VRDB file from ${vicedir}/db/VRList.new"
    exit 1
fi

# All seemed to have gone well. Make a backup of the old VRList and move the
# new VRList in it's place.
mv ${vicedir}/db/VRList ${vicedir}/db/VRList.old
mv ${vicedir}/db/VRList.new ${vicedir}/db/VRList

echon "Do you wish this volume to be Backed Up (y/n)? [n] "

read _ans_

if  [ x$_ans_ = xy -o x$_ans_ = xyes ]; then
    echon "Day to take full dumps: [Mon] "

    read day

    if [ x"$day" = x"" ]; then 
	day="Mon"	
    fi

    case $day in 
       [Ss][Uu][Nn]*)
	    _cycle_="FIIIIII" ;;
	[Mm][Oo][Nn]*)
	    _cycle_="IFIIIII" ;;
	[Tt][Uu][Ee]*)
	    _cycle_="IIFIIII" ;;
	[Ww][Ee][Dd]*)
	    _cycle_="IIIFIII" ;;
	[Tt][Hh][Uu]*)
	    _cycle_="IIIIFII" ;;
	[Ff][Rr][Ii]*)
	    _cycle_="IIIIIFI" ;;
	[Ss][Aa][Tt]*)
	    _cycle_="IIIIIIF" ;;
	*) 
            echo "$day" is not a valid day, not adding $VOLNAME to backup list.
	    exit 
	    ;;
    esac

    echo "echoing $HEXGROUPID        $_cycle_        $VOLNAME >>${vicedir}/db/dumplist"
    echo "$HEXGROUPID        $_cycle_         $VOLNAME" >>${vicedir}/db/dumplist

    # Generate a disklist for Amanda while we're at it
    #for SERVER in $SERVERS ; do
    #	echo $SERVER $VOLNAME coda >> ${vicedir}/db/disklist.amanda
    #done
fi

