1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176
|
#!/bin/sh
# UNISRC_ID: @(#)shar.sh 27.1 84/12/17
: Make a shell archive package
# Usage: $0 [-b] [-c] [-t] [-v] files... > package
# See the manual entry for details.
# Initialize:
diagnostic='eval echo >&2' # diagnostics to stderr by default.
trap '$diagnostic "$0: quitting early"; exit 1' 1 2 3 15
base_option=FALSE # use pathnames, not basenames.
check_option=FALSE # don't generate integrity check.
USAGE='Usage: $0 \[-b] \[-c] \[-t] \[-v] files... \> package'
# Extract and digest options, if any:
#
# Un-comment the "-)" line below to treat single dashes as a no-op.
# Commented means single dashes elicit a usage diagnostic.
while [ -n "$1" ] # while there are more arguments,
do # digest them; stop when you find a non-option.
case "$1" in
-b) base_option=TRUE; shift;;
-c) check_option=TRUE; shift;;
-v) verbose=TRUE; shift;;
-t) verbose=TRUE; diagnostic='eval echo >/dev/tty'; shift;;
### -) shift;; # if uncommented, eat single dashes.
-*) $diagnostic $USAGE; exit 1;; # die at illegal options.
*) break;; # non-option found.
esac
done
# Check remaining arguments, which should be just a list of files:
if [ $# = 0 ]
then # no arguments left!
$diagnostic $USAGE
exit 1
fi
# Check the cupboard to see if the ingredients are all there:
contents='' # no files so far.
contdirs='' # no directories so far.
for arg # for all files specified,
do # establish the archive name.
if [ -f "$arg" ]
then # file exists and is not a directory.
case $base_option in
TRUE) unpack_name=`basename "$arg"` ;;
FALSE) unpack_name="$arg" ;;
esac
contents="$contents $unpack_name"
elif [ -d "$arg" ]
then # file exists and is a directory.
case $base_option in
TRUE) $diagnostic '$0: cannot archive directory "$arg" with -b option.'
exit 1 ;;
FALSE) contdirs="$contdirs $arg/ " ;;
esac
else # not a plain file and not a directory.
$diagnostic '$0: cannot archive "$arg"'
exit 1
fi
done
# Emit the prologue:
# (The leading newline is for those who type csh instead of sh.)
cat <<!!!
# This is a shell archive. Remove anything before this line,
# then unpack it by saving it in a file and typing "sh file".
#
# Wrapped by `who am i | sed 's/[ ].*//'` on `date`
!!!
# Emit the list of ingredients:
# Simple version (breaks if you shar lots of files at once):
# echo "# Contents: $contdirs$contents"
#
# Complex and cosmetic version to pack contents list onto lines that fit on
# one terminal line ("expr string : .*" prints the length of the string):
MAX=80
line='# Contents: '
for item in $contdirs $contents
do
if [ `expr "$line" : '.*' + 1 + "$item" : '.*'` -lt $MAX ]
then # length of old line + new item is short enough,
line="$line $item" # so just append it.
else # new element makes line too long,
echo "$line" # so put it on a new line.
line="# $item" # start a new line.
MAX=74 # compensate for tab width.
fi
done
echo "$line"
echo " "
# Emit the files and their separators:
for arg
do
# Decide which name to archive under.
case $base_option in
TRUE) unpack_name=`basename "$arg"`
test $verbose && $diagnostic "a - $unpack_name [from $arg]" ;;
FALSE) unpack_name="$arg"
test $verbose && $diagnostic "a - $arg" ;;
esac
# Emit either a mkdir or a cat/sed to extract the file.
if [ -d "$arg" ]
then
echo "echo mkdir - $arg"
echo "mkdir $arg"
else
echo "echo x - $unpack_name"
separator="@//E*O*F $unpack_name//"
echo "sed 's/^@//' > \"$unpack_name\" <<'$separator'"
sed -e 's/^[.~@]/@&/' -e 's/^From/@&/' "$arg"
echo $separator
fi
# Emit chmod to set permissions on the extracted file;
# this keels over if the filename contains "?".
ls -ld $arg | sed \
-e 's/^.\(...\)\(...\)\(...\).*/u=\1,g=\2,o=\3/' \
-e 's/-//g' \
-e 's?.*?chmod & '"$unpack_name?"
echo " "
done
# If the -c option was given, emit the checking epilogue:
# (The sed script converts files to basenames so it works regardless of -b.)
if [ $check_option = TRUE ]
then
echo 'echo Inspecting for damage in transit...'
echo 'temp=/tmp/shar$$; dtemp=/tmp/.shar$$'
echo 'trap "rm -f $temp $dtemp; exit" 0 1 2 3 15'
echo 'cat > $temp <<\!!!'
case $base_option in
TRUE) wc $@ | sed 's=[^ ]*/==' ;;
FALSE) wc $contents | sed 's=[^ ]*/==' ;;
esac
echo '!!!'
echo "wc $contents | sed 's=[^ ]*/==' | "'diff -b $temp - >$dtemp'
echo 'if [ -s $dtemp ]'
echo 'then echo "Ouch [diff of wc output]:" ; cat $dtemp'
echo 'else echo "No problems found."'
echo 'fi'
fi
# Finish up:
echo 'exit 0' # sharchives unpack even if junk follows.
exit 0
|