Text 6115, 1040 rader
Skriven 2034-05-21 23:47:00 av Paul Rogers (1:105/360.0)
Ärende: Guarded Inst'n Tool
===========================
I intend to change "--depends-on" to "--requires", & "--makes-use-of"
to "--uses". Unfortunately there're no docs.
#!/bin/bash
#PGR was here for minor config changes
#PGR SUBVER=16a: added restore command
#PGR SUBVER=16b: changed files function to include "touched" files in
# lists and backups
#PGR SUBVER=16c: added --color to ls
#
# Guarded Installation Tool, by Ingo Brueckl (ib@wupperonline.de) 14.11.1996
# modified: 09.10.2004
#
# Method for coping with arbitrary filenames that may contain newlines
# and some other stuff were supplied by Rainer Fischer.
# configuration section
#--------------------------------------------------------------------------
SHOWRESULT=yes # default answer to 'Show it?'
FINDCASE=-i # will cause --find to ignore case
PROFILEVAR=*default* # empty, *default*, or individual variable name
PRESERVE=yes # preserve the de-installation script's timestamps
EXPERT=no # non-experts get some additional help
BACKUPEXT=tgz # file extension used for backups
VIEWPROG="less -c" # program used to show results
LSPROG="ls --color -dCv" # program used to list de-installation scripts
EDITPROG=${EDITOR:-vi} # program used to edit de-installation scripts
BACKUPPIPE="tar --no-recursion --null -T - -czf" # program used to back up
RESTOREPIPE="tar -xzf" #restore parms
WATCHDIRS="/bin /boot /dev /etc /lib /opt /sbin /usr"
#PGR added /usr/local/src (that's where I'm installing from)
IGNOREDIRS="/usr/local/src"
#--------------------------------------------------------------------------
# end of configuration section
LNAME="Guarded Installation Tool"
SNAME=$(basename "$0")
VERSION=2
SUBVER=16c
ID="De-installation script"
DEPEND="depends on"
USE_OF="makes use of"
USED_BY="only used by (no longer needed without)"
if [ ".$1" = ".--cwd" ]; then
shift
TEMPDIR=$(pwd)/$SNAME.$$
else
#PGR change default location to /lfs/git
SCRIPTPATH=/var/local/$SNAME
TEMPDIR=${TMPDIR:-/tmp}/$SNAME.$$
fi
BACKUPPATH=$SCRIPTPATH/backups
TEMPFILE=$TEMPDIR/$SNAME
SOFAR=so-far
SUFFIX=pre-inst
GITOPT=git-opts
OPTIONS=0 # a bitmap flag for options, bit 0: --watch, bit 1: --ignore
USAGE="Usage: $SNAME ANYNAME [--watch DIR1 DIR2 ...] [--ignore DIR1 DIR2 ...]
$SNAME [--dirs [ANYNAME]] [--edit ANYNAME] [--remove ANYNAME]
$SNAME [--backup ANYNAME] [--restore ANYNAME] [--xcheck ANYNAME]
$SNAME [--files ANYNAME] [--files0 ANYNAME] [--list ANYNAME]
$SNAME [--ls [ANYNAM]] [--lsbak [ANYNAM]]
$SNAME [--find FILENAME] [[ANYNAME] --lib [LIBNAME]]
$SNAME [ANYNAME --depends-on ANYNAME2]
$SNAME [ANYNAME --makes-use-of ANYNAME2]
$SNAME [ANYNAME --only-used-by ANYNAME2]
$SNAME [--cd] [--deps] [--help] [--profile] [--version]
$SNAME [--cwd [...]]
Begin or finish the guarded installation of a program or software package and
associate this installation with ANYNAME.
--backup ANYNAME create a backup of the files in ANYNAME
--cd change the current directory to $SCRIPTPATH
--cwd [...] execute with arguments given in [...], but create all
working files in ./ (only works as first option)
--depends-on ANYNAME2 note the dependency on ANYNAME2
--deps show all dependencies and usages
--dirs [ANYNAME] show the defaults for --watch and --ignore or the
values used for the (current) installation of ANYNAME
--edit ANYNAME edit ANYNAME's script preserving the file's timestamp
--files ANYNAME list the files in ANYNAME
--files0 ANYNAME list the files in ANYNAME with null-terminated names
--find FILENAME tell which ANYNAME installed files matching FILENAME
--help display this help and exit
--ignore DIR1 DIR2 ... paths excluded from being watched during installation
--lib [LIBNAME] tell which programs use libraries matching LIBNAME
--list ANYNAME list information about the files in ANYNAME
--ls [ANYNAM] list all de-installation scripts matching ANYNAM*
--lsbak [ANYNAM] list all backups matching ANYNAM*
--makes-use-of ANYNAME2 note the advantage because of ANYNAME2
--only-used-by ANYNAME2 note the exclusive use by ANYNAME2
--profile print definitions required for option --cd and for a
variable containing $SCRIPTPATH
--remove ANYNAME call the de-installation script for ANYNAME
--restore ANYNAME restore files from backup ANYNAME
--version output version information and exit
--watch DIR1 DIR2 ... paths to be watched during installation
--xcheck ANYNAME cross-check contents of ANYNAME against all other
(executable) de-installation scripts to find out
whether a file has been installed more than once"
TRY="Try \`$SNAME --help' for more information."
WSPACE=$(echo -e " \t")
eval "$(echo -e 'NL="\n"')"
# newlines in filenames will be expressed by ${NL} in de-installation scripts
# the following...
export NL
# ...allows subshells started by this script to handle those filenames properly
function novice () # $1: string to return
{
if [ "$EXPERT" = no ]; then
echo "$1 "
else
echo ""
fi
}
function change_filenames ()
{
# split lines separated by \0
# change <newline> temporarily into \0,
# question mark into //Q,
# and \0 into question mark
tr "\0\n" "\n\0" | sed "s:?://Q:g" | tr "\0" "?"
}
function restore_filename ()
{
# reverse what change_filenames did
tr "?" "\n" | sed "s://Q:?:g"
}
function find_filenames ()
{
eval "find $WATCHDIRS $PRUNE \"\$@\" \( -type d -printf "d" -print0 -o \
-printf "f" -print0 \)" |
change_filenames
}
function translate_filenames () # $1: inserted as first character in line
{
# escape special characters,
# change question mark into ${NL},
# change //Q into question mark,
# translate file type into 'rm -f' or 'rmdir'
# and put double quotes around the filename if (possibly) necessary
sed -e 's:["$\\`]:\\&:g' -e 's:?:${NL}:g' -e "s://Q:?:g" \
-e "s:^f:$1 rm -f :" -e "s:^d:$1 rmdir :" \
-e 's:^\(.\{8\}\) \(.*[^a-zA-Z0-9+,./:_-].*\)$:\1"\2":'
}
function create_tempdir ()
{
mkdir "$TEMPDIR" && chmod go-w "$TEMPDIR" && rm -rf "$TEMPDIR"/{,.[^.],..?}*
if [ $? -ne 0 ]; then
echo "Fatal error while creating working directory."
exit 1
fi
TMPDIR=$TEMPDIR
export TMPDIR
}
function write_script () # $1: pre-inst, $2: script, $3: quiet?
{
# detect new or modified files
find_filenames -cnewer "$1" | sort > "$TEMPFILE.new"
# detect files that have been deleted
find_filenames | sort > "$TEMPFILE.all"
comm -23 "$1" "$TEMPFILE.all" > "$TEMPFILE.del"
# handle files that have been newly created
comm -13 "$1" "$TEMPFILE.new" | translate_filenames " " > "$TEMPFILE.rm"
# handle previously existing files that have been changed
comm -12 "$1" "$TEMPFILE.new" | translate_filenames "#" >> "$TEMPFILE.rm"
# now create the de-installation script
echo "#!/bin/bash" > "$2"
echo "#" >> "$2"
echo $E "$ID for \`$(basename "$1" ".$SUFFIX")'," | sed "s:^:# :" >> "$2"
echo "# created by $LNAME $VERSION.$SUBVER on $(date)" >> "$2"
echo >> "$2"
if grep -q "?" "$TEMPFILE.new" "$TEMPFILE.del"; then
echo 'NL="' >> "$2"
echo '" # some filenames contain newlines expressed by ${NL}' >>
"$2"
echo >> "$2"
fi
if [ -s "$TEMPFILE.del" ]; then
echo "## WARNING!" >> "$2"
echo "##" >> "$2"
echo "## This is a list of files that seem to have been deleted during
installation:" >> "$2"
echo "##" >> "$2"
cat "$TEMPFILE.del" | translate_filenames "#" | sed "s:^# rm...:## :" |
sort >> "$2"
echo "##" >> "$2"
echo "## End of WARNING" >> "$2"
echo >> "$2"
fi
echo "$SNAME --xcheck" '"$(basename "$0")"' >> "$2"
echo 'echo -n "Ok to start de-installation? "' >> "$2"
echo "read" >> "$2"
echo 'if [ ".$REPLY" != ".y" -a ".$REPLY" != ".yes" ]; then' >> "$2"
echo ' echo "No, aborted."' >> "$2"
echo " exit" >> "$2"
echo "else" >> "$2"
echo -n ' echo -n "Removing \`$(basename "$0")' >> "$2"
echo "'... \"" >> "$2"
echo "fi" >> "$2"
echo >> "$2"
echo "# The following statements will completely remove the installation," >>
"$2"
echo "# files already existing prior to the installation are commented out."
>> "$2"
echo >> "$2"
sort +0.9 -r "$TEMPFILE.rm" >> "$2"
echo >> "$2"
echo 'chmod -x "$0"' >> "$2"
echo 'echo "done."' >> "$2"
echo 'echo -n "Remove script, too? "' >> "$2"
echo "read" >> "$2"
echo 'if [ ".$REPLY" = ".y" -o ".$REPLY" = ".yes" ]; then' >> "$2"
echo ' rm "$0"' >> "$2"
echo "else" >> "$2"
echo ' echo "It has been made non-executable instead."' >> "$2"
echo "fi" >> "$2"
# we're done
if [ -z "$3" ]; then
trap "" SIGINT
echo "done."
if [ -s "$TEMPFILE.del" ]; then
echo "See it for warnings!"
fi
fi
}
function show_result () # $1: script
{
if [ ! -s "$1" ]; then
echo "Nothing to show."
return 1
elif [ -z "$VIEWPROG" ]; then
echo -n "Can't show it, press enter. "
read
else
echo -n "Show it? [$SHOWRESULT] "
read
REPLY=${REPLY:-$SHOWRESULT}
if [ ".$REPLY" = ".y" -o ".$REPLY" = ".yes" ]; then
$VIEWPROG "$1"
fi
fi
return 0
}
function extract_filenames () # $1: search pattern for beginning of line
{
NFNAME="[^$WSPACE\";]\+" # normal (unquoted) filenames
QFNAME='".*"' # double quoted filenames
sed "s:$1\($NFNAME\|$QFNAME\)\([$WSPACE;].*\)\?\$: \1:"
}
function xcheck () # $1: script, $2: ANYNAME
{
echo $E -n "Checking \`$(basename "$1")'... "
# separate files to be removed
grep "^ *rm -f " "$1" | extract_filenames "^ *rm -f \+" |
sort > "$TEMPFILE.check"
# separate files commented out
find "$SCRIPTPATH" -type f -maxdepth 1 -perm +u+x -print0 |
xargs -0re grep -h '^#[^"]*rm -f ' | extract_filenames '^#[^"]*rm -f \+' |
sort > "$TEMPFILE.against"
# detect files being installed more than once
FILES=$(comm -12 "$TEMPFILE.check" "$TEMPFILE.against")
# check result
if [ "$FILES" ]; then
echo -e "\nSome files seem to have been installed more than once!\n"
grep -F "$FILES" "$1"
echo -e "conflict(s) with:\n"
INUM=$(find "$1" -printf "%i")
find "$SCRIPTPATH" -type f -maxdepth 1 -perm +u+x -not -inum $INUM \
-exec grep -F "$FILES" {} \; -printf "(in %P)\n\n"
fi
SCRIPT=$(echo $E -n "$2" | change_filenames)
DEPENDENCIES=$(dependencies "$SCRIPT")
if [ -z "$FILES" -a -z "$DEPENDENCIES" ]; then
echo "done."
return 0
fi
if [ -z "$FILES" ]; then
echo -e "\n"
fi
if [ "$DEPENDENCIES" ]; then
echo $E "$DEPENDENCIES"
echo
fi
return 1
}
function permissions () # $1: script
{
COL="\([^ ]\+\)\( \+\)" # a column (with delimiter)
IFSold=$IFS
IFS=$(echo -e "\t")
for c in " " "#"; do
grep "^$c *rm... " "$1" | extract_filenames "^$c *rm... \+" | tr "\n" "\0"
|
xargs -0re sh -c 'eval ls -ldbF "$@"' -- |
sed "s:^$COL$COL$COL$COL$COL$COL$COL$COL:\1\t\3\t\5\t\7\t$c\t:"
done | sort -r -k 6 -t "$IFS" |
while read -r p n o g c f; do
printf "%s %3s %-8s %-8s %s %s\n" $p $n $o $g "$c" "$f"
done
IFS=$IFSold
}
function files () # $1: script
{
# grep "^ *rm... " "$1" | extract_filenames "^ *rm... \+" | sed "s:^ ::" |
grep "^[ #] *rm... " "$1" | extract_filenames "^[ #] *rm... \+" | sed "s:^
::" |
tr "\n" "\0" | xargs -0re sh -c 'eval find "$@" -maxdepth 0 -print0' --
}
function chkname () # $1: ANYNAME
{
case "$1" in
*/*) echo $E "Will not handle \`$1' (containing a slash)!"
exit 1
;;
esac
}
function chkscript () # $1: ANYNAME
{
chkname "$1"
if [ ! -f "$SCRIPTPATH/$1" ]; then
echo $E "\`$SCRIPTPATH/$1' does not exist!"
exit 1
elif sed -n "3p" "$SCRIPTPATH/$1" | grep -q "$ID"; then
return 0
else
echo $E "\`$SCRIPTPATH/$1' does not seem to be a de-installation script!"
exit 1
fi
}
function chkbakpath ()
{
if [ ! -d "$BACKUPPATH" ]; then
echo -n "Ok to create backup directory $BACKUPPATH? $(novice '[no/yes]')"
read
if [ ".$REPLY" = ".y" -o ".$REPLY" = ".yes" ]; then
mkdir -p "$BACKUPPATH" || exit 1
else
echo "No, aborted."
exit 1
fi
fi
}
function check_paths () # $@: directories to check
{
RC=0
for p in "$@"; do
case "$p" in
/*) if [ ! -d "$p" ]; then
echo $E "Warning: \`$p' does not exist!"
RC=1
fi
;;
*) echo $E "Will not accept \`$p' (not an absolute path)!"
exit 1
;;
esac
done
return $RC
}
function find_script () # $1: string to search
{
NOREGEX=$(echo $E -n "f$1" | change_filenames | translate_filenames " " |
sed -e "s:^.\{9\}::" -e 's:"$::' -e 's:[][^$\\.*]:\\&:g')
NFNAME="[^$WSPACE\";]*$NOREGEX" # string inside normal (unquoted) filenames
QFNAME="\".*$NOREGEX.*\"" # string inside double quoted filenames
cd "$SCRIPTPATH" || return 1
find -type f -maxdepth 1 -perm +u+x -printf "%P\0" |
xargs -0re grep $FINDCASE "^[ #] *rm... \+\($NFNAME\|$QFNAME\)" /dev/null
}
function profile ()
{
echo "function $SNAME ()"
echo "{"
echo ' if [ ".$1" = ".--cd" ]; then'
echo " cd \"$SCRIPTPATH\""
echo " else"
echo " command $SNAME" '"$@"'
echo " fi"
echo "}"
echo "export -f $SNAME"
if [ ".$PROFILEVAR" = ".*default*" ]; then
PROFILEVAR=$SNAME
fi
case "$PROFILEVAR" in *[^a-zA-Z0-9_]* | [0-9]* | _)
echo "$SNAME --profile: \`$PROFILEVAR' is not a valid variable name." >&2
exit 1
;;
esac
if [ "$PROFILEVAR" ]; then
echo "$PROFILEVAR=\"$SCRIPTPATH\""
echo "export $PROFILEVAR"
fi
}
function quote () # $1: file or path name
{
# put single quotes around the name
# after replacing all ' by '\'' if necessary
case "$1" in
*\'*) echo $E "$1" | sed -e "s:':'\\\'':g" -e "1s:^:':" -e '$s:$:'\'':'
;;
*) echo $E "'$1'"
;;
esac
}
function option_list () # $@: command line
{
CURROPT=""
for p in "$@"; do
case "$p" in
--watch) WATCHDIRS=""
CURROPT=--watch
OPTIONS=$((OPTIONS | 1))
;;
--ignore) IGNOREDIRS=""
CURROPT=--ignore
OPTIONS=$((OPTIONS | 2))
;;
-*) echo $TRY
exit 1
;;
"") continue
;;
*) if [ -z "$CURROPT" ]; then
CURROPT=none
elif [ $CURROPT = --watch ]; then
WATCHDIRS="$WATCHDIRS $(quote "$p")"
elif [ $CURROPT = --ignore ]; then
IGNOREDIRS="$IGNOREDIRS $(quote "$p")"
else
echo $TRY
exit 1
fi
;;
esac
done
WATCHDIRS=${WATCHDIRS# }
IGNOREDIRS=${IGNOREDIRS# }
}
function prune_statement () # $@: directories to ignore
{
PRUNE=""
for p in "$@"; do
PRUNE="$PRUNE -path $(quote "$p") -prune -o"
done
PRUNE=$(echo $E "$PRUNE" | sed "s:[][*?]:\\\&:g")
}
function default_dirs ()
{
echo $E "--watch ${WATCHDIRS:-\"\"}"
echo $E "--ignore ${IGNOREDIRS:-\"\"}"
}
function dirs () # $1: ANYNAME
{
if [ ! -f "$SCRIPTPATH/$1.$SUFFIX" ]; then
echo $E "A guarded installation of \`$1' isn't in progress."
return 1
else
if [ -f "$SCRIPTPATH/$1.$GITOPT" ]; then
WATCHDIRS=$(grep "^w" "$SCRIPTPATH/$1.$GITOPT" | sed "s:^.::")
IGNOREDIRS=$(grep "^i" "$SCRIPTPATH/$1.$GITOPT" | sed "s:^.::")
fi
default_dirs
return 0
fi
}
function finish_installation () # $1: ANYNAME
{
chmod u+x "$SCRIPTPATH/$1"
rm "$SCRIPTPATH/$1.$SUFFIX"
rm -f "$SCRIPTPATH/$1.$GITOPT"
trap SIGINT
show_result "$SCRIPTPATH/$1"
}
function check_directories ()
{
if [ -z "$WATCHDIRS" ]; then
echo "Nothing to watch."
exit 1
fi
eval check_paths "$WATCHDIRS $IGNOREDIRS"
if [ $? -ne 0 -a $OPTIONS -ne 0 ]; then
echo -n "Continue anyway? $(novice '[no/yes]')"
read
if [ ".$REPLY" != ".y" -a ".$REPLY" != ".yes" ]; then
echo "No, aborted."
exit 1
fi
fi
eval prune_statement "$IGNOREDIRS"
}
function cleanup () # $@: files to delete
{
trap "" SIGINT
echo "interrupted!"
rm -f "$@"
exit 1
}
function noregex () # $1: pattern
{
echo $E ".$1" | sed -e "s:^.::" -e 's:[][^$\\.*]:\\&:g'
}
function lddlib () # $1: script, $2: search pattern, $3:
ANYNAME
{
if [ -z "$2" ]; then
HEADER="Use of libraries found in \`$3'."
else
HEADER="Use of \`$2' found in \`$3'."
fi
NOREGEX=$(noregex "$2")
FILE=""
grep "^. *rm -f " "$1" | extract_filenames "^. *rm -f \+" |
grep -v "^ /dev/\|^ /proc/" | tr "\n" "\0" |
xargs -0re sh -c 'eval ldd "$@"' -- /dev/null 2> /dev/null |
grep $FINDCASE "^[^$WSPACE]\|$NOREGEX" |
while read -r; do
case "$REPLY" in
[^$WSPACE]*) FILE=$REPLY
;;
*) [ "$HEADER" ] && echo && echo $E "$HEADER" && HEADER=""
[ "$FILE" ] && echo $E "$FILE" && FILE=""
echo $E "$REPLY"
;;
esac
done
}
function dependencies () # $1: search pattern
{
NOREGEX=$(noregex "$1")
if [ "$1" ]; then
NOREGEX="$NOREGEX\$"
fi
MAGIC="#: \($DEPEND\|$USE_OF\|$USED_BY\): "
cd "$SCRIPTPATH" || return 1
find -type f -maxdepth 1 -perm +u+x -printf "%P\0" |
xargs -0re grep "^${MAGIC}${NOREGEX}" /dev/null |
# change all question marks in front of :$MAGIC and
# those in all lines not containing :$MAGIC to //Q
# (which protects them against restore_filename)
# then extract $DEPEND, $USE_OF or $USED_BY from :$MAGIC
sed -e ":loop" -e "s;?\(.*:$MAGIC\);//Q\1;" -e "t loop" \
-e "/:$MAGIC/ !s:?://Q:g" \
-e "s;:$MAGIC; \1 ;" |
restore_filename
}
function touch_script () # $1: script, $2: save/restore
{
case $2 in
save) touch -r "$1" "$TEMPFILE.mtime"
;;
restore) if [ "$1" -nt "$TEMPFILE.mtime" -o \
"$1" -ot "$TEMPFILE.mtime" ]; then
touch -mr "$TEMPFILE.mtime" "$1"
fi
;;
esac
}
function depend () # $1: script, $2: DEPNAME, $3: string
{
SCRIPT=$(echo $E -n "$2" | change_filenames)
if grep -q "^#: $3: $(noregex "$SCRIPT")\$" "$1"; then
return 0
else
touch_script "$1" save
N="\\$NL"
if grep -q "^#: $3: " "$1"; then
MAGIC="^#: $3: "
EXTRA=""
elif grep -q "^#: " "$1"; then
MAGIC="^#: "
EXTRA=""
else
MAGIC="^[$WSPACE]*\$"
EXTRA=$N
fi
# determine the line number behind the last $MAGIC line
# and insert '#: $3: $SCRIPT' there
LNR=$(sed -n "/$MAGIC/,\$ { /$MAGIC/ !{ =; q; }; }" "$1")
sed "$((LNR)) i${N}#: $3: ${SCRIPT}${EXTRA}" "$1" > "$TEMPFILE.copy"
if [ $? -eq 0 -a -s "$TEMPFILE.copy" ]; then
cp "$TEMPFILE.copy" "$1"
else
return 1
fi
if [ "$PRESERVE" = yes ]; then
touch_script "$1" restore
fi
fi
}
function edit_script () # $1: script
{
touch_script "$1" save
$EDITPROG "$1"
touch_script "$1" restore
}
function no_other_pre_inst_file ()
{
FILES=$(find "$SCRIPTPATH" -type f -maxdepth 1 -name "*.$SUFFIX")
if [ "$FILES" ]; then
echo "Other guarded installation(s) still in progress:"
cd "$SCRIPTPATH" && ls -CdbF *."$SUFFIX"
echo -n "Continue anyway? $(novice '[no/yes]')"
read
if [ ".$REPLY" = ".y" -o ".$REPLY" = ".yes" ]; then
return 0
else
return 1
fi
else
return 0
fi
}
function backup () # $1: script, $2: ANYNAME
{
if [ -e "$BACKUPPATH/$2.$BACKUPEXT" ]; then
echo -n "Backup already exists. Ok to overwrite? $(novice '[no/yes]')"
read
if [ ".$REPLY" != ".y" -a ".$REPLY" != ".yes" ]; then
echo "No, aborted."
exit 1
fi
fi
files "$1" | $BACKUPPIPE "$BACKUPPATH/$2.$BACKUPEXT"
echo "Done."
}
#
# start of main program
#
case "$SNAME" in *[^a-zA-Z0-9+,.:_-]*)
echo "Please call me under a name only containing characters
[a-zA-Z0-9+,.:_-]."
exit 1
;;
esac
if echo "\t" | grep -q "t"; then
E=""
elif echo -E "\t" | grep -q "t"; then
E="-E"
else
echo "Warning: Your \`echo' can't handle backslash-escaped characters
literally."
E=""
fi
trap 'trap "" SIGINT; rm -rf "$TEMPDIR"' EXIT
trap 'echo "interrupted!"; exit 1' SIGINT
create_tempdir
if [ ".$1" = ".--ls" ]; then
chkname "$2"
cd "$SCRIPTPATH" && $LSPROG -- "$2"*
exit
elif [ ".$1" = ".--lsbak" ]; then
chkname "$2"
chkbakpath
cd "$BACKUPPATH" && $LSPROG -- "$2"*
exit
elif [ ".$1" = ".--lib" -a $# -le 2 ]; then
find "$SCRIPTPATH" -type f -maxdepth 1 -perm +u+x -print0 |
xargs -0re -i $SNAME {} "$@"
exit
elif [ ".$2" = ".--lib" -a $# -le 3 ]; then
ANYNAME=${1#"$SCRIPTPATH/"}
chkscript "$ANYNAME"
lddlib "$SCRIPTPATH/$ANYNAME" "$3" "$ANYNAME"
exit
fi
case $# in
3) ANYNAME=${1#"$SCRIPTPATH/"}
DEPNAME=${3#"$SCRIPTPATH/"}
case "$2" in
--depends-on) chkscript "$ANYNAME"
chkscript "$DEPNAME"
depend "$SCRIPTPATH/$ANYNAME" "$DEPNAME" "$DEPEND"
exit
;;
--makes-use-of) chkscript "$ANYNAME"
chkscript "$DEPNAME"
depend "$SCRIPTPATH/$ANYNAME" "$DEPNAME" "$USE_OF"
exit
;;
--only-used-by) chkscript "$ANYNAME"
chkscript "$DEPNAME"
depend "$SCRIPTPATH/$ANYNAME" "$DEPNAME" "$USED_BY"
exit
;;
*) chkname "$1"
option_list "$@"
;;
esac
;;
2) ANYNAME=${2#"$SCRIPTPATH/"}
case "$1" in
--xcheck) chkscript "$ANYNAME"
xcheck "$SCRIPTPATH/$ANYNAME" "$ANYNAME"
exit
;;
--remove) chkscript "$ANYNAME"
rm -rf "$TEMPDIR"
export -n TMPDIR
exec "$SCRIPTPATH/$ANYNAME"
;;
--backup) chkscript "$ANYNAME"
chkbakpath
backup "$SCRIPTPATH/$ANYNAME" "$ANYNAME"
exit
;;
#PGR added "restore" command so we don't have to run tar from / and chmod
--restore) chkname "$ANYNAME"
chkbakpath
if [ -e "$BACKUPPATH/$ANYNAME.$BACKUPEXT" ]; then
(cd / && $RESTOREPIPE "$BACKUPPATH/$ANYNAME.$BACKUPEXT")
if [ $? -eq 0 ]; then
echo "Files restored successfully."
if [ -e "$SCRIPTPATH/$ANYNAME" ]; then
if [ ! -x "$SCRIPTPATH/$ANYNAME" ]; then
chmod u+x "$SCRIPTPATH/$ANYNAME"
echo "$SCRIPTPATH/$ANYNAME made executable again."
fi
else
echo "Oops! $ID $ANYNAME doesn't exist anymore."
# Yes, backup is restored even if deinstall script is missing.
fi
else
echo "Restore returned error code $?"
fi
else
echo "$BACKUPPATH/$ANYNAME.$BACKUPEXT doesn't exist."
fi
exit
;;
--list) chkscript "$ANYNAME"
permissions "$SCRIPTPATH/$ANYNAME"
exit 0
;;
--files) chkscript "$ANYNAME"
files "$SCRIPTPATH/$ANYNAME" | tr "\0" "\n"
exit 0
;;
--files0) chkscript "$ANYNAME"
files "$SCRIPTPATH/$ANYNAME"
exit 0
;;
--edit) chkscript "$ANYNAME"
edit_script "$SCRIPTPATH/$ANYNAME"
exit
;;
--find) find_script "$2"
exit
;;
--dirs) chkname "$ANYNAME"
dirs "$ANYNAME"
exit
;;
*) echo $TRY
exit 1
;;
esac
;;
1) case "$1" in
--cd) echo "Option --cd isn't available, use \`cd $SCRIPTPATH'
instead."
exit 1
;;
--deps) dependencies
exit
;;
--dirs) default_dirs
exit 0
;;
--profile) profile
exit 0
;;
--help) echo "$USAGE"
exit 0
;;
--version) echo "$SNAME - $LNAME $VERSION.$SUBVER"
exit 0
;;
-*) echo $TRY
exit 1
;;
*) chkname "$1"
;;
esac
;;
*) case "$1" in
-* | "") echo $TRY
exit 1
;;
*) chkname "$1"
option_list "$@"
;;
esac
;;
esac
# called first time ever
if [ ! -d "$SCRIPTPATH" ]; then
echo -n "Ok to create script directory $SCRIPTPATH? $(novice '[no/yes]')"
read
if [ ".$REPLY" = ".y" -o ".$REPLY" = ".yes" ]; then
mkdir -p "$SCRIPTPATH" || exit 1
else
echo "No, aborted."
exit 1
fi
fi
ANYNAME=$1
# installation in progress
if [ -f "$SCRIPTPATH/$ANYNAME.$SUFFIX" ]; then
if [ -f "$SCRIPTPATH/$ANYNAME.$GITOPT" ]; then
if [ $((OPTIONS & 1)) -eq 0 ]; then
WATCHDIRS=$(grep "^w" "$SCRIPTPATH/$ANYNAME.$GITOPT" | sed "s:^.::")
fi
if [ $((OPTIONS & 2)) -eq 0 ]; then
IGNOREDIRS=$(grep "^i" "$SCRIPTPATH/$ANYNAME.$GITOPT" | sed "s:^.::")
fi
fi
check_directories
# ask what to do
echo $E "The guarded installation of \`$ANYNAME' is in progress."
REPLY=""
until [ "$REPLY" ]; do
echo -n "What shall $SNAME do now (s/r/f/q)? $(novice '[Press enter for
help]')"
read
if [ ".$REPLY" != ".s" -a ".$REPLY" != ".r" -a \
".$REPLY" != ".f" -a ".$REPLY" != ".q" ]; then
echo " s ... show state of installation"
echo " r ... revoke installation"
echo " f ... finish installation"
echo " q ... quit"
REPLY=""
fi
done
# finish installation
if [ "$REPLY" = "f" ]; then
echo $E -n "Creating de-installation script \`$SCRIPTPATH/$ANYNAME'... "
trap 'cleanup "$SCRIPTPATH/$ANYNAME"' SIGINT
write_script "$SCRIPTPATH/$ANYNAME.$SUFFIX" "$SCRIPTPATH/$ANYNAME"
finish_installation "$ANYNAME"
# state of installation
elif [ "$REPLY" = "s" ]; then
echo $E -n "Analyzing the state of installation of \`$ANYNAME'... "
write_script "$SCRIPTPATH/$ANYNAME.$SUFFIX" "$TEMPFILE.script" -q
grep "^##" "$TEMPFILE.script" > "$TEMPDIR/$ANYNAME.$SOFAR"
if [ -s "$TEMPDIR/$ANYNAME.$SOFAR" ]; then
echo >> "$TEMPDIR/$ANYNAME.$SOFAR"
fi
permissions "$TEMPFILE.script" >> "$TEMPDIR/$ANYNAME.$SOFAR" 2>&1
echo "done."
show_result "$TEMPDIR/$ANYNAME.$SOFAR"
# enable quick finish of installation
if [ $? -eq 0 ]; then
echo -n "Use state information and finish installation now? $(novice
'[no/yes]')"
read
if [ ".$REPLY" = ".y" -o ".$REPLY" = ".yes" ]; then
echo -n "State information may be out of date. Please confirm: $(novice
'[no/yes]')"
read
if [ ".$REPLY" = ".y" -o ".$REPLY" = ".yes" ]; then
echo $E -n "Creating de-installation script
\`$SCRIPTPATH/$ANYNAME'... "
trap 'cleanup "$SCRIPTPATH/$ANYNAME"' SIGINT
mv "$TEMPFILE.script" "$SCRIPTPATH/$ANYNAME"
trap "" SIGINT
echo "done."
finish_installation "$ANYNAME"
else
echo "No."
fi
else
echo "No."
fi
fi
# revoke installation
elif [ "$REPLY" = "r" ]; then
echo $E -n "Revoking the guarded installation of \`$ANYNAME'... Sure?
$(novice '[no/yes]')"
read
if [ ".$REPLY" = ".y" -o ".$REPLY" = ".yes" ]; then
rm "$SCRIPTPATH/$ANYNAME.$SUFFIX"
rm -f "$SCRIPTPATH/$ANYNAME.$GITOPT"
echo "Done."
else
echo "Nothing done."
exit 1
fi
# quit
else
echo "Nothing done."
exit 1
fi
# new installation
else
check_directories
if [ -e "$SCRIPTPATH/$ANYNAME" ]; then
echo $E "\`$ANYNAME' seems to be installed."
echo "What about removing the script first?"
exit 1
elif no_other_pre_inst_file; then
echo $E -n "Preparing the guarded installation of \`$ANYNAME'... "
trap 'cleanup "$SCRIPTPATH/$ANYNAME".{"$SUFFIX","$GITOPT"}' SIGINT
find_filenames | sort > "$SCRIPTPATH/$ANYNAME.$SUFFIX"
if [ $OPTIONS -ne 0 ]; then
echo $E "$WATCHDIRS" | sed "s:^:w:" > "$SCRIPTPATH/$ANYNAME.$GITOPT"
echo $E "$IGNOREDIRS" | sed "s:^:i:" >> "$SCRIPTPATH/$ANYNAME.$GITOPT"
fi
trap "" SIGINT
if [ -f "$SCRIPTPATH/$ANYNAME.$SUFFIX" ]; then
sleep 2 # PGR make sure before and after timestamps aren't the same
echo "done."
else
echo "failed!"
exit 1
fi
else
echo "Nothing done."
exit 1
fi
fi
exit 0
Paul Rogers, paulgrogers@yahoo.com -o)
http://www.angelfire.com/or/paulrogers /\\
Rogers' Second Law: Everything you do communicates. _\_V
... Let us taunt it; perhaps it will become cross, & go away
___ MultiMail/MS-DOS v0.35
---
* Origin: The Bare Bones BBS (1:105/360)
|