]> git.sur5r.net Git - openldap/blob - build/shtool
Update to 1.6.1
[openldap] / build / shtool
1 #!/bin/sh
2 # $OpenLDAP$
3 # This file is distributed with OpenLDAP Software, but is an
4 # an independently licensed program.
5
6 ##
7 ##  GNU shtool -- The GNU Portable Shell Tool
8 ##  Copyright (c) 1994-2002 Ralf S. Engelschall <rse@engelschall.com>
9 ##
10 ##  See http://www.gnu.org/software/shtool/ for more information.
11 ##  See ftp://ftp.gnu.org/gnu/shtool/ for latest version.
12 ##
13 ##  Version:  1.6.1 (12-Jul-2002)
14 ##  Contents: 6/19 available modules
15 ##
16
17 ##
18 ##  This program is free software; you can redistribute it and/or modify
19 ##  it under the terms of the GNU General Public License as published by
20 ##  the Free Software Foundation; either version 2 of the License, or
21 ##  (at your option) any later version.
22 ##
23 ##  This program is distributed in the hope that it will be useful,
24 ##  but WITHOUT ANY WARRANTY; without even the implied warranty of
25 ##  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
26 ##  General Public License for more details.
27 ##
28 ##  You should have received a copy of the GNU General Public License
29 ##  along with this program; if not, write to the Free Software
30 ##  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
31 ##  USA, or contact Ralf S. Engelschall <rse@engelschall.com>.
32 ##
33 ##  NOTICE: Given that you include this file verbatim into your own
34 ##  source tree, you are justified in saying that it remains separate
35 ##  from your package, and that this way you are simply just using GNU
36 ##  shtool. So, in this situation, there is no requirement that your
37 ##  package itself is licensed under the GNU General Public License in
38 ##  order to take advantage of GNU shtool.
39 ##
40
41 ##
42 ##  Usage: shtool [<options>] [<cmd-name> [<cmd-options>] [<cmd-args>]]
43 ##
44 ##  Available commands:
45 ##    echo       Print string with optional construct expansion
46 ##    move       Move files with simultaneous substitution
47 ##    install    Install a program, script or datafile
48 ##    mkdir      Make one or more directories
49 ##    mkln       Make link with calculation of relative paths
50 ##    subst      Apply sed(1) substitution operations
51 ##
52 ##  Not available commands (because module was not built-in):
53 ##    mdate      Pretty-print modification time of a file or dir
54 ##    table      Pretty-print a field-separated list as a table
55 ##    prop       Display progress with a running propeller
56 ##    mkshadow   Make a shadow tree through symbolic links
57 ##    fixperm    Fix file permissions inside a source tree
58 ##    rotate     Logfile rotation
59 ##    tarball    Roll distribution tarballs
60 ##    guessos    Simple operating system guesser
61 ##    arx        Extended archive command
62 ##    slo        Separate linker options by library class
63 ##    scpp       Sharing C Pre-Processor
64 ##    version    Maintain a version information file
65 ##    path       Deal with program paths
66 ##
67
68 if [ $# -eq 0 ]; then
69     echo "$0:Error: invalid command line" 1>&2
70     echo "$0:Hint:  run \`$0 -h' for usage" 1>&2
71     exit 1
72 fi
73 if [ ".$1" = ".-h" -o ".$1" = ".--help" ]; then
74     echo "This is GNU shtool, version 1.6.1 (12-Jul-2002)"
75     echo "Copyright (c) 1994-2002 Ralf S. Engelschall <rse@engelschall.com>"
76     echo "Report bugs to <bug-shtool@gnu.org>"
77     echo ''
78     echo "Usage: shtool [<options>] [<cmd-name> [<cmd-options>] [<cmd-args>]]"
79     echo ''
80     echo 'Available global <options>:'
81     echo '  -v, --version   display shtool version information'
82     echo '  -h, --help      display shtool usage help page (this one)'
83     echo '  -d, --debug     display shell trace information'
84     echo '  -r, --recreate  recreate this shtool script via shtoolize'
85     echo ''
86     echo 'Available <cmd-name> [<cmd-options>] [<cmd-args>]:'
87     echo '  echo     [-n|--newline] [-e|--expand] [<str> ...]'
88     echo '  move     [-v|--verbose] [-t|--trace] [-e|--expand] [-p|--preserve]'
89     echo '           <src-file> <dst-file>'
90     echo '  install  [-v|--verbose] [-t|--trace] [-c|--copy] [-C|--compare-copy]'
91     echo '           [-s|--strip] [-m|--mode <mode>] [-o|--owner <owner>]'
92     echo '           [-g|--group <group>] [-e|--exec <sed-cmd>] <file> [<file>'
93     echo '           ...] <path>'
94     echo '  mkdir    [-t|--trace] [-f|--force] [-p|--parents] [-m|--mode'
95     echo '           <mode>] <dir> [<dir> ...]'
96     echo '  mkln     [-t|--trace] [-f|--force] [-s|--symbolic] <src-path>'
97     echo '           [<src-path> ...] <dst-path>'
98     echo '  subst    [-v|--verbose] [-t|--trace] [-n|--nop] [-s|--stealth]'
99     echo '           [-i|--interactive] [-b|--backup <ext>] [-e|--exec <cmd>]'
100     echo '           [-f|--file <cmd-file>] [<file>] [...]'
101     echo ''
102     echo 'Not available <cmd-name> (because module was not built-in):'
103     echo '  mdate    [-n|--newline] [-z|--zero] [-s|--shorten] [-d|--digits]'
104     echo '           [-f|--field-sep <str>] [-o|--order <spec>] <path>'
105     echo '  table    [-F|--field-sep <sep>] [-w|--width <width>] [-c|--columns'
106     echo '           <cols>] [-s|--strip <strip>] <str><sep><str>...'
107     echo '  prop     [-p|--prefix <str>]'
108     echo '  mkshadow [-v|--verbose] [-t|--trace] [-a|--all] <src-dir> <dst-dir>'
109     echo '  fixperm  [-v|--verbose] [-t|--trace] <path> [<path> ...]'
110     echo '  rotate   [-v|--verbose] [-t|--trace] [-f|--force] [-n|--num-files'
111     echo '           <count>] [-s|--size <size>] [-c|--copy] [-r|--remove]'
112     echo '           [-a|--archive-dir <dir>] [-z|--compress [<tool>:]<level>]'
113     echo '           [-b|--background] [-d|--delay] [-p|--pad <len>] [-o|--owner'
114     echo '           <owner>] [-g|--group <group>] [-m|--mode <mode>] [-M|--migrate'
115     echo '           <cmd>] [-P|--prolog <cmd>] [-E|--epilog <cmd>] <file> [...]'
116     echo '  tarball  [-t|--trace] [-v|--verbose] [-o|--output <tarball>]'
117     echo '           [-c|--compress <prog>] [-d|--directory <dir>] [-u|--user'
118     echo '           <user>] [-g|--group <group>] [-e|--exclude <pattern>]'
119     echo '           <path> [<path> ...]'
120     echo '  guessos  '
121     echo '  arx      [-t|--trace] [-C|--command <cmd>] <op> <archive> [<file>'
122     echo '           ...]'
123     echo '  slo      [-p|--prefix <str>] -- -L<dir> -l<lib> [-L<dir> -l<lib>'
124     echo '           ...]'
125     echo '  scpp     [-v|--verbose] [-p|--preserve] [-f|--filter <filter>]'
126     echo '           [-o|--output <ofile>] [-t|--template <tfile>] [-M|--mark'
127     echo '           <mark>] [-D|--define <dname>] [-C|--class <cname>]'
128     echo '           <file> [<file> ...]'
129     echo '  version  [-l|--language <lang>] [-n|--name <name>] [-p|--prefix'
130     echo '           <prefix>] [-s|--set <version>] [-e|--edit] [-i|--increase'
131     echo '           <knob>] [-d|--display <type>] <file>'
132     echo '  path     [-s|--suppress] [-r|--reverse] [-d|--dirname] [-b|--basename]'
133     echo '           [-m|--magic] [-p|--path <path>] <str> [<str> ...]'
134     echo ''
135     exit 0
136 fi
137 if [ ".$1" = ".-v" -o ".$1" = ."--version" ]; then
138     echo "GNU shtool 1.6.1 (12-Jul-2002)"
139     exit 0
140 fi
141 if [ ".$1" = ".-r" -o ".$1" = ."--recreate" ]; then
142     shtoolize -obuild/shtool echo move install mkdir mkln subst
143     exit 0
144 fi
145 if [ ".$1" = ".-d" -o ".$1" = ."--debug" ]; then
146     shift
147     set -x
148 fi
149 name=`echo "$0" | sed -e 's;.*/\([^/]*\)$;\1;' -e 's;-sh$;;' -e 's;\.sh$;;'`
150 case "$name" in
151     echo|move|install|mkdir|mkln|subst )
152         #   implicit tool command selection
153         tool="$name"
154         ;;
155     * )
156         #   explicit tool command selection
157         tool="$1"
158         shift
159         ;;
160 esac
161 arg_spec=""
162 opt_spec=""
163 gen_tmpfile=no
164
165 ##
166 ##  DISPATCH INTO SCRIPT PROLOG
167 ##
168
169 case $tool in
170     echo )
171         str_tool="echo"
172         str_usage="[-n|--newline] [-e|--expand] [<str> ...]"
173         arg_spec="0+"
174         opt_spec="n.e."
175         opt_alias="n:newline,e:expand"
176         opt_n=no
177         opt_e=no
178         ;;
179     move )
180         str_tool="move"
181         str_usage="[-v|--verbose] [-t|--trace] [-e|--expand] [-p|--preserve] <src-file> <dst-file>"
182         arg_spec="2="
183         opt_spec="v.t.e.p."
184         opt_alias="v:verbose,t:trace,e:expand,p:preserve"
185         opt_v=no
186         opt_t=no
187         opt_e=no
188         opt_p=no
189         ;;
190     install )
191         str_tool="install"
192         str_usage="[-v|--verbose] [-t|--trace] [-c|--copy] [-C|--compare-copy] [-s|--strip] [-m|--mode <mode>] [-o|--owner <owner>] [-g|--group <group>] [-e|--exec <sed-cmd>] <file> [<file> ...] <path>"
193         arg_spec="2+"
194         opt_spec="v.t.c.C.s.m:o:g:e+"
195         opt_alias="v:verbose,t:trace,c:copy,C:compare-copy,s:strip,m:mode,o:owner,g:group,e:exec"
196         opt_v=no
197         opt_t=no
198         opt_c=no
199         opt_C=no
200         opt_s=no
201         opt_m="0755"
202         opt_o=""
203         opt_g=""
204         opt_e=""
205         ;;
206     mkdir )
207         str_tool="mkdir"
208         str_usage="[-t|--trace] [-f|--force] [-p|--parents] [-m|--mode <mode>] <dir> [<dir> ...]"
209         arg_spec="1+"
210         opt_spec="t.f.p.m:"
211         opt_alias="t:trace,f:force,p:parents,m:mode"
212         opt_t=no
213         opt_f=no
214         opt_p=no
215         opt_m=""
216         ;;
217     mkln )
218         str_tool="mkln"
219         str_usage="[-t|--trace] [-f|--force] [-s|--symbolic] <src-path> [<src-path> ...] <dst-path>"
220         arg_spec="2+"
221         opt_spec="t.f.s."
222         opt_alias="t:trace,f:force,s:symbolic"
223         opt_t=no
224         opt_f=no
225         opt_s=no
226         ;;
227     subst )
228         str_tool="subst"
229         str_usage="[-v|--verbose] [-t|--trace] [-n|--nop] [-s|--stealth] [-i|--interactive] [-b|--backup <ext>] [-e|--exec <cmd>] [-f|--file <cmd-file>] [<file>] [...]"
230         gen_tmpfile=yes
231         arg_spec="0+"
232         opt_spec="v.t.n.s.i.b:e+f:"
233         opt_alias="v:verbose,t:trace,n:nop,s:stealth,i:interactive,b:backup,e:exec,f:file"
234         opt_v=no
235         opt_t=no
236         opt_n=no
237         opt_s=no
238         opt_i=no
239         opt_b=""
240         opt_e=""
241         opt_f=""
242         ;;
243     -* )
244         echo "$0:Error: unknown option \`$tool'" 2>&1
245         echo "$0:Hint:  run \`$0 -h' for usage" 2>&1
246         exit 1
247         ;;
248     * )
249         echo "$0:Error: unknown command \`$tool'" 2>&1
250         echo "$0:Hint:  run \`$0 -h' for usage" 2>&1
251         exit 1
252         ;;
253 esac
254
255 ##
256 ##  COMMON UTILITY CODE
257 ##
258
259 #   commonly used ASCII values
260 ASC_TAB="       "
261 ASC_NL="
262 "
263
264 #   determine name of tool
265 if [ ".$tool" != . ]; then
266     #   used inside shtool script
267     toolcmd="$0 $tool"
268     toolcmdhelp="shtool $tool"
269     msgprefix="shtool:$tool"
270 else
271     #   used as standalone script
272     toolcmd="$0"
273     toolcmdhelp="sh $0"
274     msgprefix="$str_tool"
275 fi
276
277 #   parse argument specification string
278 eval `echo $arg_spec |\
279       sed -e 's/^\([0-9]*\)\([+=]\)/arg_NUMS=\1; arg_MODE=\2/'`
280
281 #   parse option specification string
282 eval `echo h.$opt_spec |\
283       sed -e 's/\([a-zA-Z0-9]\)\([.:+]\)/opt_MODE_\1=\2;/g'`
284
285 #   parse option alias string
286 eval `echo h:help,$opt_alias |\
287       tr 'x-' 'x_' | sed -e 's/\([a-zA-Z0-9]\):\([^,]*\),*/opt_ALIAS_\2=\1;/g'`
288
289 #   interate over argument line
290 opt_PREV=''
291 while [ $# -gt 0 ]; do
292     #   special option stops processing
293     if [ ".$1" = ".--" ]; then
294         shift
295         break
296     fi
297
298     #   determine option and argument
299     opt_ARG_OK=no
300     if [ ".$opt_PREV" != . ]; then
301         #   merge previous seen option with argument
302         opt_OPT="$opt_PREV"
303         opt_ARG="$1"
304         opt_ARG_OK=yes
305         opt_PREV=''
306     else
307         #   split argument into option and argument
308         case "$1" in
309             --[a-zA-Z0-9]*=*)
310                 eval `echo "x$1" |\
311                       sed -e 's/^x--\([a-zA-Z0-9-]*\)=\(.*\)$/opt_OPT="\1";opt_ARG="\2"/'`
312                 opt_STR=`echo $opt_OPT | tr 'x-' 'x_'`
313                 eval "opt_OPT=\${opt_ALIAS_${opt_STR}-${opt_OPT}}"
314                 ;;
315             --[a-zA-Z0-9]*)
316                 opt_OPT=`echo "x$1" | cut -c4-`
317                 opt_STR=`echo $opt_OPT | tr 'x-' 'x_'`
318                 eval "opt_OPT=\${opt_ALIAS_${opt_STR}-${opt_OPT}}"
319                 opt_ARG=''
320                 ;;
321             -[a-zA-Z0-9]*)
322                 eval `echo "x$1" |\
323                       sed -e 's/^x-\([a-zA-Z0-9]\)/opt_OPT="\1";/' \
324                           -e 's/";\(.*\)$/"; opt_ARG="\1"/'`
325                 ;;
326             -[a-zA-Z0-9])
327                 opt_OPT=`echo "x$1" | cut -c3-`
328                 opt_ARG=''
329                 ;;
330             *)
331                 break
332                 ;;
333         esac
334     fi
335
336     #   eat up option
337     shift
338
339     #   determine whether option needs an argument
340     eval "opt_MODE=\$opt_MODE_${opt_OPT}"
341     if [ ".$opt_ARG" = . -a ".$opt_ARG_OK" != .yes ]; then
342         if [ ".$opt_MODE" = ".:" -o ".$opt_MODE" = ".+" ]; then
343             opt_PREV="$opt_OPT"
344             continue
345         fi
346     fi
347
348     #   process option
349     case $opt_MODE in
350         '.' )
351             #   boolean option
352             eval "opt_${opt_OPT}=yes"
353             ;;
354         ':' )
355             #   option with argument (multiple occurances override)
356             eval "opt_${opt_OPT}=\"\$opt_ARG\""
357             ;;
358         '+' )
359             #   option with argument (multiple occurances append)
360             eval "opt_${opt_OPT}=\"\$opt_${opt_OPT}\${ASC_NL}\$opt_ARG\""
361             ;;
362         * )
363             echo "$msgprefix:Error: unknown option: \`$opt_OPT'" 1>&2
364             echo "$msgprefix:Hint:  run \`$toolcmdhelp -h' or \`man shtool' for details" 1>&2
365             exit 1
366             ;;
367     esac
368 done
369 if [ ".$opt_PREV" != . ]; then
370     echo "$msgprefix:Error: missing argument to option \`$opt_PREV'" 1>&2
371     echo "$msgprefix:Hint:  run \`$toolcmdhelp -h' or \`man shtool' for details" 1>&2
372     exit 1
373 fi
374
375 #   process help option
376 if [ ".$opt_h" = .yes ]; then
377     echo "Usage: $toolcmdhelp $str_usage"
378     exit 0
379 fi
380
381 #   complain about incorrect number of arguments
382 case $arg_MODE in
383     '=' )
384         if [ $# -ne $arg_NUMS ]; then
385             echo "$msgprefix:Error: invalid number of arguments (exactly $arg_NUMS expected)" 1>&2
386             echo "$msgprefix:Hint:  run \`$toolcmd -h' or \`man shtool' for details" 1>&2
387             exit 1
388         fi
389         ;;
390     '+' )
391         if [ $# -lt $arg_NUMS ]; then
392             echo "$msgprefix:Error: invalid number of arguments (at least $arg_NUMS expected)" 1>&2
393             echo "$msgprefix:Hint:  run \`$toolcmd -h' or \`man shtool' for details" 1>&2
394             exit 1
395         fi
396         ;;
397 esac
398
399 #   establish a temporary file on request
400 if [ ".$gen_tmpfile" = .yes ]; then
401     if [ ".$TMPDIR" != . ]; then
402         tmpdir="$TMPDIR"
403     elif [ ".$TEMPDIR" != . ]; then
404         tmpdir="$TEMPDIR"
405     else
406         tmpdir="/tmp"
407     fi
408     tmpfile="$tmpdir/.shtool.$$"
409     rm -f $tmpfile >/dev/null 2>&1
410     touch $tmpfile
411     chmod 600 $tmpfile
412 fi
413
414 ##
415 ##  DISPATCH INTO SCRIPT BODY
416 ##
417
418 case $tool in
419
420 echo )
421     ##
422     ##  echo -- Print string with optional construct expansion
423     ##  Copyright (c) 1998-2002 Ralf S. Engelschall <rse@engelschall.com>
424     ##  Originally written for WML as buildinfo
425     ##
426     
427     text="$*"
428     
429     #   check for broken escape sequence expansion
430     seo=''
431     bytes=`echo '\1' | wc -c | awk '{ printf("%s", $1); }'`
432     if [ ".$bytes" != .3 ]; then
433         bytes=`echo -E '\1' | wc -c | awk '{ printf("%s", $1); }'`
434         if [ ".$bytes" = .3 ]; then
435             seo='-E'
436         fi
437     fi
438     
439     #   check for existing -n option (to suppress newline)
440     minusn=''
441     bytes=`echo -n 123 2>/dev/null | wc -c | awk '{ printf("%s", $1); }'`
442     if [ ".$bytes" = .3 ]; then
443         minusn='-n'
444     fi
445     
446     #   determine terminal bold sequence
447     term_bold=''
448     term_norm=''
449     if [ ".$opt_e" = .yes -a ".`echo $text | egrep '%[Bb]'`" != . ]; then
450         case $TERM in
451             #   for the most important terminal types we directly know the sequences
452             xterm|xterm*|vt220|vt220*)
453                 term_bold=`awk 'BEGIN { printf("%c%c%c%c", 27, 91, 49, 109); }' </dev/null 2>/dev/null`
454                 term_norm=`awk 'BEGIN { printf("%c%c%c", 27, 91, 109); }' </dev/null 2>/dev/null`
455                 ;;
456             vt100|vt100*)
457                 term_bold=`awk 'BEGIN { printf("%c%c%c%c%c%c", 27, 91, 49, 109, 0, 0); }' </dev/null 2>/dev/null`
458                 term_norm=`awk 'BEGIN { printf("%c%c%c%c%c", 27, 91, 109, 0, 0); }' </dev/null 2>/dev/null`
459                 ;;
460             #   for all others, we try to use a possibly existing `tput' or `tcout' utility
461             * )
462                 paths=`echo $PATH | sed -e 's/:/ /g'`
463                 for tool in tput tcout; do
464                     for dir in $paths; do
465                         if [ -r "$dir/$tool" ]; then
466                             for seq in bold md smso; do # 'smso' is last
467                                 bold="`$dir/$tool $seq 2>/dev/null`"
468                                 if [ ".$bold" != . ]; then
469                                     term_bold="$bold"
470                                     break
471                                 fi
472                             done
473                             if [ ".$term_bold" != . ]; then
474                                 for seq in sgr0 me rmso reset; do # 'reset' is last
475                                     norm="`$dir/$tool $seq 2>/dev/null`"
476                                     if [ ".$norm" != . ]; then
477                                         term_norm="$norm"
478                                         break
479                                     fi
480                                 done
481                             fi
482                             break
483                         fi
484                     done
485                     if [ ".$term_bold" != . -a ".$term_norm" != . ]; then
486                         break;
487                     fi
488                 done
489                 ;;
490         esac
491         if [ ".$term_bold" = . -o ".$term_norm" = . ]; then
492             echo "$msgprefix:Warning: unable to determine terminal sequence for bold mode" 1>&2
493         fi
494     fi
495     
496     #   determine user name
497     username=''
498     if [ ".$opt_e" = .yes -a ".`echo $text | egrep '%[uUgG]'`" != . ]; then
499         username="$LOGNAME"
500         if [ ".$username" = . ]; then
501             username="$USER"
502             if [ ".$username" = . ]; then
503                 username="`(whoami) 2>/dev/null |\
504                            awk '{ printf("%s", $1); }'`"
505                 if [ ".$username" = . ]; then
506                     username="`(who am i) 2>/dev/null |\
507                                awk '{ printf("%s", $1); }'`"
508                     if [ ".$username" = . ]; then
509                         username='unknown'
510                     fi
511                 fi
512             fi
513         fi
514     fi
515     
516     #   determine user id
517     userid=''
518     if [ ".$opt_e" = .yes -a ".`echo $text | egrep '%U'`" != . ]; then
519         userid="`(id -u) 2>/dev/null`"
520         if [ ".$userid" = . ]; then
521             str="`(id) 2>/dev/null`"
522             if [ ".`echo $str | grep '^uid[     ]*=[    ]*[0-9]*('`" != . ]; then
523                 userid=`echo $str | sed -e 's/^uid[     ]*=[    ]*//' -e 's/(.*//'`
524             fi
525             if [ ".$userid" = . ]; then
526                 userid=`egrep "^${username}:" /etc/passwd 2>/dev/null | \
527                         sed -e 's/[^:]*:[^:]*://' -e 's/:.*$//'`
528                 if [ ".$userid" = . ]; then
529                     userid=`(ypcat passwd) 2>/dev/null |
530                             egrep "^${username}:" | \
531                             sed -e 's/[^:]*:[^:]*://' -e 's/:.*$//'`
532                     if [ ".$userid" = . ]; then
533                         userid='?'
534                     fi
535                 fi
536             fi
537         fi
538     fi
539     
540     #   determine (primary) group id
541     groupid=''
542     if [ ".$opt_e" = .yes -a ".`echo $text | egrep '%[gG]'`" != . ]; then
543         groupid=`egrep "^${username}:" /etc/passwd 2>/dev/null | \
544                  sed -e 's/[^:]*:[^:]*:[^:]*://' -e 's/:.*$//'`
545         if [ ".$groupid" = . ]; then
546             groupid=`(ypcat passwd) 2>/dev/null | egrep "^${username}:" | \
547                      sed -e 's/[^:]*:[^:]*:[^:]*://' -e 's/:.*$//'`
548             if [ ".$groupid" = . ]; then
549                 groupid='?'
550             fi
551         fi
552     fi
553     
554     #   determine (primary) group name
555     groupname=''
556     if [ ".$opt_e" = .yes -a ".`echo $text | egrep '%g'`" != . ]; then
557         groupname=`egrep "^[^:]*:[^:]*:${groupid}:" /etc/group 2>/dev/null | \
558                    sed -e 's/:.*$//'`
559         if [ ".$groupname" = . ]; then
560             groupname=`(ypcat group) 2>/dev/null | \
561                        egrep "^[^:]*:[^:]*:${groupid}:" | \
562                        sed -e 's/:.*$//'`
563             if [ ".$groupname" = . ]; then
564                 groupname='?'
565             fi
566         fi
567     fi
568     
569     #   determine host and domain name
570     hostname=''
571     domainname=''
572     if [ ".$opt_e" = .yes -a ".`echo $text | egrep '%h'`" != . ]; then
573         hostname="`(uname -n) 2>/dev/null |\
574                    awk '{ printf("%s", $1); }'`"
575         if [ ".$hostname" = . ]; then
576             hostname="`(hostname) 2>/dev/null |\
577                        awk '{ printf("%s", $1); }'`"
578             if [ ".$hostname" = . ]; then
579                 hostname='unknown'
580             fi
581         fi
582         case $hostname in
583             *.* )
584                 domainname=".`echo $hostname | cut -d. -f2-`"
585                 hostname="`echo $hostname | cut -d. -f1`"
586                 ;;
587         esac
588     fi
589     if [ ".$opt_e" = .yes -a ".`echo $text | egrep '%d'`" != . ]; then
590         if [ ".$domainname" = . ]; then
591             if [ -f /etc/resolv.conf ]; then
592                 domainname="`egrep '^[  ]*domain' /etc/resolv.conf | sed -e 'q' |\
593                              sed -e 's/.*domain//' \
594                                  -e 's/^[       ]*//' -e 's/^ *//' -e 's/^      *//' \
595                                  -e 's/^\.//' -e 's/^/./' |\
596                              awk '{ printf("%s", $1); }'`"
597                 if [ ".$domainname" = . ]; then
598                     domainname="`egrep '^[      ]*search' /etc/resolv.conf | sed -e 'q' |\
599                                  sed -e 's/.*search//' \
600                                      -e 's/^[   ]*//' -e 's/^ *//' -e 's/^      *//' \
601                                      -e 's/ .*//' -e 's/        .*//' \
602                                      -e 's/^\.//' -e 's/^/./' |\
603                                  awk '{ printf("%s", $1); }'`"
604                 fi
605             fi
606         fi
607     fi
608     
609     #   determine current time
610     time_day=''
611     time_month=''
612     time_year=''
613     time_monthname=''
614     if [ ".$opt_e" = .yes -a ".`echo $text | egrep '%[DMYm]'`" != . ]; then
615         time_day=`date '+%d'`
616         time_month=`date '+%m'`
617         time_year=`date '+%Y' 2>/dev/null`
618         if [ ".$time_year" = . ]; then
619             time_year=`date '+%y'`
620             case $time_year in
621                 [5-9][0-9]) time_year="19$time_year" ;;
622                 [0-4][0-9]) time_year="20$time_year" ;;
623             esac
624         fi
625         case $time_month in
626             1|01) time_monthname='Jan' ;;
627             2|02) time_monthname='Feb' ;;
628             3|03) time_monthname='Mar' ;;
629             4|04) time_monthname='Apr' ;;
630             5|05) time_monthname='May' ;;
631             6|06) time_monthname='Jun' ;;
632             7|07) time_monthname='Jul' ;;
633             8|08) time_monthname='Aug' ;;
634             9|09) time_monthname='Sep' ;;
635               10) time_monthname='Oct' ;;
636               11) time_monthname='Nov' ;;
637               12) time_monthname='Dec' ;;
638         esac
639     fi
640     
641     #   expand special ``%x'' constructs
642     if [ ".$opt_e" = .yes ]; then
643         text=`echo $seo "$text" |\
644               sed -e "s/%B/${term_bold}/g" \
645                   -e "s/%b/${term_norm}/g" \
646                   -e "s/%u/${username}/g" \
647                   -e "s/%U/${userid}/g" \
648                   -e "s/%g/${groupname}/g" \
649                   -e "s/%G/${groupid}/g" \
650                   -e "s/%h/${hostname}/g" \
651                   -e "s/%d/${domainname}/g" \
652                   -e "s/%D/${time_day}/g" \
653                   -e "s/%M/${time_month}/g" \
654                   -e "s/%Y/${time_year}/g" \
655                   -e "s/%m/${time_monthname}/g" 2>/dev/null`
656     fi
657     
658     #   create output
659     if [ .$opt_n = .no ]; then
660         echo $seo "$text"
661     else
662         #   the harder part: echo -n is best, because
663         #   awk may complain about some \xx sequences.
664         if [ ".$minusn" != . ]; then
665             echo $seo $minusn "$text"
666         else
667             echo dummy | awk '{ printf("%s", TEXT); }' TEXT="$text"
668         fi
669     fi
670     ;;
671
672 move )
673     ##
674     ##  move -- Move files with simultaneous substitution
675     ##  Copyright (c) 1999-2002 Ralf S. Engelschall <rse@engelschall.com>
676     ##  Originally written for shtool
677     ##
678     
679     src="$1"
680     dst="$2"
681     
682     #   consistency checks
683     if [ ".$src" = . -o ".$dst" = . ]; then
684         echo "$msgprefix:Error: Invalid arguments" 1>&2
685         exit 1
686     fi
687     if [ ".$src" = ".$dst" ]; then
688         echo "$msgprefix:Error: Source and destination files are the same" 1>&2
689         exit 1
690     fi
691     expsrc="$src"
692     if [ ".$opt_e" = .yes ]; then
693         expsrc="`echo $expsrc`"
694     fi
695     if [ ".$opt_e" = .yes ]; then
696         if [ ".`echo "$src" | sed -e 's;^.*\\*.*$;;'`" = ".$src" ]; then
697             echo "$msgprefix:Error: Source doesn't contain wildcard ('*'): $dst" 1>&2
698             exit 1
699         fi
700         if [ ".`echo "$dst" | sed -e 's;^.*%[1-9].*$;;'`" = ".$dst" ]; then
701             echo "$msgprefix:Error: Destination doesn't contain substitution ('%N'): $dst" 1>&2
702             exit 1
703         fi
704         if [ ".$expsrc" = ".$src" ]; then
705             echo "$msgprefix:Error: Sources not found or no asterisk : $src" 1>&2
706             exit 1
707         fi
708     else
709         if [ ! -r "$src" ]; then
710             echo "$msgprefix:Error: Source not found: $src" 1>&2
711             exit 1
712         fi
713     fi
714     
715     #   determine substitution patterns
716     if [ ".$opt_e" = .yes ]; then
717         srcpat=`echo "$src" | sed -e 's/\\./\\\\./g' -e 's/;/\\;/g' -e 's;\\*;\\\\(.*\\\\);g'`
718         dstpat=`echo "$dst" | sed -e 's;%\([1-9]\);\\\\\1;g'`
719     fi
720     
721     #   iterate over source(s)
722     for onesrc in $expsrc; do
723         if [ .$opt_e = .yes ]; then
724             onedst=`echo $onesrc | sed -e "s;$srcpat;$dstpat;"`
725         else
726             onedst="$dst"
727         fi
728         errorstatus=0
729         if [ ".$opt_v" = .yes ]; then
730             echo "$onesrc -> $onedst"
731         fi
732         if [ ".$opt_p" = .yes ]; then
733             if [ -r $onedst ]; then
734                 if cmp -s $onesrc $onedst; then
735                     if [ ".$opt_t" = .yes ]; then
736                         echo "rm -f $onesrc" 1>&2
737                     fi
738                     rm -f $onesrc || errorstatus=$?
739                 else
740                     if [ ".$opt_t" = .yes ]; then
741                         echo "mv -f $onesrc $onedst" 1>&2
742                     fi
743                     mv -f $onesrc $onedst || errorstatus=$?
744                 fi
745             else
746                 if [ ".$opt_t" = .yes ]; then
747                     echo "mv -f $onesrc $onedst" 1>&2
748                 fi
749                 mv -f $onesrc $onedst || errorstatus=$?
750             fi
751         else
752             if [ ".$opt_t" = .yes ]; then
753                 echo "mv -f $onesrc $onedst" 1>&2
754             fi
755             mv -f $onesrc $onedst || errorstatus=$?
756         fi
757         if [ $errorstatus -ne 0 ]; then
758             break;
759         fi
760     done
761     exit $errorstatus
762     ;;
763
764 install )
765     ##
766     ##  install -- Install a program, script or datafile
767     ##  Copyright (c) 1997-2002 Ralf S. Engelschall <rse@engelschall.com>
768     ##  Originally written for shtool
769     ##
770     
771     #   determine source(s) and destination
772     argc=$#
773     srcs=""
774     while [ $# -gt 1 ]; do
775         srcs="$srcs $1"
776         shift
777     done
778     dstpath="$1"
779     
780     #   type check for destination
781     dstisdir=0
782     if [ -d $dstpath ]; then
783         dstpath=`echo "$dstpath" | sed -e 's:/$::'`
784         dstisdir=1
785     fi
786     
787     #   consistency check for destination
788     if [ $argc -gt 2 -a $dstisdir = 0 ]; then
789         echo "$msgprefix:Error: multiple sources require destination to be directory" 1>&2
790         exit 1
791     fi
792     
793     #   iterate over all source(s)
794     for src in $srcs; do
795         dst=$dstpath
796     
797         #   if destination is a directory, append the input filename
798         if [ $dstisdir = 1 ]; then
799             dstfile=`echo "$src" | sed -e 's;.*/\([^/]*\)$;\1;'`
800             dst="$dst/$dstfile"
801         fi
802     
803         #   check for correct arguments
804         if [ ".$src" = ".$dst" ]; then
805             echo "$msgprefix:Warning: source and destination are the same - skipped" 1>&2
806             continue
807         fi
808         if [ -d "$src" ]; then
809             echo "$msgprefix:Warning: source \`$src' is a directory - skipped" 1>&2
810             continue
811         fi
812     
813         #   make a temp file name in the destination directory
814         dsttmp=`echo $dst |\
815                 sed -e 's;[^/]*$;;' -e 's;\(.\)/$;\1;' -e 's;^$;.;' \
816                     -e "s;\$;/#INST@$$#;"`
817     
818         #   verbosity
819         if [ ".$opt_v" = .yes ]; then
820             echo "$src -> $dst" 1>&2
821         fi
822     
823         #   copy or move the file name to the temp name
824         #   (because we might be not allowed to change the source)
825         if [ ".$opt_C" = .yes ]; then
826             opt_c=yes
827         fi
828         if [ ".$opt_c" = .yes ]; then
829             if [ ".$opt_t" = .yes ]; then
830                 echo "cp $src $dsttmp" 1>&2
831             fi
832             cp $src $dsttmp || exit $?
833         else
834             if [ ".$opt_t" = .yes ]; then
835                 echo "mv $src $dsttmp" 1>&2
836             fi
837             mv $src $dsttmp || exit $?
838         fi
839     
840         #   adjust the target file
841         if [ ".$opt_e" != . ]; then
842             sed='sed'
843             OIFS="$IFS"; IFS="$ASC_NL"; set -- $opt_e; IFS="$OIFS"
844             for e
845             do
846                 sed="$sed -e '$e'"
847             done
848             cp $dsttmp $dsttmp.old
849             eval "$sed <$dsttmp.old >$dsttmp" || exit $?
850             rm -f $dsttmp.old
851         fi
852         if [ ".$opt_s" = .yes ]; then
853             if [ ".$opt_t" = .yes ]; then
854                 echo "strip $dsttmp" 1>&2
855             fi
856             strip $dsttmp || exit $?
857         fi
858         if [ ".$opt_o" != . ]; then
859             if [ ".$opt_t" = .yes ]; then
860                 echo "chown $opt_o $dsttmp" 1>&2
861             fi
862             chown $opt_o $dsttmp || exit $?
863         fi
864         if [ ".$opt_g" != . ]; then
865             if [ ".$opt_t" = .yes ]; then
866                 echo "chgrp $opt_g $dsttmp" 1>&2
867             fi
868             chgrp $opt_g $dsttmp || exit $?
869         fi
870         if [ ".$opt_m" != ".-" ]; then
871             if [ ".$opt_t" = .yes ]; then
872                 echo "chmod $opt_m $dsttmp" 1>&2
873             fi
874             chmod $opt_m $dsttmp || exit $?
875         fi
876     
877         #   determine whether to do a quick install
878         #   (has to be done _after_ the strip was already done)
879         quick=no
880         if [ ".$opt_C" = .yes ]; then
881             if [ -r $dst ]; then
882                 if cmp -s $src $dst; then
883                     quick=yes
884                 fi
885             fi
886         fi
887     
888         #   finally, install the file to the real destination
889         if [ $quick = yes ]; then
890             if [ ".$opt_t" = .yes ]; then
891                 echo "rm -f $dsttmp" 1>&2
892             fi
893             rm -f $dsttmp
894         else
895             if [ ".$opt_t" = .yes ]; then
896                 echo "rm -f $dst && mv $dsttmp $dst" 1>&2
897             fi
898             rm -f $dst && mv $dsttmp $dst
899         fi
900     done
901     ;;
902
903 mkdir )
904     ##
905     ##  mkdir -- Make one or more directories
906     ##  Copyright (c) 1996-2002 Ralf S. Engelschall <rse@engelschall.com>
907     ##  Originally written for public domain by Noah Friedman <friedman@prep.ai.mit.edu>
908     ##  Cleaned up and enhanced for shtool
909     ##
910     
911     errstatus=0
912     for p in ${1+"$@"}; do
913         #   if the directory already exists...
914         if [ -d "$p" ]; then
915             if [ ".$opt_f" = .no -a ".$opt_p" = .no ]; then
916                 echo "$msgprefix:Error: directory already exists: $p" 1>&2
917                 errstatus=1
918                 break
919             else
920                 continue
921             fi
922         fi
923         #   if the directory has to be created...
924         if [ ".$opt_p" = .no ]; then
925             if [ ".$opt_t" = .yes ]; then
926                 echo "mkdir $p" 1>&2
927             fi
928             mkdir $p || errstatus=$?
929             if [ ".$opt_m" != . ]; then
930                 if [ ".$opt_t" = .yes ]; then
931                     echo "chmod $opt_m $p" 1>&2
932                 fi
933                 chmod $opt_m $p || errstatus=$?
934             fi
935         else
936             #   the smart situation
937             set fnord `echo ":$p" |\
938                        sed -e 's/^:\//%/' \
939                            -e 's/^://' \
940                            -e 's/\// /g' \
941                            -e 's/^%/\//'`
942             shift
943             pathcomp=''
944             for d in ${1+"$@"}; do
945                 pathcomp="$pathcomp$d"
946                 case "$pathcomp" in
947                     -* ) pathcomp="./$pathcomp" ;;
948                 esac
949                 if [ ! -d "$pathcomp" ]; then
950                     if [ ".$opt_t" = .yes ]; then
951                         echo "mkdir $pathcomp" 1>&2
952                     fi
953                     mkdir $pathcomp || errstatus=$?
954                     if [ ".$opt_m" != . ]; then
955                         if [ ".$opt_t" = .yes ]; then
956                             echo "chmod $opt_m $pathcomp" 1>&2
957                         fi
958                         chmod $opt_m $pathcomp || errstatus=$?
959                     fi
960                 fi
961                 pathcomp="$pathcomp/"
962             done
963         fi
964     done
965     exit $errstatus
966     ;;
967
968 mkln )
969     ##
970     ##  mkln -- Make link with calculation of relative paths
971     ##  Copyright (c) 1999-2002 Ralf S. Engelschall <rse@engelschall.com>
972     ##  Originally written for shtool
973     ##
974     
975     args=$?
976     srcs=""
977     while [ $# -gt 1 ]; do
978         srcs="$srcs $1"
979         shift
980     done
981     dst="$1"
982     if [ ! -d $dst ]; then
983         if [ $args -gt 2 ]; then
984             echo "$msgprefix:Error: multiple sources not allowed when target isn't a directory" 1>&2
985             exit 1
986         fi
987     fi
988     
989     #   determine link options
990     lnopt=""
991     if [ ".$opt_f" = .yes ]; then
992         lnopt="$lnopt -f"
993     fi
994     if [ ".$opt_s" = .yes ]; then
995         lnopt="$lnopt -s"
996     fi
997     
998     #   iterate over sources
999     for src in $srcs; do
1000         #   determine if one of the paths is an absolute path,
1001         #   because then we _have_ to use an absolute symlink
1002         oneisabs=0
1003         srcisabs=0
1004         dstisabs=0
1005         case $src in
1006             /* ) oneisabs=1; srcisabs=1 ;;
1007         esac
1008         case $dst in
1009             /* ) oneisabs=1; dstisabs=1 ;;
1010         esac
1011     
1012         #   split source and destination into dir and base name
1013         if [ -d $src ]; then
1014             srcdir=`echo $src | sed -e 's;/*$;;'`
1015             srcbase=""
1016         else
1017             srcdir=`echo  $src | sed -e 's;^[^/]*$;;' -e 's;^\(.*/\)[^/]*$;\1;' -e 's;\(.\)/$;\1;'`
1018             srcbase=`echo $src | sed -e 's;.*/\([^/]*\)$;\1;'`
1019         fi
1020         if [ -d $dst ]; then
1021             dstdir=`echo $dst | sed -e 's;/*$;;'`
1022             dstbase=""
1023         else
1024             dstdir=`echo  $dst | sed -e 's;^[^/]*$;;' -e 's;^\(.*/\)[^/]*$;\1;' -e 's;\(.\)/$;\1;'`
1025             dstbase=`echo $dst | sed -e 's;.*/\([^/]*\)$;\1;'`
1026         fi
1027     
1028         #   consistency check
1029         if [ ".$dstdir" != . ]; then
1030             if [ ! -d $dstdir ]; then
1031                 echo "$msgprefix:Error: destination directory not found: $dstdir" 1>&2
1032                 exit 1
1033             fi
1034         fi
1035     
1036         #   make sure the source is reachable from the destination
1037         if [ $dstisabs = 1 ]; then
1038             if [ $srcisabs = 0 ]; then
1039                 if [ -d $srcdir ]; then
1040                     srcdir="`cd $srcdir; pwd | sed -e 's;/*$;;'`"
1041                     srcisabs=1
1042                     oneisabs=1
1043                 fi
1044             fi
1045         fi
1046     
1047         #   split away a common prefix
1048         prefix=""
1049         if [ ".$srcdir" = ".$dstdir" -a ".$srcdir" != . ]; then
1050             prefix="$srcdir/"
1051             srcdir=""
1052             dstdir=""
1053         else
1054             while [ ".$srcdir" != . -a ".$dstdir" != . ]; do
1055                 presrc=`echo $srcdir | sed -e 's;^\([^/]*\)/.*;\1;'`
1056                 predst=`echo $dstdir | sed -e 's;^\([^/]*\)/.*;\1;'`
1057                 if [ ".$presrc" != ".$predst" ]; then
1058                     break
1059                 fi
1060                 prefix="$prefix$presrc/"
1061                 srcdir=`echo $srcdir | sed -e 's;^[^/]*/*;;'`
1062                 dstdir=`echo $dstdir | sed -e 's;^[^/]*/*;;'`
1063             done
1064         fi
1065     
1066         #   destination prefix is just the common prefix
1067         dstpre="$prefix"
1068     
1069         #   determine source prefix which is the reverse directory
1070         #   step-up corresponding to the destination directory
1071         srcpre=""
1072         if [ $oneisabs = 0 ] || [ ".$prefix" != . -a ".$prefix" != ./ ]; then
1073             pl="$dstdir/"
1074             OIFS="$IFS"; IFS='/'
1075             for pe in $pl; do
1076                 [ ".$pe" = . ] && continue
1077                 srcpre="../$srcpre"
1078             done
1079             IFS="$OIFS"
1080         else
1081             if [ $srcisabs = 1 ]; then
1082                 srcpre="$prefix"
1083             fi
1084         fi
1085     
1086         #   determine destination symlink name
1087         if [ ".$dstbase" = . ]; then
1088             if [ ".$srcbase" != . ]; then
1089                 dstbase="$srcbase"
1090             else
1091                 dstbase=`echo "$prefix$srcdir" | sed -e 's;/*$;;' -e 's;.*/\([^/]*\)$;\1;'`
1092             fi
1093         fi
1094     
1095         #   now finalize source and destination directory paths
1096         srcdir=`echo $srcdir | sed -e 's;\([^/]\)$;\1/;'`
1097         dstdir=`echo $dstdir | sed -e 's;\([^/]\)$;\1/;'`
1098     
1099         #   run the final link command
1100         if [ ".$opt_t" = .yes ]; then
1101             echo "ln$lnopt $srcpre$srcdir$srcbase $dstpre$dstdir$dstbase"
1102         fi
1103         eval ln$lnopt $srcpre$srcdir$srcbase $dstpre$dstdir$dstbase
1104     done
1105     ;;
1106
1107 subst )
1108     ##
1109     ##  subst -- Apply sed(1) substitution operations
1110     ##  Copyright (c) 2001-2002 Ralf S. Engelschall <rse@engelschall.com>
1111     ##  Originally written for OpenPKG's rpmtool
1112     ##
1113     
1114     #   remember optional list of file(s)
1115     files="$*"
1116     
1117     #   parameter consistency check
1118     if [ $# -eq 0 -a ".$opt_b" != . ]; then
1119         echo "$msgprefix:Error: option -b cannot be applied to stdin" 1>&2
1120         exit 1
1121     fi
1122     if [ $# -eq 0 -a ".$opt_s" = .yes ]; then
1123         echo "$msgprefix:Error: option -s cannot be applied to stdin" 1>&2
1124         exit 1
1125     fi
1126     
1127     #   build underlying sed(1) command
1128     sedcmd='sed'
1129     if [ ".$opt_e" != . ]; then
1130         OIFS="$IFS"; IFS="$ASC_NL"; set -- $opt_e; IFS="$OIFS"
1131         for e
1132         do
1133             sedcmd="$sedcmd -e '$e'" 
1134         done
1135     elif [ ".$opt_f" != . ]; then
1136         if [ ! -f $opt_f ]; then
1137             echo "$msgprefix:Error: command file \`$opt_f' not found or not a regular file" 1>&2
1138             exit 1
1139         fi
1140         sedcmd="$sedcmd -f '$opt_f'"
1141     else
1142         echo "$msgprefix:Error: either -e option(s) or -f option required" 1>&2
1143         exit 1
1144     fi
1145     
1146     #   determine extension for original file
1147     orig=".orig"
1148     if [ ".$opt_b" != . ]; then
1149         orig="$opt_b"
1150     fi
1151     
1152     #   apply sed(1) operation(s)
1153     if [ ".$files" != . ]; then
1154         #   apply operation(s) to files
1155         for file in $files; do
1156             test ".$file" = . && continue
1157             if [ ! -f $file ]; then
1158                 echo "$msgprefix:Warning: file \`$file' not found or not a regular file" 1>&2
1159                 continue
1160             fi
1161     
1162             #   handle interactive mode
1163             if [ ".$opt_i" = .yes ]; then
1164                 eval "$sedcmd <$file >$file.new"
1165                 skip=no
1166                 if cmp $file $file.new >/dev/null 2>&1; then
1167                     rm -f $file.new
1168                     skip=yes
1169                 else
1170                     (diff -U1 $file $file.new >$tmpfile) 2>/dev/null
1171                     if [ ".`cat $tmpfile`" = . ]; then
1172                         (diff -C1 $file $file.new >$tmpfile) 2>/dev/null
1173                         if [ ".`cat $tmpfile`" = . ]; then
1174                             echo "$msgprefix:Warning: unable to show difference for file \`$file'" 1>&2
1175                             cp /dev/null $tmpfile
1176                         fi
1177                     fi
1178                     rm -f $file.new
1179                     cat $tmpfile
1180                     echo dummy | awk '{ printf("%s", TEXT); }' TEXT=">>> Apply [Y/n]: "
1181                     read input
1182                     if [ ".$input" != .Y ] &&\
1183                        [ ".$input" != .y ] &&\
1184                        [ ".$input" != . ]; then
1185                        skip=yes
1186                     fi
1187                 fi
1188                 if [ ".$skip" = .yes ]; then
1189                     if [ ".$opt_v" = .yes ]; then
1190                         echo "file \`$file' -- skipped" 1>&2
1191                     fi
1192                     continue
1193                 fi
1194             fi
1195     
1196             #   apply sed(1) operation(s)
1197             if [ ".$opt_v" = .yes ]; then
1198                 echo "patching \`$file'" 1>&2
1199             fi
1200             if [ ".$opt_t" = .yes ]; then
1201                 echo "\$ cp -p $file $file$orig"
1202                 echo "\$ $sedcmd <$file$orig >$file"
1203             fi
1204             if [ ".$opt_n" = .no ]; then
1205                 cp -p $file $file$orig
1206                 eval "$sedcmd <$file$orig >$file"
1207             fi
1208     
1209             #   optionally fix timestamp
1210             if [ ".$opt_s" = .yes ]; then
1211                 if [ ".$opt_t" = .yes ]; then
1212                     echo "\$ touch -r $file$orig $file"
1213                 fi
1214                 if [ ".$opt_n" = .no ]; then
1215                     touch -r $file$orig $file
1216                 fi
1217             fi
1218     
1219             #   optionally remove preserved original file
1220             if [ ".$opt_b" = . ]; then
1221                 if [ ".$opt_t" = .yes ]; then
1222                     echo "\$ rm -f $file$orig"
1223                 fi
1224                 if [ ".$opt_n" = .no ]; then
1225                     rm -f $file$orig
1226                 fi
1227             fi
1228         done
1229     else
1230         #   apply operation(s) to stdin/stdout
1231         if [ ".$opt_v" = .yes ]; then
1232             echo "patching <stdin>" 1>&2
1233         fi
1234         if [ ".$opt_t" = .yes ]; then
1235             echo "\$ $sedcmd"
1236         fi
1237         if [ ".$opt_n" = .no ]; then
1238             eval "$sedcmd"
1239         fi
1240     fi
1241     ;;
1242
1243 esac
1244
1245 exit 0
1246
1247 ##EOF##