########################################################################
# #
# This software is part of the ast package #
# Copyright (c) 1989-2011 AT&T Intellectual Property #
# and is licensed under the #
# Eclipse Public License, Version 1.0 #
# by AT&T Intellectual Property #
# #
# A copy of the License is available at #
# (with md5 checksum b35adb5213ca9657e911e9befb180842) #
# #
# Information and Software Systems Research #
# AT&T Research #
# Florham Park NJ #
# #
# Glenn Fowler <gsf@research.att.com> #
# #
########################################################################
# Make a shell archive
function logmsg
{
}
function err_exit
{
logmsg "$@"
exit 1
}
[-?
@(#)$Id: shar (AT&T Labs Research) 1999-04-20 $
]
[+NAME? shar - create a shell archive]
[+DESCRIPTION?\bshar\b reads one or more input files and creates a
shell script which when executed will restore the contents
of these files. This is called a shell archive or \ashar\a.
The resulting archive is sent to standard output unless the
\b-o\b option is specified.]
[a:net-headers?Automatic generation of headers. The \b-n\b option
must also be specified. If the archive name does not
given archive name when constructing the header.]
[b:bits-per-code]:[bits?When doing compression, use \b-b \b\abits\a
as a parameter to \bcompress\b(1). The \b-b\b option turns on
\b-Z\b.]
[c:cut-mark?Start the shar with a cut line.]
[d:here-delimiter]:[string?Use \astring\a to delimit the files
in the shar instead of \bSHAR_EOF\b.]
[f:basenames?Use the basenames for the files.]
[g:level-for-gzip]:[level?When doing compression, use \b-\b\alevel\a
as a parameter to \bgzip\b(1). The \b-g\b option turns on
\b-z\b.]
[l:whole-size-limit]#[size?Limit the output file size to \asize\a
bytes. A suffix of \bb\b, \bk\b, or \bm\b can be specified
to indicate 512-byte blocks, kilobytes, or megabytes
respectively.]
[n:archive-name:name]:[name?Override automatically determined name
for the archive with \aname\a.]
[o:output-prefix]:[prefix?Save the archive files \aprefix\a\b.01\b
through \aprefix\a\b.\b\ann\a instead of standard output. This
option must be used when \b-l\b or the \b-L\b is specified.]
[p:intermix-type?Allow positional parameter options. The options
\b-B\b, \b-T\b, \b-z\b and \b-Z\b may be embedded, and files
to the right of the option will be processed in the specified
mode.]
[q:quit|silent?Do not output verbose messages locally when producing
the archive.]
[s:submitter]:[user?Override automatically determined submitter name
with \auser\a which is of the form \awho\a\b@\b\awhere\a.]
archived.]
[w:no-character-count?Do NOT check each file with \bwc -c\b after
unpack.]
[z:gzip?\bgzip\b(1) and \buuencode\b(1) all files prior to packing.]
[B:uuencode,binary-files-files?Treat all files as binary and
\buuencode\b(1) prior to packing.]
[D:no-md5-digest?Do NOT use \bcksum md5sum\b digest to verify
the unpacked files. The default is to check.]
[L:split-size-limit]#[size?Limit the output file size to \asize\a
bytes as with \b-l\b, but split the archive into multiple
files.]
[Q:quiet-unshar?Verbose OFF. Disables the inclusion of comments to
be output when the archive is unpacked.]
[M:mixed-uuencode?Mixed mode. Determine if the files are text or
binary and archive correctly. Files found to be binary
are uuencoded prior to packing. This is the default.]
[S:stdin-file-list?Read list of files to be packed from the standard
input rather than from the command line in the format
generated by \bfind\b(1) and \btw\b(1). If \b-p\b is specified,
the options \b-B\b, \b-T\b, \b-z\b and \b-Z\b must be
included in the standard input.]
[T:text-files?Treat all files as text.]
[X:query-user?When unpacking, ask the user if files should be
overwritten.]
[Z:compress?\bcompress\b(1) and \buuencode\b(1) all files prior to
packing.]
[files ...]
[+SEE ALSO?\bcksum\b(1), \bcompress\b(1), \bfind\b(1), \bgzip\b(1),
\bpax\b(1), \btw\b(1), \buuencode\b(1), \bwc\b(1)]
'
;;
*)
usage='ab:[bits]cd:[delim]fg:[level]l#[size]n:[name]o:[prefix]pqs:[who]tzBDL#[size]MQSXTZ files ...'
;;
esac
IFS=$'\n'
command=${0##*/}
integer size=0
# some strings that should be internationalized some day
skipping=$"echo 'x -' SKIPPING"
exists=$"'(file already exists)'"
extract=$"echo 'x -' extracting"
mkdir=$"creating directory"
uncomp=$"uncompressing file"
while getopts "$usage" c
do
case $c in
[acfpqwDSQX])
q) verbose=;;
v) verbose=1;;
[zZBMT])
mode=$c;;
esac
done
# Check remaining arguments, which should be just a list of files:
then err_exit "no arguments left!"
fi
function preprocess_files
{
typeset file=$1
elif [[ -f $file ]]
then if [[ $flags == *f* ]]
fi
elif [[ -d $file ]]
then if [[ $flags == *f* ]]
fi
fi
}
if [[ $flags == *S* ]]
then while read -r file
do preprocess_files "$file"
print -r -- "$file"
else for file
do preprocess_files "$file"
done
fi
if [[ $flags == *a* ]]
then if [[ $aname ]]
then if [[ $aname != */* ]]
fi
cat <<- !!!
!!!
else err_exit "Cannot use -a without -n"
fi
fi
# Generate the prologue
# (The leading newline is for those who type csh instead of sh.)
if [[ $flags == *c* ]]
then print -r -- '#---- Cut Here and feed the following to sh ----'
fi
cat <<!!!
# This is a shell archive (produced by a ksh93 script).
# Remove anything before this line, then unpack it by saving
# it in a file and typing "sh file".
#
# Wrapped by on $(date) by $user
# Source directory was \`$(pwd)'.
#
# This shar contains:
# length mode name
# ------ ---------- ------------------------------------------
!!!
print '\n#\nnocheck=$1'
if [[ $flags == *Q* ]]
then print quiet=:
else print quiet=false
fi
if [[ $flags == *x* ]]
then print nocheck=-c
fi
if [[ $flags != *D* ]]
then cat <<- \!!!
then uncompress='uncompress -f'
then uncompress='gunzip -f'
fi
then md5='cksum -x md5'
fi
else touch=:
echo 'WARNING: not restoring timestamps.'
fi
!!!
fi
if [[ $flags == *X* ]]
then cat <<- \!!!
#
# The unshar will be interactively queried
#
if test ! -t 2
fi
fi
!!!
fi
{
}
{
cat <<- !!!
read check
[Yy]*) ;;
*) skip=1;;
esac
fi
if test "\$skip" = 1
then
!!!
}
{
typeset file=$1
then return
fi
cat <<- !!!
if test ! -d '$file'
then test X"\$quiet" != X && echo 'x -' '$mkdir' '$file'
mkdir '$file'
fi
!!!
}
# Emit the files and their separators:
function pack_file
{
typeset file=$1
if [[ -d $file ]]
Z) filetype=compressed;;
binary=1
fi
esac
fi
# Decide which name to archive under.
if [[ $flags == *f* ]]
fi
print -r "# ============= $file =============="
if [[ $file == */* ]]
fi
if [[ -d $file ]]
then print "mkdir $file"
print 'skip='
if [[ $flags == *X* ]]
then emit_guard
fi
printf "\$quiet || $skipping %q $exists\nelse \$quiet || $extract %q '(%s)'\n" "$file" "$file" "$filetype"
then if [[ $mode == Z ]]
elif [[ $mode == z ]]
fi
print -r 'uudecode << \!!!!'
print "!!!!"
fi
else print -r "sed 's/^@//' > \"$name\" <<'$separator'"
print -r $separator
fi
fi
# Emit chmod to set permissions on the extracted file;
# this keels over if the filename contains "?".
print "fi"
}
if [[ $flags == *S* ]]
then while read -r file
else for file
done
fi
# If the -c option was given, emit the checking epilogue:
# If the receiving machine has cksum, it will be used instead of wc
then cat <<- __END__
\$quiet || echo 'Inspecting for damage in transit...'
temp=/tmp/shar\$\$; dtemp=/tmp/.shar\$\$
trap "rm -f \$temp \$dtemp; exit" EXIT HUP INT QUIT TERM
if [ X"\$md5" != X ]
then cat > \$temp <<\!!!
$(
if [[ $flags == *b* ]]
then cksum -x md5 "$@" | sed 's=[^ ]*/=='
else cksum -x md5 $contents | sed 's=[^ ]*/=='
fi
)
!!!
cksum='cksum -x md5'
else cat > \$temp <<\!!!
$(
IFS=$'\n' # this line should not be needed
if [[ $flags == *b* ]]
then wc "$@" | sed 's=[^ ]*/=='
else wc $contents | sed 's=[^ ]*/=='
fi
)
!!!
cksum=wc
fi
\$cksum $files | sed 's=[^ ]*/==' | diff -b \$temp - >\$dtemp
if [ -s \$dtemp ]
then echo "Ouch [diff of \$cksum output]:" ; cat \$dtemp
else \$quiet || echo "No problems found."
fi
__END__
fi
# split or limit size
if [[ $prefix ]]
then if [[ $split ]]
then split -b $size -f "$prefix" /tmp/shar$$.1
elif (( $size && $(wc -c < /tmp/shar$$.1) > $size ))
then head -c $size /tmp/shar$$.1 > $prefix.01
else cp /tmp/shar$$.1 "$prefix.01"
fi
fi
print 'exit 0' # exit even if more input