#!/bin/sh -

# xcopy, copy files to multiple disks
# 
# $Id: xcopy,v 2.2 1997/05/30 07:52:41 cdua Exp cdua $
# Carlos Duarte, 961215/970523

# free space on a diskette em 1024 blocks (rounded down)
free() {
	mdir $1: | sed '
s/bytes free//
ta
d
:a
y/	/ /
s/ //g
s:.*:& 1024 / p:
' | dc
}

mktemp() {
	# local doesnt exist on many systems
	#local tmp=/tmp/xcp$$
	tmp=/tmp/xcp$$

	i=0
	while [ -f "$tmp,$i" ]
	do
		i=`expr $i + 1`
	done

	echo "$tmp,$i"
}

# get 'ls -ald' fields where are the size and name of file
# return is: 'size_field name_field' on one line
#
# both fields are zero, if at least one could not be determined
#
get_ls_field() {
	F1=/tmp/xty2.$$
	F2=/tmp/xty4.$$

	cat > $F1 <<eof
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
eof

	cat > $F2 <<eof
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
eof

	S1=`wc -c < $F1`
	S2=`wc -c < $F2`

	(
		echo $S1 $F1
		ls -ald $F1 
		echo $S2 $F2
		ls -ald $F2 
	) | awk '
	{
		size = $1
		name = $2
		getline
		for (i=1; i <= NF; i++) {
			if ($i == size) sz_f = i
			if ($i == name) nm_f = i
		}

		if (! name_f) name_f = nm_f; 
		if (! size_f) size_f = sz_f; 

		if (name_f != nm_f) { err = 1; exit; }
		if (size_f != sz_f) { err = 1; exit; }
	}

	END {
		if (err) { print "0 0"; exit 1; }

		print size_f " " name_f
	}'

	rm -f $F1 $F2
}

usage() {
	# local d=...
	# d=`echo "usage: $0 [-n] [-m] [-d drive] [-t] " \
	#	 | cut -d\[ -f1 \
	#	 | wc -c`
	# echo "usage: $0 [-n] [-m] [-d drive] [-t] "
	# while [ $d -gt 10 ]; do echo -n "          "; d=`expr $d - 10`; done
	# while [ $d -gt 1 ]; do echo -n " "; d=`expr $d - 1`; done
	# echo "[-f freespace] [-h] [-w] files... "

	( cat <<eof
-n	fake, i.e. dont do commands
-m	move files, i.e. delete files after copy
-d drive
	specify drive: a, b, ...
-t	toggle between drive a and b automatically after each copy
-f	specify freespace on destination media
-h	this help
-w	wipe out media contents before the copy
-e	do eject command after filling disk 
eof

) | awk -v prog="$0" '
! /\t/ {
	opt[++ocnt] = "[" $1
	for (i=2; i <= NF; i++) {
		opt[ocnt] = opt[ocnt] " " $i
	}
	opt[ocnt] = opt[ocnt] "]"
	for (;;) {
		x[++count] = $0
		if (getline != 1) exit
		if ($0 !~ /^\t/) break; 
	}
}

{
	n = split($0, tab, "\t"); 
	opt[++ocnt] = "[" tab[1] "]"
	x[++count] = $0
	next; 
}

END {
	u = sprintf ("usage: %s", prog); 
	v = u 
	gsub(".", " ", v)
	i=1; 
	while (i <= ocnt) {
		while (length(u " " opt[i]) <= 66) {
			u = u " " opt[i]
			if (++i > ocnt) break; 
		}
		print u 
		u = v
	}
	# print "" 
	for (i=1; i <= count; i++) {
		print "  " x[i]
	}
}
'
	exit 1
}

# main

FAKE=0
MOVE=0
DRIVE=a
TOGGLE=0
WIPE=:
while [ x"$1" != x"" ]
do
	case `echo z$1|cut -c2-3` in 
	-n) 	FAKE=1 ;; 
	-m)	MOVE=1 ;;
	-d)	DRIVE=`echo $1|cut -c3-`
		[ "$DRIVE" = "" ] && {
			shift
			DRIVE=$1
			[ "$DRIVE" = "" ] && break
		} ;; 
	-t)	TOGGLE=1 ;;
	-f)	USERFREE=`echo $1|cut -c3-`
		[ "$USERFREE" = "" ] && {
			shift
			USERFREE=$1
			[ "$USERFREE" = "" ] && break
		} ;; 
	-h) 	usage ;;
	-w)	WIPE=mdel ;;
	-e)	EJECT=eject ;; 
	*)	break ;;
	esac
	shift
done

if [ ! "$1" ] ; then
	usage
fi

TEMP="`mktemp`"

get_ls_field | ( 

	read SIZE_F NAME_F 
	ls -ald $* | awk -v sz_f=$SIZE_F -v nm_f=$NAME_F '
	{ 
		blocks = $sz_f / 1024
		if (($sz_f % 1024) != 0) {
			blocks++; 
		}

		printf "%10d %s\n", blocks, $nm_f
	}' > $TEMP
)

while : 
do

#$WIPE ${DRIVE}:"*"
$WIPE ${DRIVE}:

if [ "$USERFREE" ] 
then
	FREE=$USERFREE
else
	FREE="`free $DRIVE`"
fi

awk \
	-v free=$FREE \
	-v temp=$TEMP \
	-v drive=$DRIVE \
	-v fake=$FAKE \
	-v move=$MOVE \
'

 	BEGIN {
# 		free -= 5
		tsi=0
		sum=0
 	}

	{
		if (sum + $1 < free) {
			sum += $1
			togo = togo " " $2
		} else {
			tostay[tsi] = $0
			tsi += 1
		}
	}

	END {
		printf "" > temp
		for (i=0; i<tsi; i++) {
			print tostay[i] >> temp
		}

		if (sum != 0) {
			cmd= "mcopy" togo " " drive ":"
			if (fake) {
				print cmd
			} else {
				system(cmd)
			}

			if (move) {
				if (fake) 
					print "rm -f " togo
				else
					system("rm -f " togo); 
			}
		}
	}
' $TEMP

[ -s $TEMP ] || break 

if [ "$TOGGLE" = "1" ] ; then
	if [ "$DRIVE" = "a" ] ; then
		DRIVE=b
	else
		DRIVE=a
	fi
else
	test x$EJECT != x && $EJECT 
	echo Replace disk and press return
	read ans
fi

done

rm -f $TEMP

exit 0
