#!/bin/csh -f

set OSNAME=`uname -s|sed 's/[^a-zA-Z]//g'`

alias gosub 'set stack=(\!:3 $stack); set __args=(\!:2) ; goto \!:1'
alias return 'set __lab=$stack[1] ; set stack=($stack[2-]) ; goto $__lab'
alias matches 'echo \!:1 |egrep -i \!:2|wc -l'
set stack=()

if (! $?BACKUP_HOME) then
  set pnam=$0
  set pnam = $pnam:t
  if ($pnam == $0) then
    foreach dir ($path)
      if (-x $dir/$0) then
	set p=$dir/$0
	break
      endif
    end
    if ($p == ./$pnam) then
      set p=`pwd`
      setenv BACKUP_HOME  $p:h
    else
      set p=$p:h
      setenv BACKUP_HOME  $p:h
    endif
  else
    if (./$pnam == $0) then
      set p=`pwd`/$pnam
    else
      if (`echo $0|cut -c1` != "/") then
        set p=`pwd`/$0
      else
        set p=$0
      endif
    endif
    set p=$p:h
    setenv BACKUP_HOME $p:h
  endif
endif

set path=($BACKUP_HOME/bin $path)
rehash

unsetenv AWK

# the solaris awk is doin' dawn f...... BS
foreach awk (nawk gawk awk)
  foreach dir ($path)
    if (-x $dir/$awk) then
      setenv AWK $dir/$awk
      break
    endif
  end
  if ($?AWK) break
end

if (! $?AWK) then
  echo 'No awk ? Is this really a lovely UNIX ?'
  echo 'Sorry. I have to exit.'
  exit 1
endif

set found=0
set configfiles=($BACKUP_HOME/lib/backup.conf /etc/buclient.conf /etc/afbackup/client.conf "/etc/afbackup/client.conf")

foreach configfile ($configfiles)
  if (-r $configfile) then
    set found=1
    break
  endif
end
if (! $found) then
  echo "No configuration file found. Exiting."
  exit 2
endif

alias getparam $AWK' '"'"'/^[ 	]*'"'"'\!:1'"'"'/{split($0,a,"'"'"'\!:1'"'"'[ 	]*"); print a[2]}'"' $configfile"

set num_fix_params=20
set num_var_sp_idx=20

set comments=("")
set names=("")
set values=("")
set prompts=("")
set helps=("")
set patterns=("")

set i=-1
while ($i <= $num_fix_params)
  @ i++
  set comments=($comments $i)
  set names=($names $i)
  set values=($values $i)
  set prompts=($prompts $i)
  set helps=($helps $i)
  set patterns=($patterns $i)
end
set i=1
while ($i <= $#values)
  set values[$i]=""
  @ i++
end

set comments[1]="\The backup server host"
set comments[2]="\The backup server port-number"
set comments[3]="\The cartridge set to use"
set comments[4]='\The compress and decompress programs, if desired.'
set comments[5]=''
set comments[6]='\The part of the file, where the saved filenames\are stored (current number appended)'
set comments[7]='\Whether to compress the saved files'
set comments[8]='\Whether to compress the filename logfiles'
set comments[9]='\Patterns for names of files, no compression\is attempted on'
set comments[10]='\The number of such files, that are maintained.\More (older ones) are removed.'
set comments[11]='\The file where to log events'
set comments[12]='\The directory for varying files'
set comments[13]='\The file with the authentication encryption key'
set comments[14]='\The program to save startup information'
set comments[15]='\The program to be executed when everything requested is done.\%l is replaced by the filename-logfile, %r by the file with\ the report statistics, %e by the overall exit status'
set comments[16]="\The directory, where to run the backup"
set comments[17]='\Names of files to be skipped during the backup\(wildcards are allowed)'
set comments[18]='\Names of directories to be skipped during the backup\(wildcards are allowed)'
set comments[19]='\Name of a file containing a (pattern-) list of files\and directories to be skipped during the backup'
set comments[20]='\The number of parts of the full backup (if this takes a long time)'
set comments[21]='\The subdirectories of the RootDirectory to backup\(wildcards are allowed)'
set comments[22]='\The subdirectories of the RootDirectory to backup, part #num#\(wildcards are allowed)'

set names[1]='BackupHost'
set names[2]='BackupPort'
set names[3]='CartridgeSet'
set names[4]='CompressCmd'
set names[5]='UncompressCmd'
set names[6]='IndexFilePart'
set names[7]='CompressBackupedFiles'
set names[8]='CompressLogfiles'
set names[9]='DoNotCompress'
set names[10]='NumIndexesToStore'
set names[11]='LoggingFile'
set names[12]='VarDirectory'
set names[13]='EncryptionKeyFile'
set names[14]='StartupInfoProgram'
set names[15]='ExitProgram'
set names[16]='RootDirectory'
set names[17]='FilesToSkip'
set names[18]='DirsToSkip'
set names[19]='ExcludeListFile'
set names[20]='NumBackupParts'
set names[21]='DirsToBackup'
set names[22]='DirsToBackup#num#'

set patterns[1]='[Bb]ackup[ 	_-]*[Hh]ost:?[ 	]*'
set patterns[2]='[Bb]ackup[ 	_-]*[Pp]ort:?[ 	]*'
set patterns[3]='[Cc]artr?i?d?g?e?[-_ 	]*[Ss]et:?'
set patterns[4]='[Cc]ompress[-_ 	]*[Cc]o?m?ma?n?d:?[ 	]*'
set patterns[5]='[Uu]ncompress[-_ 	]*[Cc]o?m?ma?n?d:?[ 	]*'
set patterns[6]='[Ii]ndex[ 	_-]*[Ff]ile[ 	_-]*[Pp]art:?[ 	]*'
set patterns[7]='[Cc]ompress[-_ 	]*[Bb]ackupe?d?[-_ 	]*([Ff]iles)?:?'
set patterns[8]='[Cc]ompress[-_ 	]*[Ll]ogg?i?n?g?[-_ 	]*[Ff]iles:?'
set patterns[9]="[Dd]o[-_ 	]*[Nn].?[o]?t[-_ 	]*[Cc]ompress:?[ 	]*"
set patterns[10]='[Nn]um[-_ 	]*[Ii]nd(ic|ex)es[-_ 	]*[Tt]o[ 	_-]*[Ss]tore:?'
set patterns[11]='[Ll]ogg?i?n?g?[-_ 	]*[Ff]ile:?[ 	]*'
set patterns[12]='[Vv][Aa][Rr][-_ 	]*[Dd]ire?c?t?o?r?y?:?[ 	]*'
set patterns[13]='([Ee]n)?[Cc]rypti?o?n?[ 	_-]*[Kk]ey[ 	_-]*[Ff]ile:?[ 	]*'
set patterns[14]='[Ss]tartu?p?[-_ 	]*[Ii]nfo[-_ 	]*[Pp]rogram:?[ 	]*'
set patterns[15]='[Ee]xit[-_ 	]*[Pp]rogram:?[ 	]*'
set patterns[16]='[Rr]oot[ 	_-]*[Dd]ire?c?t?o?r?y?:?[ 	]*'
set patterns[17]='[Ff]iles[ 	_-]*[Tt]o[ 	_-]*[Ss]kip:?[ 	]*'
set patterns[18]='[Dd]ire?c?t?o?r?i?e?s[ 	_-]*[Tt]o[ 	_-]*[Ss]kip:?[ 	]*'
set patterns[19]='[Ee]xclu?d?e?[-_ 	]*[Ll]ist[-_ 	]*[Ff]ile[-_ 	]*[Nn]?a?m?e?:?[ 	]*'
set patterns[20]='[Nn]um[-_ 	]*[Bb]ackup[-_ 	]*[Pp]arts:?'
set patterns[21]='[Dd]ire?c?t?o?r?i?e?s[ 	_-]*[Tt]o[ 	_-]*[Bb]ackup:?[ 	]*'
set patterns[22]='[Dd]ire?c?t?o?r?i?e?s[ 	_-]*[Tt]o[ 	_-]*[Bb]ackup[ 	]*#num#[ 	]*:?'

set prompts[1]="Backup server hostname:        "
set prompts[2]="Backup server port-number:     "
set prompts[3]="Cartridge-set to use:          "
set prompts[4]='Compress program:              '
set prompts[5]='Decompress program:            '
set prompts[6]='Backup logging file part:      '
set prompts[7]='Compress saved files:          '
set prompts[8]='Compress filename logfiles:    '
set prompts[9]='Files not to be compressed:    '
set prompts[10]='Number of saved logging files: '
set prompts[11]='Event/error-logging file:      '
set prompts[12]='Var-Directory:                 '
set prompts[13]='Encryption-Key-File:           '
set prompts[14]='Startup info logging program:  '
set prompts[15]='Program to run at exit:        '
set prompts[16]="Working directory:             "
set prompts[17]='Names of files to skip:        '
set prompts[18]='Names of directories to skip:  '
set prompts[19]='File with names to skip:       '
set prompts[20]='Number of full backup parts:   '
set prompts[21]='Directories to backup:         '
set prompts[22]='Directories to backup, part #num#: '

set helps[1]="\\
This is the hostname of the machine where the server side\\
of the backup service resides. Some kind of streamer device\\
must be connected to this machine. The files and directories,\\
that should be saved, are packed, eventually compressed,\\
and then sent to the named machine, who writes them to the\\
connected device."
set helps[2]="\\
This is the port number on the backup server machine, where\\
the backup server process listens. The default is 2988 or the\\
number found in the file /etc/services (or in NIS if it is\\
configured)."
set helps[3]="\\
The cartridge set on the server side to use for backups.\\
It must be a legal number between 1 and the number of cartridge\\
sets configured on the server side."
set helps[4]="\\
If you want your files to be compressed, you can supply the\\
name of the program that should perform the compression here.\\
If you do so, you MUST also supply the appropriate decompress-\\
program. Note that this program may be specified with options\\
but no shell-like constructions such as pipes, variables or\\
wildcards. This program must read standard input and write to\\
standard output."
set helps[5]="\\
The counterpart to the compression program. You must either\\
supply both compress- and uncompress-program or neither of\\
them. Like the compress program, the uncompress-program must\\
read standard input and write to standard output."
set helps[6]="\\
The name of the file where the names of the saved files\\
are stored. The current number is appended to this filename.\\
The number is incremented each time a full backup starts."
set helps[7]="\\
This flag specifies, whether the files, that are saved,\\
should be compressed with the given compression program."
set helps[8]="\\
This flag specifies, whether the filename logging files\\
should be compressed with the given compression program."
set helps[9]="\\
These patterns or filenames specify files, that no\\
compression is attempted on. Normally compression is\\
attempted on all files, and if a file cannot be compressed\\
any further, it is saved uncompressed. This procedure is\\
unefficient for already compressed files, so their\\
compression can be suppressed with this parameter. The\\
value of this parameter must be a list seperated by\\
whitespace. Double quotes may enclose list elements.\\"
set helps[10]="\\
This number determines how many log files of previous full\\
backups are saved. These files may serve for the restore\\
of older files than those present in the actual backup.\\
Of course there must be sufficient space to hold all the\\
backups. It doesn't help to save all the saved filenames\\
but not to have them available on tape."
set helps[11]="\\
The name of a file error messages or other notable events\\
are written to."
set helps[12]="\\
The directory, where varying files should be put in. These\\
files must not be deleted. The information they contain is\\
necessary for restore."
set helps[13]="\\
The file containing the encryption key for authenticating\\
the backup client to the server. This file must contain\\
at least 5 characters and must not have read permission for\\
group or world."
if (`matches $OSNAME HPUX`) then
set helps[14]='\\
This is the (shell-) command to run at startup time of\\
incremental or full backup. This program should read the\\
standard input and do something reasonable with it, e.g.\\
append it to some file. The produced information can be\\
used to recover from a hard crash, when the files are\\
lost, that are containing the names of the saved files.'
else
set helps[14]='\\
This is the (shell-) command to run at startup time of\\
incremental or full backup. This program should read the\\
standard input and do something reasonable with it, e.g.\\
append it to some file. The produced information can be\\
used to recover from a hard crash, when the files are\\
lost, that are containing the names of the saved files.\\
Therefore this information should not be saved locally on\\
the client host, but e.g. on an NFS-mounted filesystem, a\\
floppy disc or in a mail-file (then this command should\\
be sth. like: mail someuser).'
endif
set helps[15]='\\
This parameter may specify a (shell-) command to run at\\
exit time of a full or incremental backup. The following\\
patterns are replaced as explained:\\
 %l  by the name of the file containing the filelists\\
 %r  by the name of the file containing statistics (this\\
     file is automatically removed after execution of this\\
     program)\\
 %e  by the overall exit status.'
set helps[16]="\\
This is the directory, the backup client changes to before\\
packing the files and directories. Their names should be\\
supplied relative to this directory, e.g. ./home ."
set helps[17]="\\
These are the names of files, that should not be saved.\\
Wildcards in the usual manner are allowed "'('"shell-style or\\
glob-style, furthermore path-patterns in the style of GNU's\\
find program with option -path. Note, that wildcards also\\
match directory separators i.e. slashes"')'". E.g. it usually\\
makes not much sense to back up object files, that can be\\
easily reproduced from existing program sources."
set helps[18]="\\
These are the names of directories, that should not be saved.\\
Wildcards in the usual manner are allowed "'('"shell-style or\\
glob-style, furthermore path-patterns in the style of GNU's\\
find program with option -path. Note, that wildcards also\\
match directory separators i.e. slashes"')'". E.g. it usually\\
makes not much sense to back up lost+found or directories\\
containing object files "'(often named obj)'
set helps[19]="\\
A file with the name supplied here can be present in any\\
directory. It should contain a list of file-/directory-names\\
(or glob-style patterns), that should be skipped during backup.\\
Each entry must be in an own line. The given names/patterns are\\
valid only in the same directory, where the file resides. Thus\\
each directory can have it's individual exclusion list."
set helps[20]="\\
If you have to backup a large amount of files and the\\
full backup can't be done during one run (e.g. over a\\
weekend), you can divide the full backup into pieces.\\
This number determines, how many pieces you need. If\\
this number is not equal to 1, you have to supply which\\
files and directories you want to save in which piece.\\
You do so by setting the additional parameters appearing\\
when you set this parameter greater than 1."
if (`matches $OSNAME HPUX`) then
set helps[21]="\\
These are the names of files and directories, that should be\\
saved. Usual wildcards are allowed (shell- or glob-style).\\
They should be given relative to the working directory, the\\
client changes to when starting. Supplying a filename preceded\\
with /../ forces the file contents to be saved regardless of\\
the file type. This way raw partitions or similar things can\\
be saved. To force these to be compressed, use the prefix //../\\
The prefix .//. limits reading to the actual filesystem."
else
set helps[21]="\\
These are the names of files and directories, that should be\\
saved. Wildcards in the usual manner are allowed (shell-\\
style or glob-style). They should be supplied relative to\\
the working directory, the client changes to when starting.\\
Descending into directories can be limited to the actual file-\\
system by preceding the filename with the four characters .//.\\
or the option -m (and a space). The prefix .//. is stripped\\
off the name before saving. Supplying a filename preceded with\\
the four characters /../ (what makes no sense normally) or\\
the option -r (and a space) forces the file contents to be\\
saved regardless of the file type. This way raw partitions\\
or similar things can be saved. The prefix /../ is stripped\\
off the name before saving. These file contents are by default\\
never compressed for safety reasons. If you want to force\\
compression nonetheless, use //../ as prefix or precede the\\
name with the option -R (and a space)."
endif
if (`matches $OSNAME HPUX`) then
set helps[22]="\\
These are the names of files and directories, that should be\\
saved as part #num#. Usual wildcards are allowed (shell-\\
or glob-style). They should be given relative to the working\\
directory the client changes to. Supplying a filename preceded\\
with /../ forces the file contents to be saved regardless of\\
the file type. This way raw partitions or similar things can\\
be saved. To force these to be compressed, use //../ as prefix.\\
The prefix .//. limits reading to the actual filesystem."
else
set helps[22]="\\
These are the names of files and directories, that should\\
be saved as part #num#. Wildcards in the usual manner\\
are allowed (shell-style or glob-style). They should be\\
supplied relative to the working directory the client\\
changes to when starting. Descending into directories can\\
be limited to the actual filesystem by preceding the file-\\
name with the four characters .//. or the option -m (and a\\
space). The prefix .//. is stripped off the name before\\
saving. Supplying a filename preceded with the four cha-\\
racters /../ (what makes no sense normally) or the option\\
-r (and a space) forces the file contents to be saved\\
regardless of the file type. This way raw partitions or\\
similar things can be saved. The prefix /../ is stripped\\
off the name before saving. These file contents are by\\
default never compressed for safety reasons. If you want\\
to force compression nonetheless, use //../ as prefix or\\
precede the name with the option -R (and a space)."
endif

@ var_param_idx=$num_fix_params + 2

echo -n "Reading actual settings "
set i=1
while ($i <= $num_fix_params)
  set values[$i]="`getparam '$patterns[$i]'`"
  echo -n .
  @ i++
end
gosub set_var_params "" cont1
cont1:
if ($num_var_params > 1) then
  set j=1
  while ($j <= $num_var_params)
    set parname="`echo '$patterns[$var_param_idx]'|sed 's/#num#/'$j/g`"
    set values[$i]="`getparam '$parname'`"
    @ j++
    @ i++
    echo -n .
  end
else
  set values[$first_var_param]="`getparam '$patterns[$first_var_param]'`"
  echo -n .
endif

echo " done"

menu:
gosub set_var_params "" cont2
cont2:
clear

set tmpfile=`tempfile || exit 1`
#/bin/rm -f $tmpfile
onintr cleantmp
#touch $tmpfile

set i=1
echo ' '
while ($i <= $num_fix_params)
  echo '   ['$i']	'"$prompts[$i]""$values[$i]" >> $tmpfile
  @ i++
end
set j=1
if ($num_var_params > 1) then
  while ($i <= $num_total_params)
    echo -n '   ['$i']	' >> $tmpfile
    set text="`echo '$prompts[$var_param_idx]' | sed 's/#num#/'$j/g`"
    echo "$text$values[$i]" >> $tmpfile
    @ i++
    @ j++
  end
else
  if ($num_var_params > 0) then
    echo '   ['$first_var_param']	'"$prompts[$first_var_param]""$values[$first_var_param]" >> $tmpfile
  endif
endif

(echo " " ;\
echo 'Please enter the number of the parameter you would like to' ;\
echo 'modify. Then, if you want to clear the entry, hit the Space- and' ;\
echo 'the Return-key. To get help enter: help, and the number of the' ;\
echo 'parameter you need help on. To exit and write out the changes' ;\
echo 'enter: ok. To exit without making any changes, enter: exit.' ) >> $tmpfile
more $tmpfile

/bin/rm -f $tmpfile
onintr

read_choice:
set c=blub
while (! `matches "$c" '^([1-9][0-9]*|help *[1-9][0-9]*|exit|quit|ok)$'`)
  echo " "
  echo -n "Your choice: "
  set c="$<"
  if (! `matches "$c" '^([1-9][0-9]*|help *[1-9][0-9]*|exit|quit|ok)$'`) then
    echo " "
    echo "Invalid choice. Please try again."
    goto read_choice
  endif
  if (`matches "$c" '^[1-9][0-9]*'`) then
    if ($c > $num_total_params || $c < 1) then
      echo " "
      echo "Invalid choice. Please try again."
      goto read_choice
    endif
  endif
end

if (`matches "$c" '^[1-9]'`) then
  echo ' '
  if ($c > $num_fix_params) then
    @ i=$c - $num_fix_params
    if ($num_var_params > 1) then
      echo "$prompts[$var_param_idx]"|sed 's/#num#/'"$i"'/g'
    else
      echo "$prompts[$first_var_param]"
    endif
  else
    echo "$prompts[$c]"
  endif
  echo -n "Please enter new value: "
  set i="$<"
  if ("$i" != "") then
    set values[$c]="$i"
  endif
  goto menu
endif

if (`matches "$c" quit` || `matches "$c" exit`) exit 0

if (`matches "$c" ok`) then
  \rm -f $configfile
  touch $configfile
  set i=1
  while ($i <= $num_total_params)
    if ($i <= $num_fix_params) then
      echo "$comments[$i]" | awk '{ a=$0; while((i=index(a,"\\"))>0){printf "# %s\n",substr(a,1,i-1);a=substr(a,i+1)} printf "# %s\n",a}' >> $configfile
      if (`echo "$values[$i]"|wc -w` == 0) then
	echo "#$names[$i]":"		$values[$i]" >> $configfile
      else
	echo "$names[$i]":"		$values[$i]" >> $configfile
      endif
    else
      @ j=$i - $num_fix_params
      if ($num_var_params > 1) then
        echo "$comments[$var_param_idx]" | sed 's/#num#/'$j/g | awk '{ a=$0; while((i=index(a,"\\"))>0){printf "# %s\n",substr(a,1,i-1);a=substr(a,i+1)} printf "# %s\n",a}' >> $configfile
	if (`echo "$values[$i]"|wc -w` == 0) then
          echo "#$names[$var_param_idx]":"		$values[$i]" | \
				sed 's/#num#/'"$j"'/g' >> $configfile
	else
          echo "$names[$var_param_idx]":"		$values[$i]" | \
				sed 's/#num#/'"$j"'/g' >> $configfile
	endif
      else
        echo "$comments[$first_var_param]" | awk '{ a=$0; while((i=index(a,"\\"))>0){printf "# %s\n",substr(a,1,i-1);a=substr(a,i+1)} printf "# %s\n",a}' >> $configfile
	if (`echo "$values[$i]"|wc -w` == 0) then
          echo "#$names[$first_var_param]":"		$values[$i]" | \
				sed 's/#num#/'"$j"'/g' >> $configfile
	else
          echo "$names[$first_var_param]":"		$values[$i]" | \
				sed 's/#num#/'"$j"'/g' >> $configfile
	endif
      endif
    endif
    @ i++
  end
  exit 0
endif

if (`matches "$c" help`) then
  set num=`echo "$c"|cut -c5-`
  if ($num <= $num_fix_params) then
    echo $helps[$num] | awk '{ a=$0; while((i=index(a,"\\"))>0){printf "%s\n",substr(a,1,i-1);a=substr(a,i+1)} printf "%s\n",a}'
  else
    if ($num_var_params > 1) then
      @ j=$num - $num_fix_params
      echo $helps[$var_param_idx] | sed 's/#num#/'$j/g | awk '{ a=$0; while((i=index(a,"\\"))>0){printf "%s\n",substr(a,1,i-1);a=substr(a,i+1)} printf "%s\n",a}'
    else
      echo $helps[$first_var_param] | awk '{ a=$0; while((i=index(a,"\\"))>0){printf "%s\n",substr(a,1,i-1);a=substr(a,i+1)} printf "%s\n",a}' | sed 's/#num#/'"$c"'/g'
    endif
  endif
  echo " "
  echo "Hit Return, when done."
  set d=$<
endif

goto menu


set_var_params:

if ($num_var_sp_idx > 0) then
  set num_var_params=$values[$num_var_sp_idx]
  if ("$num_var_params" == "") then
    set num_var_params=1
  endif
else
  set num_var_params=0
endif
@ num_total_params=$num_fix_params + $num_var_params
@ first_var_param=$num_fix_params + 1
if ($num_var_params > 1) then
  set max_num_vals=$#values
  if ($#values < $num_total_params) then
    set max_num_vals=$num_total_params
  endif
  set dummy=""
  set _i=1
  while ($_i <= $max_num_vals)
    set dummy=(1 $dummy)
    @ _i++
  end
  set dummy2=($dummy)
  set _i=1
  while ($_i <= $max_num_vals)
    set dummy[$_i]=""
    @ _i++
  end
  set _i=1
  while ($_i <= $#values)
    set dummy[$_i]="$values[$_i]"
    @ _i++
  end
  set values=($dummy2)
  set _i=1
  while ($_i <= $max_num_vals)
    set values[$_i]="$dummy[$_i]"
    @ _i++
  end
endif

return

cleantmp:
/bin/rm -f $tmpfile
onintr
exit 2
