#! /usr/local/bin/setuid -r
#? /bin/sh /u/dump/bin/localtar
#
#  - Stuart Levy, Geometry Group, April 1989
#
# localtar [-n] [-a] [-G] [-N yy.mm.dd[.hh.mm[.ss]]] filesystem ...
#
# Privileged shell script.  Gnutar's the specified filesystem(s) to
# mag tape $TAPE.  Updates the ./toc file and optionally writes it to
# tape following the tar image.
#
# -n  Don't write ./toc after the tar image.
# -a  Preserve access times on files in the filesystem's.
#     Unfortunately this means their inode-change times are updated,
#     so this screws up incrementals -- all those files will be
#     dumped on the next incremental.
# -N yy.mm.dd...
#     Dump only files modified since the specified date&time.
# -G  Generate Gnutar incremental information (needed even on level-0 "tar"s),
#     also add volume header of `hostname`:filesys1:filesys2:...
#     Unfortunately it generates tar images incompatible with many other tars.
#
#
# One or two lines are added to the ./toc (tape table-of-contents) file:
# `hostname`  "-"  filesys1:filesys2:...   yy.mm.dd.hh.mm  nbytes  "tar"  yy.mm.dd.hh.mm
# The first date is the present moment; the second is the date since which
# this dump was taken, if an incremental. 
# If a copy of the toc is written to tape another line is appended to toc:
# "Table" "of" "contents"  yy.mm.dd.hh.mm  nbytes  "toc"
#


CPU=`cat /etc/cputype`
PATH=/u/dump/bin:/usr/local/bin:/usr/local/bin.$CPU:/usr/ucb:/usr/bsd:/bin:/usr/bin:/etc:/usr/etc
TAPE=${TAPE:-/dev/nrrt0}
BSIZE=${BSIZE:-64512}

DATE="`date +%y.%m.%d.%H.%M`"
since=
notoc=
atime=
dognu=

while :
do
    case "$1" in
	-N) since="$2" ; shift 2 ;;
	-n) notoc=-n   ; shift ;;
	-a) atime=-a   ; shift ;;
	-G|-V) dognu=-GV ; shift ;;
	-C) break ;;
	-*) shift $#   ; break ;; # force Usage message
	*)  break ;;
    esac
done

if [ "$1" = "" ]; then
	echo >&2 \
"Usage:	$0 [-n] [-a] [-G] [-N yy.mm.dd[.hh.mm]]  /filesystem ...
Do GNU tar dump of filesystem(s) or file subtree(s) on local host.
Writes to tape given by envariable TAPE.
Updates ./toc file; also writes ./toc to tape after dump unless -n given.
-a : preserve access times of tarred files (but screw up later incrementals).
-N yy.mm.dd... : dump only files changed since that date/time.
Uses -lGV gnutar options."
	exit 2
fi

if [ ! -w toc ]; then
	echo "$0: must have ./toc present and writable.  Run gettoc first." >&2
	exit 1
fi

# Security check.  We should only be executed by uid "dump"!
# SETUID_REALUSER provided by a hack to /usr/local/bin/setuid.

case "$SETUID_REALUSER" in
    dump|root) ;;
    *) echo "$0 may only be invoked by user 'dump'.  Go away." >&2; exit 3 ;;
esac

host="`hostname`"
volnames="`echo $* | tr ' \11' ::`"
case "$1" in
	/*) fs="-C $1 ." ;;
	*)  fs="$1" ;;
esac
shift
fs="$fs $*"

# Parse "since" date into something gnutar can read.
OIFS="$IFS"; IFS=". 	"
set -- x $since
IFS="$OIFS"
shift
case $# in
	0) gdate= ;;
	3)
	    gdate="$2/$3/$1" ;;
	4)
	    case "$1#$2#$3#$4" in
		[0-9]*#[0-9]*#[0-9]*#[0-9]*:*)
			gdate="$2/$3/$1 $4"
			;;
		*)
			echo "$0: what kind of yy.mm.dd.hh.mm spec is '$since'?  I quit." >&2
			exit 4
			;;
	    esac
	    ;;
	5)  gdate="$2/$3/$1 $4:$5" ;;
	6)  gdate="$2/$3/$1 $4:$5:$6" ;;
	*)
	    echo "$0: what kind of yy.mm.dd spec is '$since'?  I quit." >&2
	    exit 4
	    ;;
esac

# Now for it!

TEMP=/tmp/buffer.$$

if [ "$dognu" != "" ]; then
	dognu="-GV ${host}:${volnames}"
fi
if [ "$gdate" != "" ]; then
	level="-1"
	gnutar -cl ${dognu} ${atime} -f - -N "${gdate}" -- $fs | \
	buffer $BSIZE >$TAPE 2> $TEMP
else
	level="0"
	gnutar -cl ${dognu} ${atime} -f - -- $fs | \
	buffer $BSIZE >$TAPE 2> $TEMP
fi

set --  "" `grep 'bytes copied' $TEMP`
if [ "$7" = "" -o "$7" = "0" ]; then
	echo $host ${volnames} FAILED ${DATE} 0 tar >>./toc
	rm -f $TEMP
	exit 1
fi

echo ${host} ${volnames} ${level} ${DATE} $2 "tar" ${gdate} >>./toc

if [ "$notoc" = "" ]; then
	cp ./toc $TEMP
	echo Table of contents `date +%y.%m.%d.%H.%M` $BSIZE toc >>$TEMP
	if dd if=./toc of=$TAPE bs=$BSIZE conv=sync; then
		cp $TEMP ./toc
	else
		echo $0: Error writing table-of-contents to $TAPE >&2
		rm -f $TEMP
		exit 1
	fi
fi
exit 0
