Tillbaka till svenska Fidonet
English   Information   Debug  
IC   0/2851
INTERNET   0/424
INTERUSER   0/3
IP_CONNECT   719
JAMNNTPD   0/233
JAMTLAND   0/47
KATTY_KORNER   0/41
LAN   0/16
LINUX-USER   0/19
LINUXHELP   0/1155
LINUX   0/22013
LINUX_BBS   0/957
mail   18.68
mail_fore_ok   249
MENSA   0/341
MODERATOR   0/102
MONTE   0/992
MOSCOW_OKLAHOMA   0/1245
MUFFIN   0/783
MUSIC   0/321
N203_STAT   900
N203_SYSCHAT   313
NET203   321
NET204   69
NET_DEV   0/10
NORD.ADMIN   0/101
NORD.CHAT   0/2572
NORD.FIDONET   189
NORD.HARDWARE   0/28
NORD.KULTUR   0/114
NORD.PROG   0/32
NORD.SOFTWARE   0/88
NORD.TEKNIK   0/58
NORD   0/453
OCCULT_CHAT   0/93
OS2BBS   0/787
OS2DOSBBS   0/580
OS2HW   0/42
OS2INET   0/37
OS2LAN   0/134
OS2PROG   0/36
OS2REXX   0/113
OS2USER-L   207
OS2   0/4785
OSDEBATE   0/18996
PASCAL   0/490
PERL   0/457
PHP   0/45
POINTS   0/405
POLITICS   0/29554
POL_INC   0/14731
PSION   103
R20_ADMIN   1117
R20_AMATORRADIO   0/2
R20_BEST_OF_FIDONET   13
R20_CHAT   0/893
R20_DEPP   0/3
R20_DEV   399
R20_ECHO2   1379
R20_ECHOPRES   0/35
R20_ESTAT   0/719
R20_FIDONETPROG...
...RAM.MYPOINT
  0/2
R20_FIDONETPROGRAM   0/22
R20_FIDONET   0/248
R20_FILEFIND   0/24
R20_FILEFOUND   0/22
R20_HIFI   0/3
R20_INFO2   2817
R20_INTERNET   0/12940
R20_INTRESSE   0/60
R20_INTR_KOM   0/99
R20_KANDIDAT.CHAT   42
R20_KANDIDAT   28
R20_KOM_DEV   112
R20_KONTROLL   0/13070
R20_KORSET   0/18
R20_LOKALTRAFIK   0/24
R20_MODERATOR   0/1852
R20_NC   76
R20_NET200   245
R20_NETWORK.OTH...
...ERNETS
  0/13
R20_OPERATIVSYS...
...TEM.LINUX
  0/44
R20_PROGRAMVAROR   0/1
R20_REC2NEC   534
R20_SFOSM   0/340
R20_SF   0/108
R20_SPRAK.ENGLISH   0/1
R20_SQUISH   107
R20_TEST   2
R20_WORST_OF_FIDONET   12
RAR   0/9
RA_MULTI   106
RA_UTIL   0/162
REGCON.EUR   0/2055
REGCON   0/13
SCIENCE   0/1206
SF   0/239
SHAREWARE_SUPPORT   0/5146
SHAREWRE   0/14
SIMPSONS   0/169
STATS_OLD1   0/2539.065
STATS_OLD2   0/2530
STATS_OLD3   0/2395.095
STATS_OLD4   0/1692.25
SURVIVOR   0/495
SYSOPS_CORNER   0/3
SYSOP   0/84
TAGLINES   0/112
TEAMOS2   0/4530
TECH   0/2617
TEST.444   0/105
TRAPDOOR   0/19
TREK   0/755
TUB   0/290
UFO   0/40
UNIX   0/1316
USA_EURLINK   0/102
USR_MODEMS   0/1
VATICAN   0/2740
VIETNAM_VETS   0/14
VIRUS   0/378
VIRUS_INFO   0/201
VISUAL_BASIC   0/473
WHITEHOUSE   0/5187
WIN2000   0/101
WIN32   0/30
WIN95   0/4277
WIN95_OLD1   0/70272
WINDOWS   0/1517
WWB_SYSOP   0/419
WWB_TECH   0/810
ZCC-PUBLIC   0/1
ZEC   4

 
4DOS   0/134
ABORTION   0/7
ALASKA_CHAT   0/506
ALLFIX_FILE   0/1313
ALLFIX_FILE_OLD1   0/7997
ALT_DOS   0/152
AMATEUR_RADIO   0/1039
AMIGASALE   0/14
AMIGA   0/331
AMIGA_INT   0/1
AMIGA_PROG   0/20
AMIGA_SYSOP   0/26
ANIME   0/15
ARGUS   0/924
ASCII_ART   0/340
ASIAN_LINK   0/651
ASTRONOMY   0/417
AUDIO   0/92
AUTOMOBILE_RACING   0/105
BABYLON5   0/17862
BAG   135
BATPOWER   0/361
BBBS.ENGLISH   0/382
BBSLAW   0/109
BBS_ADS   0/5290
BBS_INTERNET   0/507
BIBLE   0/3563
BINKD   0/1119
BINKLEY   0/215
BLUEWAVE   0/2173
CABLE_MODEMS   0/25
CBM   0/46
CDRECORD   0/66
CDROM   0/20
CLASSIC_COMPUTER   0/378
COMICS   0/15
CONSPRCY   0/899
COOKING   28619
COOKING_OLD1   0/24719
COOKING_OLD2   0/40862
COOKING_OLD3   0/37489
COOKING_OLD4   0/35496
COOKING_OLD5   9370
C_ECHO   0/189
C_PLUSPLUS   0/31
DIRTY_DOZEN   0/201
DOORGAMES   0/2025
DOS_INTERNET   0/196
duplikat   6000
ECHOLIST   0/18295
EC_SUPPORT   0/318
ELECTRONICS   0/359
ELEKTRONIK.GER   1534
ENET.LINGUISTIC   0/13
ENET.POLITICS   0/4
ENET.SOFT   0/11701
ENET.SYSOP   33806
ENET.TALKS   0/32
ENGLISH_TUTOR   0/2000
EVOLUTION   0/1335
FDECHO   0/217
FDN_ANNOUNCE   0/7068
FIDONEWS   23548
FIDONEWS_OLD1   0/49742
FIDONEWS_OLD2   0/35949
FIDONEWS_OLD3   0/30874
FIDONEWS_OLD4   0/37224
FIDO_SYSOP   12847
FIDO_UTIL   0/180
FILEFIND   0/209
FILEGATE   0/212
FILM   0/18
FNEWS_PUBLISH   4200
FN_SYSOP   41525
FN_SYSOP_OLD1   71952
FTP_FIDO   0/2
FTSC_PUBLIC   0/13586
FUNNY   0/4886
GENEALOGY.EUR   0/71
GET_INFO   105
GOLDED   0/408
HAM   0/16053
HOLYSMOKE   0/6791
HOT_SITES   0/1
HTMLEDIT   0/71
HUB203   466
HUB_100   264
HUB_400   39
HUMOR   0/29
Möte LINUX, 22013 texter
 lista första sista föregående nästa
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)