#!/bin/sh
# $Id: archive,v 1.13 2023/02/18 18:09:22 tom Exp $
# archive, unarchive -- tar and compress source for archival storage
CDPATH=
command=`basename "$0"`
debug="eval"
extract="-xp"
listonly=""
remove="n"
touch="n"
unarchive="n"
verbose=""
suffix="tgz"
compress="gzip"
while getopts "bBdhlrtuvxzZ" opt
do
case $opt in
b) compress="bzip2";suffix="tar.bz2";;
B) compress="bzip2";suffix="tbz";;
d) debug="echo";;
l) extract="-tv"; listonly="#";;
r) remove="y";;
t) touch="y";;
u) unarchive="y";;
v) verbose="v";;
x) compress="xz";suffix="tar.xz";;
z) compress="gzip";suffix="tar.gz";;
Z) compress="compress";suffix="tar.Z";;
*) cat <<eof
Usage: $command [options] [archive_name]
Options:
-b use bzip2 and suffix .tar.bz2
-B use bzip2 and suffix .tbz
-d debug
-l list-only (don't extract files)
-r remove directory (leave tar in parent)
-t touch archive (latest file)
-u un archive
-v verbose (lists filenames)
-x use xz and .tar.xz
-z use gzip and .tar.gz
-Z use compress and suffix .tar.Z
Parameters:
archive_name name for archive (default is current directory name)
By default, archive uses gzip to produce a gzip'd tar archive with suffix .tgz
eof
exit 1;;
--) break;;
-*) exec "$0" -h;;
esac
done
shift `expr $OPTIND - 1`
#-- if script is invoked as 'unarchive' do same as -u option
if [ "$command" = unarchive ]
then unarchive="y"
fi
#-- figure out where we are
paths=`/bin/pwd`
#-- Provide default archive-name
if [ $# = 1 ]
then dir="$1"
arg="$1"
else dir=$paths
arg=.
fi
myfile=
SUF=".tar.gz .tgz .tar.bz2 .tbz .tar.Z .tar.xz .tz"
# Try to decide what the parameter is, and deduce the archive-file and its
# directory:
if [ -f "$dir" ]
then
myfile="$dir"
dir=`echo "$dir" |sed -e 's@/[^/]*$@@'`
if [ "$dir" = "$myfile" ]
then
dir=.
fi
cmp=`basename "$myfile"`
for suf in $SUF none
do
tst=`basename "$myfile" "$suf"`
if [ "$cmp" != "$tst" ]
then
break
fi
done
elif [ -d "$dir" ]
then
for suf in $SUF none
do
tst=$dir/`basename $dir`$suf
if [ -f "$tst" ]
then
myfile="$tst"
break
fi
done
else
echo "Neither a directory nor a file: $dir"
exit 1
fi
if [ $unarchive = "y" ]
then
if [ -z "$myfile" ]
then
echo "Cannot determine archive-file for $dir"
exit 1
fi
case $suf in #(vi
.tar.gz|.tgz) #(vi
decomp="gzip -d"
;;
.tar.bz2|.tbz) #(vi
decomp="bzip2 -d"
;;
.tar.xz|.tz) #(vi
decomp="xz -d"
;;
.tar.Z) #(vi
decomp="uncompress"
;;
*) #(vi
echo "No archive found in ${dir}."
exit 1
esac
if [ ! -w . ] && [ ".$listonly" = "." ]
then
$debug "chmod u+w ."
if [ $? != 0 ]
then
echo "archive: chmod error"
exit 1
fi
fi
if [ "$dir" != "$paths" ]
then
$debug cd "$dir"
if [ "$debug" = echo ]
then
cd "$dir" || exit 1
fi
fi
myfile=`basename "$myfile"`
#-- uncompress and untar
if [ ".$listonly" = "." ]
then
if [ ! -w . ]
then
$debug chmod u+w .
fi
if [ -w .. ]
then
$debug "mv $myfile .."
if [ $? != 0 ]
then
echo "archive: mv error"
exit 1
fi
myfile="../$myfile"
fi
fi
$debug "umask 0;$decomp -c $myfile | tar ${extract}${verbose}f - 2>&1"
if [ $? != 0 ]
then
echo "archive: $decomp/tar error"
exit 1
fi
#-- remove archive
if [ ".$listonly" = "." ]
then
$debug "rm -f $myfile"
fi
elif [ ".$listonly" != "." ]
then
echo "archive: -l option applies only to dearchiving"
exit 1
else
test -z "$myfile" && myfile="${dir}.$suffix"
if [ -f "$myfile" ]
then
echo "Archive $myfile already present."
exit 1
fi
myfile=`basename "$myfile"`
if [ $arg = . ]
then all='`ls -A`'
else all='`ls -Ad '$arg'`'
fi
$debug "tar -c${verbose}f - $all | $compress -c >../$myfile"
if [ $? != 0 ]
then
echo "archive: tar error"
exit 1
fi
#-- obtain date for "-t" option
if [ $touch = "y" ]
then
last=`find $arg -type f -print |sed -e 's/^/"/' -e 's/$/"/'`
if [ ".$last" != "." ]
then
last=`eval ls -1t $last | head -1`
$debug cpd "$last" ../"$myfile"
if [ ".$verbose" = ".v" ]
then
echo "last=$last"
fi
fi
fi
#-- remove current sources
$debug "chmod u+w ."
$debug "find $arg -type d -exec chmod u+w {} \\;"
$debug "rm -rf $all"
if [ $remove = "y" ]
then #-- move archive to parent, removing leaf
leaf=`basename "$paths"`
$debug "cd ..;rmdir $leaf"
else #-- move archive back in
$debug "mv ../$myfile ."
if [ $arg = . ]
then
$debug "chmod -w ."
fi
if [ $touch = "y" ]
then
$debug cpd "$myfile" .
fi
fi
fi