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