1#!/bin/sh 2## 3## GNU shtool -- The GNU Portable Shell Tool 4## Copyright (c) 1994-2005 Ralf S. Engelschall <rse@engelschall.com> 5## 6## See http://www.gnu.org/software/shtool/ for more information. 7## See ftp://ftp.gnu.org/gnu/shtool/ for latest version. 8## 9## Version: 2.0.3 (02-Oct-2005) 10## Contents: 6/19 available modules 11## 12 13## 14## This program is free software; you can redistribute it and/or modify 15## it under the terms of the GNU General Public License as published by 16## the Free Software Foundation; either version 2 of the License, or 17## (at your option) any later version. 18## 19## This program is distributed in the hope that it will be useful, 20## but WITHOUT ANY WARRANTY; without even the implied warranty of 21## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 22## General Public License for more details. 23## 24## You should have received a copy of the GNU General Public License 25## along with this program; if not, write to the Free Software 26## Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 27## USA, or contact Ralf S. Engelschall <rse@engelschall.com>. 28## 29## NOTICE: Given that you include this file verbatim into your own 30## source tree, you are justified in saying that it remains separate 31## from your package, and that this way you are simply just using GNU 32## shtool. So, in this situation, there is no requirement that your 33## package itself is licensed under the GNU General Public License in 34## order to take advantage of GNU shtool. 35## 36 37## 38## Usage: shtool [<options>] [<cmd-name> [<cmd-options>] [<cmd-args>]] 39## 40## Available commands: 41## echo Print string with optional construct expansion 42## install Install a program, script or datafile 43## mkdir Make one or more directories 44## fixperm Fix file permissions inside a source tree 45## tarball Roll distribution tarballs 46## version Maintain a version information file 47## 48## Not available commands (because module was not built-in): 49## mdate Pretty-print modification time of a file or dir 50## table Pretty-print a field-separated list as a table 51## prop Display progress with a running propeller 52## move Move files with simultaneous substitution 53## mkln Make link with calculation of relative paths 54## mkshadow Make a shadow tree through symbolic links 55## rotate Logfile rotation 56## subst Apply sed(1) substitution operations 57## platform Platform Identification Utility 58## arx Extended archive command 59## slo Separate linker options by library class 60## scpp Sharing C Pre-Processor 61## path Deal with program paths 62## 63 64if [ $# -eq 0 ]; then 65 echo "$0:Error: invalid command line" 1>&2 66 echo "$0:Hint: run \`$0 -h' for usage" 1>&2 67 exit 1 68fi 69if [ ".$1" = ".-h" ] || [ ".$1" = ".--help" ]; then 70 echo "This is GNU shtool, version 2.0.3 (02-Oct-2005)" 71 echo "Copyright (c) 1994-2005 Ralf S. Engelschall <rse@engelschall.com>" 72 echo "Report bugs to <bug-shtool@gnu.org>" 73 echo '' 74 echo "Usage: shtool [<options>] [<cmd-name> [<cmd-options>] [<cmd-args>]]" 75 echo '' 76 echo 'Available global <options>:' 77 echo ' -v, --version display shtool version information' 78 echo ' -h, --help display shtool usage help page (this one)' 79 echo ' -d, --debug display shell trace information' 80 echo ' -r, --recreate recreate this shtool script via shtoolize' 81 echo '' 82 echo 'Available <cmd-name> [<cmd-options>] [<cmd-args>]:' 83 echo ' echo [-n|--newline] [-e|--expand] [<string> ...]' 84 echo ' install [-v|--verbose] [-t|--trace] [-d|--mkdir] [-c|--copy]' 85 echo ' [-C|--compare-copy] [-s|--strip] [-m|--mode <mode>]' 86 echo ' [-o|--owner <owner>] [-g|--group <group>] [-e|--exec' 87 echo ' <sed-cmd>] <file> [<file> ...] <path>' 88 echo ' mkdir [-t|--trace] [-f|--force] [-p|--parents] [-m|--mode' 89 echo ' <mode>] [-o|--owner <owner>] [-g|--group <group>] <dir>' 90 echo ' [<dir> ...]' 91 echo ' fixperm [-v|--verbose] [-t|--trace] <path> [<path> ...]' 92 echo ' tarball [-t|--trace] [-v|--verbose] [-o|--output <tarball>]' 93 echo ' [-c|--compress <prog>] [-d|--directory <dir>] [-u|--user' 94 echo ' <user>] [-g|--group <group>] [-e|--exclude <pattern>]' 95 echo ' <path> [<path> ...]' 96 echo ' version [-l|--language <lang>] [-n|--name <name>] [-p|--prefix' 97 echo ' <prefix>] [-s|--set <version>] [-e|--edit] [-i|--increase' 98 echo ' <knob>] [-d|--display <type>] <file>' 99 echo '' 100 echo 'Not available <cmd-name> (because module was not built-in):' 101 echo ' mdate [-n|--newline] [-z|--zero] [-s|--shorten] [-d|--digits]' 102 echo ' [-f|--field-sep <str>] [-o|--order <spec>] <path>' 103 echo ' table [-F|--field-sep <sep>] [-w|--width <width>] [-c|--columns' 104 echo ' <cols>] [-s|--strip <strip>] <str><sep><str>...' 105 echo ' prop [-p|--prefix <str>]' 106 echo ' move [-v|--verbose] [-t|--trace] [-e|--expand] [-p|--preserve]' 107 echo ' <src-file> <dst-file>' 108 echo ' mkln [-t|--trace] [-f|--force] [-s|--symbolic] <src-path>' 109 echo ' [<src-path> ...] <dst-path>' 110 echo ' mkshadow [-v|--verbose] [-t|--trace] [-a|--all] <src-dir> <dst-dir>' 111 echo ' rotate [-v|--verbose] [-t|--trace] [-f|--force] [-n|--num-files' 112 echo ' <count>] [-s|--size <size>] [-c|--copy] [-r|--remove]' 113 echo ' [-a|--archive-dir <dir>] [-z|--compress [<tool>:]<level>]' 114 echo ' [-b|--background] [-d|--delay] [-p|--pad <len>] [-m|--mode' 115 echo ' <mode>] [-o|--owner <owner>] [-g|--group <group>] [-M|--migrate' 116 echo ' <cmd>] [-P|--prolog <cmd>] [-E|--epilog <cmd>] <file> [...]' 117 echo ' subst [-v|--verbose] [-t|--trace] [-n|--nop] [-w|--warning]' 118 echo ' [-q|--quiet] [-s|--stealth] [-i|--interactive] [-b|--backup' 119 echo ' <ext>] [-e|--exec <cmd>] [-f|--file <cmd-file>] [<file>]' 120 echo ' [...]' 121 echo ' platform [-F|--format <format>] [-S|--sep <string>] [-C|--conc' 122 echo ' <string>] [-L|--lower] [-U|--upper] [-v|--verbose]' 123 echo ' [-c|--concise] [-n|--no-newline] [-t|--type <type>]' 124 echo ' [-V|--version] [-h|--help]' 125 echo ' arx [-t|--trace] [-C|--command <cmd>] <op> <archive> [<file>' 126 echo ' ...]' 127 echo ' slo [-p|--prefix <str>] -- -L<dir> -l<lib> [-L<dir> -l<lib>' 128 echo ' ...]' 129 echo ' scpp [-v|--verbose] [-p|--preserve] [-f|--filter <filter>]' 130 echo ' [-o|--output <ofile>] [-t|--template <tfile>] [-M|--mark' 131 echo ' <mark>] [-D|--define <dname>] [-C|--class <cname>]' 132 echo ' <file> [<file> ...]' 133 echo ' path [-s|--suppress] [-r|--reverse] [-d|--dirname] [-b|--basename]' 134 echo ' [-m|--magic] [-p|--path <path>] <str> [<str> ...]' 135 echo '' 136 exit 0 137fi 138if [ ".$1" = ".-v" ] || [ ".$1" = ".--version" ]; then 139 echo "GNU shtool 2.0.3 (02-Oct-2005)" 140 exit 0 141fi 142if [ ".$1" = ".-r" ] || [ ".$1" = ".--recreate" ]; then 143 shtoolize -oshtool echo install mkdir fixperm tarball version 144 exit 0 145fi 146if [ ".$1" = ".-d" ] || [ ".$1" = ".--debug" ]; then 147 shift 148 set -x 149fi 150name=`echo "$0" | sed -e 's;.*/\([^/]*\)$;\1;' -e 's;-sh$;;' -e 's;\.sh$;;'` 151case "$name" in 152 echo|install|mkdir|fixperm|tarball|version ) 153 # implicit tool command selection 154 tool="$name" 155 ;; 156 * ) 157 # explicit tool command selection 158 tool="$1" 159 shift 160 ;; 161esac 162arg_spec="" 163opt_spec="" 164gen_tmpfile=no 165 166## 167## DISPATCH INTO SCRIPT PROLOG 168## 169 170case $tool in 171 echo ) 172 str_tool="echo" 173 str_usage="[-n|--newline] [-e|--expand] [<string> ...]" 174 arg_spec="0+" 175 opt_spec="n.e." 176 opt_alias="n:newline,e:expand" 177 opt_n=no 178 opt_e=no 179 ;; 180 install ) 181 str_tool="install" 182 str_usage="[-v|--verbose] [-t|--trace] [-d|--mkdir] [-c|--copy] [-C|--compare-copy] [-s|--strip] [-m|--mode <mode>] [-o|--owner <owner>] [-g|--group <group>] [-e|--exec <sed-cmd>] <file> [<file> ...] <path>" 183 arg_spec="1+" 184 opt_spec="v.t.d.c.C.s.m:o:g:e+" 185 opt_alias="v:verbose,t:trace,d:mkdir,c:copy,C:compare-copy,s:strip,m:mode,o:owner,g:group,e:exec" 186 opt_v=no 187 opt_t=no 188 opt_d=no 189 opt_c=no 190 opt_C=no 191 opt_s=no 192 opt_m="0755" 193 opt_o="" 194 opt_g="" 195 opt_e="" 196 ;; 197 mkdir ) 198 str_tool="mkdir" 199 str_usage="[-t|--trace] [-f|--force] [-p|--parents] [-m|--mode <mode>] [-o|--owner <owner>] [-g|--group <group>] <dir> [<dir> ...]" 200 arg_spec="1+" 201 opt_spec="t.f.p.m:o:g:" 202 opt_alias="t:trace,f:force,p:parents,m:mode,o:owner,g:group" 203 opt_t=no 204 opt_f=no 205 opt_p=no 206 opt_m="" 207 opt_o="" 208 opt_g="" 209 ;; 210 fixperm ) 211 str_tool="fixperm" 212 str_usage="[-v|--verbose] [-t|--trace] <path> [<path> ...]" 213 arg_spec="1+" 214 opt_spec="v.t." 215 opt_alias="v:verbose,t:trace" 216 opt_v=no 217 opt_t=no 218 ;; 219 tarball ) 220 str_tool="tarball" 221 str_usage="[-t|--trace] [-v|--verbose] [-o|--output <tarball>] [-c|--compress <prog>] [-d|--directory <dir>] [-u|--user <user>] [-g|--group <group>] [-e|--exclude <pattern>] <path> [<path> ...]" 222 gen_tmpfile=yes 223 arg_spec="1+" 224 opt_spec="t.v.o:c:d:u:g:e:" 225 opt_alias="t:trace,v:verbose,o:output,c:compress,d:directory,u:user,g:group,e:exclude" 226 opt_t=no 227 opt_v=no 228 opt_o="" 229 opt_c="" 230 opt_d="" 231 opt_u="" 232 opt_g="" 233 opt_e="CVS,\\.cvsignore,\\.[oa]\$" 234 ;; 235 version ) 236 str_tool="version" 237 str_usage="[-l|--language <lang>] [-n|--name <name>] [-p|--prefix <prefix>] [-s|--set <version>] [-e|--edit] [-i|--increase <knob>] [-d|--display <type>] <file>" 238 arg_spec="1=" 239 opt_spec="l:n:p:s:i:e.d:" 240 opt_alias="l:language,n:name,p:prefix,s:set,e:edit,i:increase,d:display" 241 opt_l="txt" 242 opt_n="unknown" 243 opt_p="" 244 opt_s="" 245 opt_e="no" 246 opt_i="" 247 opt_d="short" 248 ;; 249 -* ) 250 echo "$0:Error: unknown option \`$tool'" 2>&1 251 echo "$0:Hint: run \`$0 -h' for usage" 2>&1 252 exit 1 253 ;; 254 * ) 255 echo "$0:Error: unknown command \`$tool'" 2>&1 256 echo "$0:Hint: run \`$0 -h' for usage" 2>&1 257 exit 1 258 ;; 259esac 260 261## 262## COMMON UTILITY CODE 263## 264 265# commonly used ASCII values 266ASC_TAB=" " 267ASC_NL=" 268" 269 270# determine name of tool 271if [ ".$tool" != . ]; then 272 # used inside shtool script 273 toolcmd="$0 $tool" 274 toolcmdhelp="shtool $tool" 275 msgprefix="shtool:$tool" 276else 277 # used as standalone script 278 toolcmd="$0" 279 toolcmdhelp="sh $0" 280 msgprefix="$str_tool" 281fi 282 283# parse argument specification string 284eval `echo $arg_spec |\ 285 sed -e 's/^\([0-9]*\)\([+=]\)/arg_NUMS=\1; arg_MODE=\2/'` 286 287# parse option specification string 288eval `echo h.$opt_spec |\ 289 sed -e 's/\([a-zA-Z0-9]\)\([.:+]\)/opt_MODE_\1=\2;/g'` 290 291# parse option alias string 292eval `echo h:help,$opt_alias |\ 293 sed -e 's/-/_/g' -e 's/\([a-zA-Z0-9]\):\([^,]*\),*/opt_ALIAS_\2=\1;/g'` 294 295# interate over argument line 296opt_PREV='' 297while [ $# -gt 0 ]; do 298 # special option stops processing 299 if [ ".$1" = ".--" ]; then 300 shift 301 break 302 fi 303 304 # determine option and argument 305 opt_ARG_OK=no 306 if [ ".$opt_PREV" != . ]; then 307 # merge previous seen option with argument 308 opt_OPT="$opt_PREV" 309 opt_ARG="$1" 310 opt_ARG_OK=yes 311 opt_PREV='' 312 else 313 # split argument into option and argument 314 case "$1" in 315 --[a-zA-Z0-9]*=*) 316 eval `echo "x$1" |\ 317 sed -e 's/^x--\([a-zA-Z0-9-]*\)=\(.*\)$/opt_OPT="\1";opt_ARG="\2"/'` 318 opt_STR=`echo $opt_OPT | sed -e 's/-/_/g'` 319 eval "opt_OPT=\${opt_ALIAS_${opt_STR}-${opt_OPT}}" 320 ;; 321 --[a-zA-Z0-9]*) 322 opt_OPT=`echo "x$1" | cut -c4-` 323 opt_STR=`echo $opt_OPT | sed -e 's/-/_/g'` 324 eval "opt_OPT=\${opt_ALIAS_${opt_STR}-${opt_OPT}}" 325 opt_ARG='' 326 ;; 327 -[a-zA-Z0-9]*) 328 eval `echo "x$1" |\ 329 sed -e 's/^x-\([a-zA-Z0-9]\)/opt_OPT="\1";/' \ 330 -e 's/";\(.*\)$/"; opt_ARG="\1"/'` 331 ;; 332 -[a-zA-Z0-9]) 333 opt_OPT=`echo "x$1" | cut -c3-` 334 opt_ARG='' 335 ;; 336 *) 337 break 338 ;; 339 esac 340 fi 341 342 # eat up option 343 shift 344 345 # determine whether option needs an argument 346 eval "opt_MODE=\$opt_MODE_${opt_OPT}" 347 if [ ".$opt_ARG" = . ] && [ ".$opt_ARG_OK" != .yes ]; then 348 if [ ".$opt_MODE" = ".:" ] || [ ".$opt_MODE" = ".+" ]; then 349 opt_PREV="$opt_OPT" 350 continue 351 fi 352 fi 353 354 # process option 355 case $opt_MODE in 356 '.' ) 357 # boolean option 358 eval "opt_${opt_OPT}=yes" 359 ;; 360 ':' ) 361 # option with argument (multiple occurances override) 362 eval "opt_${opt_OPT}=\"\$opt_ARG\"" 363 ;; 364 '+' ) 365 # option with argument (multiple occurances append) 366 eval "opt_${opt_OPT}=\"\$opt_${opt_OPT}\${ASC_NL}\$opt_ARG\"" 367 ;; 368 * ) 369 echo "$msgprefix:Error: unknown option: \`$opt_OPT'" 1>&2 370 echo "$msgprefix:Hint: run \`$toolcmdhelp -h' or \`man shtool' for details" 1>&2 371 exit 1 372 ;; 373 esac 374done 375if [ ".$opt_PREV" != . ]; then 376 echo "$msgprefix:Error: missing argument to option \`$opt_PREV'" 1>&2 377 echo "$msgprefix:Hint: run \`$toolcmdhelp -h' or \`man shtool' for details" 1>&2 378 exit 1 379fi 380 381# process help option 382if [ ".$opt_h" = .yes ]; then 383 echo "Usage: $toolcmdhelp $str_usage" 384 exit 0 385fi 386 387# complain about incorrect number of arguments 388case $arg_MODE in 389 '=' ) 390 if [ $# -ne $arg_NUMS ]; then 391 echo "$msgprefix:Error: invalid number of arguments (exactly $arg_NUMS expected)" 1>&2 392 echo "$msgprefix:Hint: run \`$toolcmd -h' or \`man shtool' for details" 1>&2 393 exit 1 394 fi 395 ;; 396 '+' ) 397 if [ $# -lt $arg_NUMS ]; then 398 echo "$msgprefix:Error: invalid number of arguments (at least $arg_NUMS expected)" 1>&2 399 echo "$msgprefix:Hint: run \`$toolcmd -h' or \`man shtool' for details" 1>&2 400 exit 1 401 fi 402 ;; 403esac 404 405# establish a temporary file on request 406if [ ".$gen_tmpfile" = .yes ]; then 407 # create (explicitly) secure temporary directory 408 if [ ".$TMPDIR" != . ]; then 409 tmpdir="$TMPDIR" 410 elif [ ".$TEMPDIR" != . ]; then 411 tmpdir="$TEMPDIR" 412 else 413 tmpdir="/tmp" 414 fi 415 tmpdir="$tmpdir/.shtool.$$" 416 ( umask 077 417 rm -rf "$tmpdir" >/dev/null 2>&1 || true 418 mkdir "$tmpdir" >/dev/null 2>&1 419 if [ $? -ne 0 ]; then 420 echo "$msgprefix:Error: failed to create temporary directory \`$tmpdir'" 1>&2 421 exit 1 422 fi 423 ) 424 425 # create (implicitly) secure temporary file 426 tmpfile="$tmpdir/shtool.tmp" 427 touch "$tmpfile" 428fi 429 430# utility function: map string to lower case 431util_lower () { 432 echo "$1" | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' 433} 434 435# utility function: map string to upper case 436util_upper () { 437 echo "$1" | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 438} 439 440# cleanup procedure 441shtool_exit () { 442 rc="$1" 443 if [ ".$gen_tmpfile" = .yes ]; then 444 rm -rf "$tmpdir" >/dev/null 2>&1 || true 445 fi 446 exit $rc 447} 448 449## 450## DISPATCH INTO SCRIPT BODY 451## 452 453case $tool in 454 455echo ) 456 ## 457 ## echo -- Print string with optional construct expansion 458 ## Copyright (c) 1998-2005 Ralf S. Engelschall <rse@engelschall.com> 459 ## 460 461 text="$*" 462 463 # check for broken escape sequence expansion 464 seo='' 465 bytes=`echo '\1' | wc -c | awk '{ printf("%s", $1); }'` 466 if [ ".$bytes" != .3 ]; then 467 bytes=`echo -E '\1' | wc -c | awk '{ printf("%s", $1); }'` 468 if [ ".$bytes" = .3 ]; then 469 seo='-E' 470 fi 471 fi 472 473 # check for existing -n option (to suppress newline) 474 minusn='' 475 bytes=`echo -n 123 2>/dev/null | wc -c | awk '{ printf("%s", $1); }'` 476 if [ ".$bytes" = .3 ]; then 477 minusn='-n' 478 fi 479 480 # determine terminal bold sequence 481 term_bold='' 482 term_norm='' 483 if [ ".$opt_e" = .yes ] && [ ".`echo $text | grep '%[Bb]'`" != . ]; then 484 case $TERM in 485 # for the most important terminal types we directly know the sequences 486 xterm|xterm*|vt220|vt220*) 487 term_bold=`awk 'BEGIN { printf("%c%c%c%c", 27, 91, 49, 109); }' </dev/null 2>/dev/null` 488 term_norm=`awk 'BEGIN { printf("%c%c%c", 27, 91, 109); }' </dev/null 2>/dev/null` 489 ;; 490 vt100|vt100*|cygwin) 491 term_bold=`awk 'BEGIN { printf("%c%c%c%c%c%c", 27, 91, 49, 109, 0, 0); }' </dev/null 2>/dev/null` 492 term_norm=`awk 'BEGIN { printf("%c%c%c%c%c", 27, 91, 109, 0, 0); }' </dev/null 2>/dev/null` 493 ;; 494 # for all others, we try to use a possibly existing `tput' or `tcout' utility 495 * ) 496 paths=`echo $PATH | sed -e 's/:/ /g'` 497 for tool in tput tcout; do 498 for dir in $paths; do 499 if [ -r "$dir/$tool" ]; then 500 for seq in bold md smso; do # 'smso' is last 501 bold="`$dir/$tool $seq 2>/dev/null`" 502 if [ ".$bold" != . ]; then 503 term_bold="$bold" 504 break 505 fi 506 done 507 if [ ".$term_bold" != . ]; then 508 for seq in sgr0 me rmso init reset; do # 'reset' is last 509 norm="`$dir/$tool $seq 2>/dev/null`" 510 if [ ".$norm" != . ]; then 511 term_norm="$norm" 512 break 513 fi 514 done 515 fi 516 break 517 fi 518 done 519 if [ ".$term_bold" != . ] && [ ".$term_norm" != . ]; then 520 break; 521 fi 522 done 523 ;; 524 esac 525 if [ ".$term_bold" = . ] || [ ".$term_norm" = . ]; then 526 echo "$msgprefix:Warning: unable to determine terminal sequence for bold mode" 1>&2 527 term_bold='' 528 term_norm='' 529 fi 530 fi 531 532 # determine user name 533 username='' 534 if [ ".$opt_e" = .yes ] && [ ".`echo $text | grep '%[uUgG]'`" != . ]; then 535 username="`(id -un) 2>/dev/null`" 536 if [ ".$username" = . ]; then 537 str="`(id) 2>/dev/null`" 538 if [ ".`echo $str | grep '^uid[ ]*=[ ]*[0-9]*('`" != . ]; then 539 username=`echo $str | sed -e 's/^uid[ ]*=[ ]*[0-9]*(//' -e 's/).*$//'` 540 fi 541 if [ ".$username" = . ]; then 542 username="$LOGNAME" 543 if [ ".$username" = . ]; then 544 username="$USER" 545 if [ ".$username" = . ]; then 546 username="`(whoami) 2>/dev/null |\ 547 awk '{ printf("%s", $1); }'`" 548 if [ ".$username" = . ]; then 549 username="`(who am i) 2>/dev/null |\ 550 awk '{ printf("%s", $1); }'`" 551 if [ ".$username" = . ]; then 552 username='unknown' 553 fi 554 fi 555 fi 556 fi 557 fi 558 fi 559 fi 560 561 # determine user id 562 userid='' 563 if [ ".$opt_e" = .yes ] && [ ".`echo $text | grep '%U'`" != . ]; then 564 userid="`(id -u) 2>/dev/null`" 565 if [ ".$userid" = . ]; then 566 userid="`(id -u ${username}) 2>/dev/null`" 567 if [ ".$userid" = . ]; then 568 str="`(id) 2>/dev/null`" 569 if [ ".`echo $str | grep '^uid[ ]*=[ ]*[0-9]*('`" != . ]; then 570 userid=`echo $str | sed -e 's/^uid[ ]*=[ ]*//' -e 's/(.*$//'` 571 fi 572 if [ ".$userid" = . ]; then 573 userid=`(getent passwd ${username}) 2>/dev/null | \ 574 sed -e 's/[^:]*:[^:]*://' -e 's/:.*$//'` 575 if [ ".$userid" = . ]; then 576 userid=`grep "^${username}:" /etc/passwd 2>/dev/null | \ 577 sed -e 's/[^:]*:[^:]*://' -e 's/:.*$//'` 578 if [ ".$userid" = . ]; then 579 userid=`(ypcat passwd) 2>/dev/null | 580 grep "^${username}:" | \ 581 sed -e 's/[^:]*:[^:]*://' -e 's/:.*$//'` 582 if [ ".$userid" = . ]; then 583 userid='?' 584 fi 585 fi 586 fi 587 fi 588 fi 589 fi 590 fi 591 592 # determine (primary) group id 593 groupid='' 594 if [ ".$opt_e" = .yes ] && [ ".`echo $text | grep '%[gG]'`" != . ]; then 595 groupid="`(id -g ${username}) 2>/dev/null`" 596 if [ ".$groupid" = . ]; then 597 str="`(id) 2>/dev/null`" 598 if [ ".`echo $str | grep 'gid[ ]*=[ ]*[0-9]*('`" != . ]; then 599 groupid=`echo $str | sed -e 's/^.*gid[ ]*=[ ]*//' -e 's/(.*$//'` 600 fi 601 if [ ".$groupid" = . ]; then 602 groupid=`(getent passwd ${username}) 2>/dev/null | \ 603 sed -e 's/[^:]*:[^:]*:[^:]*://' -e 's/:.*$//'` 604 if [ ".$groupid" = . ]; then 605 groupid=`grep "^${username}:" /etc/passwd 2>/dev/null | \ 606 sed -e 's/[^:]*:[^:]*:[^:]*://' -e 's/:.*$//'` 607 if [ ".$groupid" = . ]; then 608 groupid=`(ypcat passwd) 2>/dev/null | grep "^${username}:" | \ 609 sed -e 's/[^:]*:[^:]*:[^:]*://' -e 's/:.*$//'` 610 if [ ".$groupid" = . ]; then 611 groupid='?' 612 fi 613 fi 614 fi 615 fi 616 fi 617 fi 618 619 # determine (primary) group name 620 groupname='' 621 if [ ".$opt_e" = .yes ] && [ ".`echo $text | grep '%g'`" != . ]; then 622 groupname="`(id -gn ${username}) 2>/dev/null`" 623 if [ ".$groupname" = . ]; then 624 str="`(id) 2>/dev/null`" 625 if [ ".`echo $str | grep 'gid[ ]*=[ ]*[0-9]*('`" != . ]; then 626 groupname=`echo $str | sed -e 's/^.*gid[ ]*=[ ]*[0-9]*(//' -e 's/).*$//'` 627 fi 628 if [ ".$groupname" = . ]; then 629 groupname=`(getent group) 2>/dev/null | \ 630 grep "^[^:]*:[^:]*:${groupid}:" | \ 631 sed -e 's/:.*$//'` 632 if [ ".$groupname" = . ]; then 633 groupname=`grep "^[^:]*:[^:]*:${groupid}:" /etc/group 2>/dev/null | \ 634 sed -e 's/:.*$//'` 635 if [ ".$groupname" = . ]; then 636 groupname=`(ypcat group) 2>/dev/null | \ 637 grep "^[^:]*:[^:]*:${groupid}:" | \ 638 sed -e 's/:.*$//'` 639 if [ ".$groupname" = . ]; then 640 groupname='?' 641 fi 642 fi 643 fi 644 fi 645 fi 646 fi 647 648 # determine host and domain name 649 hostname='' 650 domainname='' 651 if [ ".$opt_e" = .yes ] && [ ".`echo $text | grep '%h'`" != . ]; then 652 hostname="`(uname -n) 2>/dev/null |\ 653 awk '{ printf("%s", $1); }'`" 654 if [ ".$hostname" = . ]; then 655 hostname="`(hostname) 2>/dev/null |\ 656 awk '{ printf("%s", $1); }'`" 657 if [ ".$hostname" = . ]; then 658 hostname='unknown' 659 fi 660 fi 661 case $hostname in 662 *.* ) 663 domainname=".`echo $hostname | cut -d. -f2-`" 664 hostname="`echo $hostname | cut -d. -f1`" 665 ;; 666 esac 667 fi 668 if [ ".$opt_e" = .yes ] && [ ".`echo $text | grep '%d'`" != . ]; then 669 if [ ".$domainname" = . ]; then 670 if [ -f /etc/resolv.conf ]; then 671 domainname="`grep '^[ ]*domain' /etc/resolv.conf | sed -e 'q' |\ 672 sed -e 's/.*domain//' \ 673 -e 's/^[ ]*//' -e 's/^ *//' -e 's/^ *//' \ 674 -e 's/^\.//' -e 's/^/./' |\ 675 awk '{ printf("%s", $1); }'`" 676 if [ ".$domainname" = . ]; then 677 domainname="`grep '^[ ]*search' /etc/resolv.conf | sed -e 'q' |\ 678 sed -e 's/.*search//' \ 679 -e 's/^[ ]*//' -e 's/^ *//' -e 's/^ *//' \ 680 -e 's/ .*//' -e 's/ .*//' \ 681 -e 's/^\.//' -e 's/^/./' |\ 682 awk '{ printf("%s", $1); }'`" 683 fi 684 fi 685 fi 686 fi 687 688 # determine current time 689 time_day='' 690 time_month='' 691 time_year='' 692 time_monthname='' 693 if [ ".$opt_e" = .yes ] && [ ".`echo $text | grep '%[DMYm]'`" != . ]; then 694 time_day=`date '+%d'` 695 time_month=`date '+%m'` 696 time_year=`date '+%Y' 2>/dev/null` 697 if [ ".$time_year" = . ]; then 698 time_year=`date '+%y'` 699 case $time_year in 700 [5-9][0-9]) time_year="19$time_year" ;; 701 [0-4][0-9]) time_year="20$time_year" ;; 702 esac 703 fi 704 case $time_month in 705 1|01) time_monthname='Jan' ;; 706 2|02) time_monthname='Feb' ;; 707 3|03) time_monthname='Mar' ;; 708 4|04) time_monthname='Apr' ;; 709 5|05) time_monthname='May' ;; 710 6|06) time_monthname='Jun' ;; 711 7|07) time_monthname='Jul' ;; 712 8|08) time_monthname='Aug' ;; 713 9|09) time_monthname='Sep' ;; 714 10) time_monthname='Oct' ;; 715 11) time_monthname='Nov' ;; 716 12) time_monthname='Dec' ;; 717 esac 718 fi 719 720 # expand special ``%x'' constructs 721 if [ ".$opt_e" = .yes ]; then 722 text=`echo $seo "$text" |\ 723 sed -e "s/%B/${term_bold}/g" \ 724 -e "s/%b/${term_norm}/g" \ 725 -e "s/%u/${username}/g" \ 726 -e "s/%U/${userid}/g" \ 727 -e "s/%g/${groupname}/g" \ 728 -e "s/%G/${groupid}/g" \ 729 -e "s/%h/${hostname}/g" \ 730 -e "s/%d/${domainname}/g" \ 731 -e "s/%D/${time_day}/g" \ 732 -e "s/%M/${time_month}/g" \ 733 -e "s/%Y/${time_year}/g" \ 734 -e "s/%m/${time_monthname}/g" 2>/dev/null` 735 fi 736 737 # create output 738 if [ .$opt_n = .no ]; then 739 echo $seo "$text" 740 else 741 # the harder part: echo -n is best, because 742 # awk may complain about some \xx sequences. 743 if [ ".$minusn" != . ]; then 744 echo $seo $minusn "$text" 745 else 746 echo dummy | awk '{ printf("%s", TEXT); }' TEXT="$text" 747 fi 748 fi 749 750 shtool_exit 0 751 ;; 752 753install ) 754 ## 755 ## install -- Install a program, script or datafile 756 ## Copyright (c) 1997-2005 Ralf S. Engelschall <rse@engelschall.com> 757 ## 758 759 # special case: "shtool install -d <dir> [...]" internally 760 # maps to "shtool mkdir -f -p -m 755 <dir> [...]" 761 if [ "$opt_d" = yes ]; then 762 cmd="$0 mkdir -f -p -m 755" 763 if [ ".$opt_o" != . ]; then 764 cmd="$cmd -o '$opt_o'" 765 fi 766 if [ ".$opt_g" != . ]; then 767 cmd="$cmd -g '$opt_g'" 768 fi 769 if [ ".$opt_v" = .yes ]; then 770 cmd="$cmd -v" 771 fi 772 if [ ".$opt_t" = .yes ]; then 773 cmd="$cmd -t" 774 fi 775 for dir in "$@"; do 776 eval "$cmd $dir" || shtool_exit $? 777 done 778 shtool_exit 0 779 fi 780 781 # determine source(s) and destination 782 argc=$# 783 srcs="" 784 while [ $# -gt 1 ]; do 785 srcs="$srcs $1" 786 shift 787 done 788 dstpath="$1" 789 790 # type check for destination 791 dstisdir=0 792 if [ -d $dstpath ]; then 793 dstpath=`echo "$dstpath" | sed -e 's:/$::'` 794 dstisdir=1 795 fi 796 797 # consistency check for destination 798 if [ $argc -gt 2 ] && [ $dstisdir = 0 ]; then 799 echo "$msgprefix:Error: multiple sources require destination to be directory" 1>&2 800 shtool_exit 1 801 fi 802 803 # iterate over all source(s) 804 for src in $srcs; do 805 dst=$dstpath 806 807 # if destination is a directory, append the input filename 808 if [ $dstisdir = 1 ]; then 809 dstfile=`echo "$src" | sed -e 's;.*/\([^/]*\)$;\1;'` 810 dst="$dst/$dstfile" 811 fi 812 813 # check for correct arguments 814 if [ ".$src" = ".$dst" ]; then 815 echo "$msgprefix:Warning: source and destination are the same - skipped" 1>&2 816 continue 817 fi 818 if [ -d "$src" ]; then 819 echo "$msgprefix:Warning: source \`$src' is a directory - skipped" 1>&2 820 continue 821 fi 822 823 # make a temp file name in the destination directory 824 dsttmp=`echo $dst |\ 825 sed -e 's;[^/]*$;;' -e 's;\(.\)/$;\1;' -e 's;^$;.;' \ 826 -e "s;\$;/#INST@$$#;"` 827 828 # verbosity 829 if [ ".$opt_v" = .yes ]; then 830 echo "$src -> $dst" 1>&2 831 fi 832 833 # copy or move the file name to the temp name 834 # (because we might be not allowed to change the source) 835 if [ ".$opt_C" = .yes ]; then 836 opt_c=yes 837 fi 838 if [ ".$opt_c" = .yes ]; then 839 if [ ".$opt_t" = .yes ]; then 840 echo "cp $src $dsttmp" 1>&2 841 fi 842 cp $src $dsttmp || shtool_exit $? 843 else 844 if [ ".$opt_t" = .yes ]; then 845 echo "mv $src $dsttmp" 1>&2 846 fi 847 mv $src $dsttmp || shtool_exit $? 848 fi 849 850 # adjust the target file 851 if [ ".$opt_e" != . ]; then 852 sed='sed' 853 OIFS="$IFS"; IFS="$ASC_NL"; set -- $opt_e; IFS="$OIFS" 854 for e 855 do 856 sed="$sed -e '$e'" 857 done 858 cp $dsttmp $dsttmp.old 859 chmod u+w $dsttmp 860 eval "$sed <$dsttmp.old >$dsttmp" || shtool_exit $? 861 rm -f $dsttmp.old 862 fi 863 if [ ".$opt_s" = .yes ]; then 864 if [ ".$opt_t" = .yes ]; then 865 echo "strip $dsttmp" 1>&2 866 fi 867 strip $dsttmp || shtool_exit $? 868 fi 869 if [ ".$opt_o" != . ]; then 870 if [ ".$opt_t" = .yes ]; then 871 echo "chown $opt_o $dsttmp" 1>&2 872 fi 873 chown $opt_o $dsttmp || shtool_exit $? 874 fi 875 if [ ".$opt_g" != . ]; then 876 if [ ".$opt_t" = .yes ]; then 877 echo "chgrp $opt_g $dsttmp" 1>&2 878 fi 879 chgrp $opt_g $dsttmp || shtool_exit $? 880 fi 881 if [ ".$opt_m" != ".-" ]; then 882 if [ ".$opt_t" = .yes ]; then 883 echo "chmod $opt_m $dsttmp" 1>&2 884 fi 885 chmod $opt_m $dsttmp || shtool_exit $? 886 fi 887 888 # determine whether to do a quick install 889 # (has to be done _after_ the strip was already done) 890 quick=no 891 if [ ".$opt_C" = .yes ]; then 892 if [ -r $dst ]; then 893 if cmp -s $src $dst; then 894 quick=yes 895 fi 896 fi 897 fi 898 899 # finally, install the file to the real destination 900 if [ $quick = yes ]; then 901 if [ ".$opt_t" = .yes ]; then 902 echo "rm -f $dsttmp" 1>&2 903 fi 904 rm -f $dsttmp 905 else 906 if [ ".$opt_t" = .yes ]; then 907 echo "rm -f $dst && mv $dsttmp $dst" 1>&2 908 fi 909 rm -f $dst && mv $dsttmp $dst 910 fi 911 done 912 913 shtool_exit 0 914 ;; 915 916mkdir ) 917 ## 918 ## mkdir -- Make one or more directories 919 ## Copyright (c) 1996-2005 Ralf S. Engelschall <rse@engelschall.com> 920 ## 921 922 errstatus=0 923 for p in ${1+"$@"}; do 924 # if the directory already exists... 925 if [ -d "$p" ]; then 926 if [ ".$opt_f" = .no ] && [ ".$opt_p" = .no ]; then 927 echo "$msgprefix:Error: directory already exists: $p" 1>&2 928 errstatus=1 929 break 930 else 931 continue 932 fi 933 fi 934 # if the directory has to be created... 935 if [ ".$opt_p" = .no ]; then 936 if [ ".$opt_t" = .yes ]; then 937 echo "mkdir $p" 1>&2 938 fi 939 mkdir $p || errstatus=$? 940 if [ ".$opt_o" != . ]; then 941 if [ ".$opt_t" = .yes ]; then 942 echo "chown $opt_o $p" 1>&2 943 fi 944 chown $opt_o $p || errstatus=$? 945 fi 946 if [ ".$opt_g" != . ]; then 947 if [ ".$opt_t" = .yes ]; then 948 echo "chgrp $opt_g $p" 1>&2 949 fi 950 chgrp $opt_g $p || errstatus=$? 951 fi 952 if [ ".$opt_m" != . ]; then 953 if [ ".$opt_t" = .yes ]; then 954 echo "chmod $opt_m $p" 1>&2 955 fi 956 chmod $opt_m $p || errstatus=$? 957 fi 958 else 959 # the smart situation 960 set fnord `echo ":$p" |\ 961 sed -e 's/^:\//%/' \ 962 -e 's/^://' \ 963 -e 's/\// /g' \ 964 -e 's/^%/\//'` 965 shift 966 pathcomp='' 967 for d in ${1+"$@"}; do 968 pathcomp="$pathcomp$d" 969 case "$pathcomp" in 970 -* ) pathcomp="./$pathcomp" ;; 971 esac 972 if [ ! -d "$pathcomp" ]; then 973 if [ ".$opt_t" = .yes ]; then 974 echo "mkdir $pathcomp" 1>&2 975 fi 976 mkdir $pathcomp || errstatus=$? 977 if [ ".$opt_o" != . ]; then 978 if [ ".$opt_t" = .yes ]; then 979 echo "chown $opt_o $pathcomp" 1>&2 980 fi 981 chown $opt_o $pathcomp || errstatus=$? 982 fi 983 if [ ".$opt_g" != . ]; then 984 if [ ".$opt_t" = .yes ]; then 985 echo "chgrp $opt_g $pathcomp" 1>&2 986 fi 987 chgrp $opt_g $pathcomp || errstatus=$? 988 fi 989 if [ ".$opt_m" != . ]; then 990 if [ ".$opt_t" = .yes ]; then 991 echo "chmod $opt_m $pathcomp" 1>&2 992 fi 993 chmod $opt_m $pathcomp || errstatus=$? 994 fi 995 fi 996 pathcomp="$pathcomp/" 997 done 998 fi 999 done 1000 1001 shtool_exit $errstatus 1002 ;; 1003 1004fixperm ) 1005 ## 1006 ## fixperm -- Fix file permissions inside a source tree 1007 ## Copyright (c) 1996-2005 Ralf S. Engelschall <rse@engelschall.com> 1008 ## 1009 1010 paths="$*" 1011 1012 # check whether the test command supports the -x option 1013 if [ -x /bin/sh ] 2>/dev/null; then 1014 minusx="-x" 1015 else 1016 minusx="-r" 1017 fi 1018 1019 # iterate over paths 1020 for p in $paths; do 1021 for file in `find $p -depth -print`; do 1022 if [ -f $file ]; then 1023 if [ $minusx $file ]; then 1024 if [ ".$opt_v" = .yes ]; then 1025 echo "-rwxr-xr-x $file" 2>&1 1026 fi 1027 if [ ".$opt_t" = .yes ]; then 1028 echo "chmod 755 $file" 2>&1 1029 fi 1030 chmod 755 $file 1031 else 1032 if [ ".$opt_v" = .yes ]; then 1033 echo "-rw-r--r-- $file" 2>&1 1034 fi 1035 if [ ".$opt_t" = .yes ]; then 1036 echo "chmod 644 $file" 2>&1 1037 fi 1038 chmod 644 $file 1039 fi 1040 continue 1041 fi 1042 if [ -d $file ]; then 1043 if [ ".$opt_v" = .yes ]; then 1044 echo "drwxr-xr-x $file" 2>&1 1045 fi 1046 if [ ".$opt_t" = .yes ]; then 1047 echo "chmod 755 $file" 2>&1 1048 fi 1049 chmod 755 $file 1050 continue 1051 fi 1052 if [ ".$opt_v" = .yes ]; then 1053 echo "?????????? $file" 2>&1 1054 fi 1055 done 1056 done 1057 1058 shtool_exit 0 1059 ;; 1060 1061tarball ) 1062 ## 1063 ## tarball -- Roll distribution tarballs 1064 ## Copyright (c) 1999-2005 Ralf S. Engelschall <rse@engelschall.com> 1065 ## 1066 1067 srcs="$*" 1068 1069 # check whether the test command supports the -x option 1070 if [ -x /bin/sh ] 2>/dev/null; then 1071 minusx="-x" 1072 else 1073 minusx="-r" 1074 fi 1075 1076 # find the tools 1077 paths="`echo $PATH |\ 1078 sed -e 's%/*:%:%g' -e 's%/*$%%' \ 1079 -e 's/^:/.:/' -e 's/::/:.:/g' -e 's/:$/:./' \ 1080 -e 's/:/ /g'`" 1081 for spec in find:gfind,find tar:gtar,tar tardy:tardy,tarcust; do 1082 prg=`echo $spec | sed -e 's/:.*$//'` 1083 tools=`echo $spec | sed -e 's/^.*://'` 1084 eval "prg_${prg}=''" 1085 # iterate over tools 1086 for tool in `echo $tools | sed -e 's/,/ /g'`; do 1087 # iterate over paths 1088 for path in $paths; do 1089 if [ $minusx "$path/$tool" ] && [ ! -d "$path/$tool" ]; then 1090 eval "prg_${prg}=\"$path/$tool\"" 1091 break 1092 fi 1093 done 1094 eval "val=\$prg_${prg}" 1095 if [ ".$val" != . ]; then 1096 break 1097 fi 1098 done 1099 done 1100 1101 # expand source paths 1102 exclude='' 1103 for pat in `echo $opt_e | sed 's/,/ /g'`; do 1104 exclude="$exclude | grep -v '$pat'" 1105 done 1106 if [ ".$opt_t" = .yes ]; then 1107 echo "cp /dev/null $tmpfile.lst" 1>&2 1108 fi 1109 cp /dev/null $tmpfile.lst 1110 for src in $srcs; do 1111 if [ -d $src ]; then 1112 if [ ".$opt_t" = .yes ]; then 1113 echo "(cd $src && $prg_find . -type f -depth -print) | sed -e 's:^\\.\$::' -e 's:^\\./::' | cat $exclude >>$tmpfile.lst" 1>&2 1114 fi 1115 (cd $src && $prg_find . -type f -depth -print) |\ 1116 sed -e 's:^\.$::' -e 's:^\./::' | eval cat $exclude >>$tmpfile.lst 1117 else 1118 if [ ".$opt_t" = .yes ]; then 1119 echo "echo $src >>$tmpfile.lst" 1>&2 1120 fi 1121 echo $src >>$tmpfile.lst 1122 fi 1123 done 1124 sort <$tmpfile.lst >$tmpfile.lst.n 1125 mv $tmpfile.lst.n $tmpfile.lst 1126 if [ ".$opt_v" = .yes ]; then 1127 cat $tmpfile.lst | sed -e 's/^/ /' 1>&2 1128 fi 1129 1130 # determine tarball file and directory name 1131 if [ ".$opt_o" != . ]; then 1132 tarfile="$opt_o" 1133 if [ ".$opt_d" != . ]; then 1134 tarname="$opt_d" 1135 else 1136 tarname=`echo $tarfile | sed -e 's/\.tar.*$//' -e 's;.*/\([^/]*\)$;\1;'` 1137 fi 1138 else 1139 if [ ".$opt_d" != . ]; then 1140 tarname="$opt_d" 1141 elif [ -d "$from" ]; then 1142 tarname=`echo $from | sed -e 's;.*/\([^/]*\)$;\1;'` 1143 else 1144 tarname="out" 1145 fi 1146 tarfile="$tarname.tar" 1147 fi 1148 1149 # roll the tarball 1150 compress='' 1151 if [ ".$opt_c" != . ]; then 1152 compress="| $opt_c" 1153 fi 1154 if [ ".$prg_tardy" != . ]; then 1155 # the elegant hackers way 1156 tardy_opt="--prefix=$tarname" 1157 tardy_opt="$tardy_opt --user_number=0 --group_number=0" # security! 1158 if [ ".$opt_u" != . ]; then 1159 tardy_opt="$tardy_opt --user_name=$opt_u" 1160 fi 1161 if [ ".$opt_g" != . ]; then 1162 tardy_opt="$tardy_opt --group_name=$opt_g" 1163 fi 1164 if [ ".$opt_t" = .yes ]; then 1165 echo "cat $tmpfile.lst | xargs $prg_tar cf - | $prg_tardy $tardy_opt | cat $compress >$tmpfile.out" 1>&2 1166 fi 1167 cat $tmpfile.lst |\ 1168 xargs $prg_tar cf - |\ 1169 $prg_tardy $tardy_opt |\ 1170 eval cat $compress >$tmpfile.out 1171 if [ ".$opt_t" = .yes ]; then 1172 echo "cp $tmpfile.out $tarfile" 1>&2 1173 fi 1174 cp $tmpfile.out $tarfile 1175 else 1176 # the portable standard way 1177 if [ ".$opt_t" = .yes ]; then 1178 echo "mkdir $tmpdir/$tarname" 1>&2 1179 fi 1180 mkdir $tmpdir/$tarname || shtool_exit 1 1181 if [ ".$opt_t" = .yes ]; then 1182 echo "cat $tmpfile.lst | xargs $prg_tar cf - | (cd $tmpdir/$tarname && $prg_tar xf -)" 1>&2 1183 fi 1184 cat $tmpfile.lst |\ 1185 xargs $prg_tar cf - |\ 1186 (cd $tmpdir/$tarname && $prg_tar xf -) 1187 if [ ".$opt_u" != . ]; then 1188 if [ ".$opt_t" = .yes ]; then 1189 echo "chown -R $opt_u $tmpdir/$tarname >/dev/null 2>&1" 2>&1 1190 fi 1191 chown -R $opt_u $tmpdir/$tarname >/dev/null 2>&1 ||\ 1192 echo "$msgprefix:Warning: cannot set user name \`$opt_u' (would require root privileges)" 1193 fi 1194 if [ ".$opt_g" != . ]; then 1195 if [ ".$opt_t" = .yes ]; then 1196 echo "chgrp -R $opt_g $tmpdir/$tarname >/dev/null 2>&1" 2>&1 1197 fi 1198 chgrp -R $opt_g $tmpdir/$tarname >/dev/null 2>&1 ||\ 1199 echo "$msgprefix:Warning: cannot set group name \`$opt_g' (would require root privileges)" 1200 fi 1201 if [ ".$opt_t" = .yes ]; then 1202 echo "(cd $tmpdir && $prg_find $tarname -type f -depth -print | sort | xargs $prg_tar cf -) | cat $compress >$tmpfile.out" 1>&2 1203 fi 1204 (cd $tmpdir && $prg_find $tarname -type f -depth -print | sort | xargs $prg_tar cf -) |\ 1205 eval cat $compress >$tmpfile.out 1206 if [ ".$opt_t" = .yes ]; then 1207 echo "cp $tmpfile.out $tarfile" 1>&2 1208 fi 1209 cp $tmpfile.out $tarfile 1210 if [ ".$opt_t" = .yes ]; then 1211 echo "rm -rf $tmpdir/$tarname" 1>&2 1212 fi 1213 rm -rf $tmpdir/$tarname 1214 fi 1215 1216 # cleanup 1217 if [ ".$opt_t" = .yes ]; then 1218 echo "rm -f $tmpfile.lst $tmpfile.out" 1>&2 1219 fi 1220 rm -f $tmpfile.lst $tmpfile.out 1221 1222 shtool_exit 0 1223 ;; 1224 1225version ) 1226 ## 1227 ## version -- Maintain a version information file 1228 ## Copyright (c) 1994-2005 Ralf S. Engelschall <rse@engelschall.com> 1229 ## 1230 1231 file="$1" 1232 1233 # determine prefix and name 1234 name="$opt_n" 1235 prefix="$opt_p" 1236 1237 # determine current version 1238 triple="$opt_s" 1239 if [ ".$triple" != . ]; then 1240 # use given triple 1241 if [ ".`echo $triple | grep '[0-9]*.[0-9]*[sabp.][0-9]*'`" = . ]; then 1242 echo "$msgprefix:Error: invalid argument to option \`-s': \`$opt_s'" 1>&2 1243 shtool_exit 1 1244 fi 1245 eval `echo $triple |\ 1246 sed -e 's%\([0-9]*\)\.\([0-9]*\)\([sabp.]\)\([0-9]*\).*%\ 1247 ver="\1";rev="\2";typ="\3";lev="\4"%'` 1248 tim=calc 1249 elif [ -r $file ]; then 1250 # determine triple from given file 1251 eval `grep 'Version [0-9]*.[0-9]*[sabp.][0-9]* ([0-9]*-[a-zA-Z]*-[0-9]*)' $file |\ 1252 sed -e 's%.*Version \([0-9]*\)\.\([0-9]*\)\([sabp.]\)\([0-9]*\) (\([0-9]*-[a-zA-Z]*-[0-9]*\)).*%\ 1253 ver="\1";rev="\2";typ="\3";lev="\4";tim="\5"%' -e 'q'` 1254 else 1255 # intialise to first version 1256 ver=0 1257 rev=1 1258 typ=. 1259 lev=0 1260 tim=calc 1261 fi 1262 1263 # determine new version in batch 1264 if [ ".$opt_i" != . ]; then 1265 case $opt_i in 1266 v ) ver=`expr $ver + 1` 1267 rev=0 1268 lev=0 1269 ;; 1270 r ) rev=`expr $rev + 1` 1271 lev=0 1272 ;; 1273 l ) lev=`expr $lev + 1` 1274 ;; 1275 * ) echo "$msgprefix:Error: invalid argument to option \`-i': \`$opt_i'" 1>&2 1276 shtool_exit 1 1277 ;; 1278 esac 1279 tim=calc 1280 fi 1281 1282 # determine new version interactively 1283 if [ ".$opt_e" = .yes ]; then 1284 echo "old version: ${ver}.${rev}${typ}${lev}" 1285 while [ 1 ]; do 1286 echo dummy | awk '{ printf("new version: "); }' 1287 read triple 1288 case $triple in 1289 [0-9]*.[0-9]*[sabp.][0-9]* ) 1290 ;; 1291 * ) echo "$msgprefix:Error: invalid version string entered: \`$triple'" 1>&2 1292 continue 1293 ;; 1294 esac 1295 break 1296 done 1297 eval `echo $triple |\ 1298 sed -e 's%^\([0-9]*\)\.\([0-9]*\)\([sabp.]\)\([0-9]*\)$%\ 1299 ver="\1";rev="\2";typ="\3";lev="\4"%'` 1300 tim=calc 1301 fi 1302 1303 # determine hexadecimal and libtool value of version 1304 case $typ in 1305 a ) typnum=0; levnum=$lev ;; 1306 b ) typnum=1; levnum=$lev ;; 1307 p | . ) typnum=2; levnum=$lev ;; 1308 s ) typnum=15; levnum=255 ;; # snapshots are special 1309 esac 1310 hex=`echo "$ver:$rev:$typnum:$levnum" |\ 1311 awk -F: '{ printf("0x%x%02x%1x%02x", $1, $2, $3, $4); }' |\ 1312 tr 'abcdef' 'ABCDEF'` 1313 ltv=`echo "$ver:$rev:$typnum:$levnum" |\ 1314 awk -F: '{ printf("%d:%d", $1*10 + $2, $3*10 + $4); }'` 1315 1316 # determine date 1317 if [ ".$tim" = .calc ]; then 1318 day=`date '+%d'` 1319 month=`date '+%m'` 1320 year=`date '+%Y' 2>/dev/null` 1321 if [ ".$time_year" = . ]; then 1322 year=`date '+%y'` 1323 case $year in 1324 [5-9][0-9]) year="19$year" ;; 1325 [0-4][0-9]) year="20$year" ;; 1326 esac 1327 fi 1328 case $month in 1329 1|01) month='Jan' ;; 1330 2|02) month='Feb' ;; 1331 3|03) month='Mar' ;; 1332 4|04) month='Apr' ;; 1333 5|05) month='May' ;; 1334 6|06) month='Jun' ;; 1335 7|07) month='Jul' ;; 1336 8|08) month='Aug' ;; 1337 9|09) month='Sep' ;; 1338 10) month='Oct' ;; 1339 11) month='Nov' ;; 1340 12) month='Dec' ;; 1341 esac 1342 tim="${day}-${month}-${year}" 1343 fi 1344 1345 # perform result actions 1346 mode=show 1347 if [ ".$opt_i" != . ]; then 1348 mode=edit 1349 elif [ ".$opt_e" = .yes ]; then 1350 mode=edit 1351 elif [ ".$opt_s" != . ]; then 1352 mode=edit 1353 fi 1354 if [ ".$mode" = .show ]; then 1355 # just display the current version 1356 case $opt_d in 1357 short ) 1358 echo "${ver}.${rev}${typ}${lev}" 1359 ;; 1360 long ) 1361 echo "${ver}.${rev}${typ}${lev} ($tim)" 1362 ;; 1363 libtool ) 1364 echo "${ltv}" 1365 ;; 1366 hex ) 1367 echo "${hex}" 1368 ;; 1369 * ) echo "$msgprefix:Error: invalid argument to option \`-d': \`$opt_d'" 1>&2 1370 shtool_exit 1 1371 ;; 1372 esac 1373 else 1374 # update the version file 1375 1376 # pre-generate various strings 1377 triple="${ver}.${rev}${typ}${lev}" 1378 vHex="$hex" 1379 vShort="${triple}" 1380 vLong="${triple} (${tim})" 1381 vTeX="This is ${name}, Version ${triple} (${tim})" 1382 vGNU="${name} ${triple} (${tim})" 1383 vWeb="${name}/${triple}" 1384 vSCCS="@(#)${name} ${triple} (${tim})" 1385 vRCS="\$Id: ${name} ${triple} (${tim}) \$" 1386 1387 # determine string out of filename 1388 # (do NOT try to optimize this in any way because of portability) 1389 filestr=`echo $file |\ 1390 tr 'abcdefghijklmnopqrstuvwxyz./%+' \ 1391 'ABCDEFGHIJKLMNOPQRSTUVWXYZ____' | sed -e 's/-/_/g'` 1392 1393 # generate uppercase prefix 1394 prefixupper=`echo $prefix |\ 1395 tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` 1396 1397 # create the version file according the the selected language 1398 echo "new version: ${vLong}" 1399 1400 cp /dev/null $file 1401 case $opt_l in 1402 txt ) 1403 echo >>$file "" 1404 echo >>$file " ${file} -- Version Information for ${name} (syntax: Text)" 1405 echo >>$file " [automatically generated and maintained by GNU shtool]" 1406 echo >>$file "" 1407 echo >>$file " $vTeX" 1408 echo >>$file "" 1409 ;; 1410 c ) 1411 echo >>$file "/*" 1412 echo >>$file "** ${file} -- Version Information for ${name} (syntax: C/C++)" 1413 echo >>$file "** [automatically generated and maintained by GNU shtool]" 1414 echo >>$file "*/" 1415 echo >>$file "" 1416 echo >>$file "#ifdef _${filestr}_AS_HEADER_" 1417 echo >>$file "" 1418 echo >>$file "#ifndef _${filestr}_" 1419 echo >>$file "#define _${filestr}_" 1420 echo >>$file "" 1421 echo >>$file "#define ${prefixupper}VERSION ${vHex}" 1422 echo >>$file "" 1423 echo >>$file "typedef struct {" 1424 echo >>$file " const int v_hex;" 1425 echo >>$file " const char *v_short;" 1426 echo >>$file " const char *v_long;" 1427 echo >>$file " const char *v_tex;" 1428 echo >>$file " const char *v_gnu;" 1429 echo >>$file " const char *v_web;" 1430 echo >>$file " const char *v_sccs;" 1431 echo >>$file " const char *v_rcs;" 1432 echo >>$file "} ${prefix}version_t;" 1433 echo >>$file "" 1434 echo >>$file "extern ${prefix}version_t ${prefix}version;" 1435 echo >>$file "" 1436 echo >>$file "#endif /* _${filestr}_ */" 1437 echo >>$file "" 1438 echo >>$file "#else /* _${filestr}_AS_HEADER_ */" 1439 echo >>$file "" 1440 echo >>$file "#define _${filestr}_AS_HEADER_" 1441 echo >>$file "#include \"${file}\"" 1442 echo >>$file "#undef _${filestr}_AS_HEADER_" 1443 echo >>$file "" 1444 echo >>$file "${prefix}version_t ${prefix}version = {" 1445 echo >>$file " ${vHex}," 1446 echo >>$file " \"${vShort}\"," 1447 echo >>$file " \"${vLong}\"," 1448 echo >>$file " \"${vTeX}\"," 1449 echo >>$file " \"${vGNU}\"," 1450 echo >>$file " \"${vWeb}\"," 1451 echo >>$file " \"${vSCCS}\"," 1452 echo >>$file " \"${vRCS}\"" 1453 echo >>$file "};" 1454 echo >>$file "" 1455 echo >>$file "#endif /* _${filestr}_AS_HEADER_ */" 1456 echo >>$file "" 1457 ;; 1458 m4 ) 1459 echo >>$file "##" 1460 echo >>$file "## ${file} -- Version Information for ${name} (syntax: M4)" 1461 echo >>$file "## [automatically generated and maintained by GNU shtool]" 1462 echo >>$file "##" 1463 echo >>$file "" 1464 echo >>$file "m4_define([v_hex], [${vHex}])" 1465 echo >>$file "m4_define([v_short], [${vShort}])" 1466 echo >>$file "m4_define([v_long], [${vLong}])" 1467 echo >>$file "m4_define([v_tex], [${vTeX}])" 1468 echo >>$file "m4_define([v_gnu], [${vGNU}])" 1469 echo >>$file "m4_define([v_web], [${vWeb}])" 1470 echo >>$file "m4_define([v_sccs], [${vSCCS}])" 1471 echo >>$file "m4_define([v_rcs], [${vRCS}])" 1472 echo >>$file "" 1473 ;; 1474 perl ) 1475 echo >>$file "##" 1476 echo >>$file "## ${file} -- Version Information for ${name} (syntax: Perl)" 1477 echo >>$file "## [automatically generated and maintained by GNU shtool]" 1478 echo >>$file "##" 1479 echo >>$file "" 1480 echo >>$file "our \$${prefix}version = {" 1481 echo >>$file " 'v_hex' => ${vHex}," 1482 echo >>$file " 'v_short' => \"${vShort}\"," 1483 echo >>$file " 'v_long' => \"${vLong}\"," 1484 echo >>$file " 'v_tex' => \"${vTeX}\"," 1485 echo >>$file " 'v_gnu' => \"${vGNU}\"," 1486 echo >>$file " 'v_web' => \"${vWeb}\"," 1487 echo >>$file " 'v_sccs' => \"${vSCCS}\"," 1488 echo >>$file " 'v_rcs' => \"\\${vRCS}/\"" 1489 echo >>$file "};" 1490 echo >>$file "" 1491 echo >>$file "1;" 1492 echo >>$file "" 1493 ;; 1494 python ) 1495 echo >>$file "##" 1496 echo >>$file "## ${file} -- Version Information for ${name} (syntax: Python)" 1497 echo >>$file "## [automatically generated and maintained by GNU shtool]" 1498 echo >>$file "##" 1499 echo >>$file "" 1500 echo >>$file "class ${prefix}version:" 1501 echo >>$file " v_hex = ${vHex}" 1502 echo >>$file " v_short = \"${vShort}\"" 1503 echo >>$file " v_long = \"${vLong}\"" 1504 echo >>$file " v_tex = \"${vTeX}\"" 1505 echo >>$file " v_gnu = \"${vGNU}\"" 1506 echo >>$file " v_web = \"${vWeb}\"" 1507 echo >>$file " v_sccs = \"${vSCCS}\"" 1508 echo >>$file " v_rcs = \"${vRCS}\"" 1509 echo >>$file "" 1510 ;; 1511 * ) echo "$msgprefix:Error: invalid argument to option \`-l': \`$opt_l'" 1>&2 1512 shtool_exit 1 1513 ;; 1514 esac 1515 fi 1516 1517 shtool_exit 0 1518 ;; 1519 1520esac 1521 1522shtool_exit 0 1523 1524