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: 7/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## scpp Sharing C Pre-Processor 47## version Maintain a version information file 48## 49## Not available commands (because module was not built-in): 50## mdate Pretty-print modification time of a file or dir 51## table Pretty-print a field-separated list as a table 52## prop Display progress with a running propeller 53## move Move files with simultaneous substitution 54## mkln Make link with calculation of relative paths 55## mkshadow Make a shadow tree through symbolic links 56## rotate Logfile rotation 57## subst Apply sed(1) substitution operations 58## platform Platform Identification Utility 59## arx Extended archive command 60## slo Separate linker options by library class 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 ' scpp [-v|--verbose] [-p|--preserve] [-f|--filter <filter>]' 122 echo ' [-o|--output <ofile>] [-t|--template <tfile>] [-M|--mark' 123 echo ' <mark>] [-D|--define <dname>] [-C|--class <cname>]' 124 echo ' <file> [<file> ...]' 125 echo ' version [-l|--language <lang>] [-n|--name <name>] [-p|--prefix' 126 echo ' <prefix>] [-s|--set <version>] [-e|--edit] [-i|--increase' 127 echo ' <knob>] [-d|--display <type>] <file>' 128 echo '' 129 echo 'Not available <cmd-name> (because module was not built-in):' 130 echo ' mdate [-n|--newline] [-z|--zero] [-s|--shorten] [-d|--digits]' 131 echo ' [-f|--field-sep <str>] [-o|--order <spec>] <path>' 132 echo ' table [-F|--field-sep <sep>] [-w|--width <width>] [-c|--columns' 133 echo ' <cols>] [-s|--strip <strip>] <str><sep><str>...' 134 echo ' prop [-p|--prefix <str>]' 135 echo ' move [-v|--verbose] [-t|--trace] [-e|--expand] [-p|--preserve]' 136 echo ' <src-file> <dst-file>' 137 echo ' mkln [-t|--trace] [-f|--force] [-s|--symbolic] <src-path>' 138 echo ' [<src-path> ...] <dst-path>' 139 echo ' mkshadow [-v|--verbose] [-t|--trace] [-a|--all] <src-dir> <dst-dir>' 140 echo ' rotate [-v|--verbose] [-t|--trace] [-f|--force] [-n|--num-files' 141 echo ' <count>] [-s|--size <size>] [-c|--copy] [-r|--remove]' 142 echo ' [-a|--archive-dir <dir>] [-z|--compress [<tool>:]<level>]' 143 echo ' [-b|--background] [-d|--delay] [-p|--pad <len>] [-m|--mode' 144 echo ' <mode>] [-o|--owner <owner>] [-g|--group <group>] [-M|--migrate' 145 echo ' <cmd>] [-P|--prolog <cmd>] [-E|--epilog <cmd>] <file> [...]' 146 echo ' subst [-v|--verbose] [-t|--trace] [-n|--nop] [-w|--warning]' 147 echo ' [-q|--quiet] [-s|--stealth] [-i|--interactive] [-b|--backup' 148 echo ' <ext>] [-e|--exec <cmd>] [-f|--file <cmd-file>] [<file>]' 149 echo ' [...]' 150 echo ' platform [-F|--format <format>] [-S|--sep <string>] [-C|--conc' 151 echo ' <string>] [-L|--lower] [-U|--upper] [-v|--verbose]' 152 echo ' [-c|--concise] [-n|--no-newline] [-t|--type <type>]' 153 echo ' [-V|--version] [-h|--help]' 154 echo ' arx [-t|--trace] [-C|--command <cmd>] <op> <archive> [<file>' 155 echo ' ...]' 156 echo ' slo [-p|--prefix <str>] -- -L<dir> -l<lib> [-L<dir> -l<lib>' 157 echo ' ...]' 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 scpp 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|scpp|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 scpp ) 261 str_tool="scpp" 262 str_usage="[-v|--verbose] [-p|--preserve] [-f|--filter <filter>] [-o|--output <ofile>] [-t|--template <tfile>] [-M|--mark <mark>] [-D|--define <dname>] [-C|--class <cname>] <file> [<file> ...]" 263 gen_tmpfile=yes 264 arg_spec="1+" 265 opt_spec="v.p.f+o:t:M:D:C:" 266 opt_alias="v:verbose,p:preserve,f:filter,o:output,t:template,M:mark,D:define,C:class" 267 opt_v=no 268 opt_p=no 269 opt_f="" 270 opt_o="lib.h" 271 opt_t="lib.h.in" 272 opt_M="%%MARK%%" 273 opt_D="cpp" 274 opt_C="intern" 275 ;; 276 version ) 277 str_tool="version" 278 str_usage="[-l|--language <lang>] [-n|--name <name>] [-p|--prefix <prefix>] [-s|--set <version>] [-e|--edit] [-i|--increase <knob>] [-d|--display <type>] <file>" 279 arg_spec="1=" 280 opt_spec="l:n:p:s:i:e.d:" 281 opt_alias="l:language,n:name,p:prefix,s:set,e:edit,i:increase,d:display" 282 opt_l="txt" 283 opt_n="unknown" 284 opt_p="" 285 opt_s="" 286 opt_e="no" 287 opt_i="" 288 opt_d="short" 289 ;; 290 -* ) 291 echo "$0:Error: unknown option \`$tool'" 2>&1 292 echo "$0:Hint: run \`$0 -h' for usage" 2>&1 293 exit 1 294 ;; 295 * ) 296 echo "$0:Error: unknown command \`$tool'" 2>&1 297 echo "$0:Hint: run \`$0 -h' for usage" 2>&1 298 exit 1 299 ;; 300esac 301 302## 303## COMMON UTILITY CODE 304## 305 306# commonly used ASCII values 307ASC_TAB=" " 308ASC_NL=" 309" 310 311# determine name of tool 312if [ ".$tool" != . ]; then 313 # used inside shtool script 314 toolcmd="$0 $tool" 315 toolcmdhelp="shtool $tool" 316 msgprefix="shtool:$tool" 317else 318 # used as standalone script 319 toolcmd="$0" 320 toolcmdhelp="sh $0" 321 msgprefix="$str_tool" 322fi 323 324# parse argument specification string 325eval `echo $arg_spec |\ 326 sed -e 's/^\([0-9]*\)\([+=]\)/arg_NUMS=\1; arg_MODE=\2/'` 327 328# parse option specification string 329eval `echo h.$opt_spec |\ 330 sed -e 's/\([a-zA-Z0-9]\)\([.:+]\)/opt_MODE_\1=\2;/g'` 331 332# parse option alias string 333eval `echo h:help,$opt_alias |\ 334 sed -e 's/-/_/g' -e 's/\([a-zA-Z0-9]\):\([^,]*\),*/opt_ALIAS_\2=\1;/g'` 335 336# interate over argument line 337opt_PREV='' 338while [ $# -gt 0 ]; do 339 # special option stops processing 340 if [ ".$1" = ".--" ]; then 341 shift 342 break 343 fi 344 345 # determine option and argument 346 opt_ARG_OK=no 347 if [ ".$opt_PREV" != . ]; then 348 # merge previous seen option with argument 349 opt_OPT="$opt_PREV" 350 opt_ARG="$1" 351 opt_ARG_OK=yes 352 opt_PREV='' 353 else 354 # split argument into option and argument 355 case "$1" in 356 --[a-zA-Z0-9]*=*) 357 eval `echo "x$1" |\ 358 sed -e 's/^x--\([a-zA-Z0-9-]*\)=\(.*\)$/opt_OPT="\1";opt_ARG="\2"/'` 359 opt_STR=`echo $opt_OPT | sed -e 's/-/_/g'` 360 eval "opt_OPT=\${opt_ALIAS_${opt_STR}-${opt_OPT}}" 361 ;; 362 --[a-zA-Z0-9]*) 363 opt_OPT=`echo "x$1" | cut -c4-` 364 opt_STR=`echo $opt_OPT | sed -e 's/-/_/g'` 365 eval "opt_OPT=\${opt_ALIAS_${opt_STR}-${opt_OPT}}" 366 opt_ARG='' 367 ;; 368 -[a-zA-Z0-9]*) 369 eval `echo "x$1" |\ 370 sed -e 's/^x-\([a-zA-Z0-9]\)/opt_OPT="\1";/' \ 371 -e 's/";\(.*\)$/"; opt_ARG="\1"/'` 372 ;; 373 -[a-zA-Z0-9]) 374 opt_OPT=`echo "x$1" | cut -c3-` 375 opt_ARG='' 376 ;; 377 *) 378 break 379 ;; 380 esac 381 fi 382 383 # eat up option 384 shift 385 386 # determine whether option needs an argument 387 eval "opt_MODE=\$opt_MODE_${opt_OPT}" 388 if [ ".$opt_ARG" = . ] && [ ".$opt_ARG_OK" != .yes ]; then 389 if [ ".$opt_MODE" = ".:" ] || [ ".$opt_MODE" = ".+" ]; then 390 opt_PREV="$opt_OPT" 391 continue 392 fi 393 fi 394 395 # process option 396 case $opt_MODE in 397 '.' ) 398 # boolean option 399 eval "opt_${opt_OPT}=yes" 400 ;; 401 ':' ) 402 # option with argument (multiple occurances override) 403 eval "opt_${opt_OPT}=\"\$opt_ARG\"" 404 ;; 405 '+' ) 406 # option with argument (multiple occurances append) 407 eval "opt_${opt_OPT}=\"\$opt_${opt_OPT}\${ASC_NL}\$opt_ARG\"" 408 ;; 409 * ) 410 echo "$msgprefix:Error: unknown option: \`$opt_OPT'" 1>&2 411 echo "$msgprefix:Hint: run \`$toolcmdhelp -h' or \`man shtool' for details" 1>&2 412 exit 1 413 ;; 414 esac 415done 416if [ ".$opt_PREV" != . ]; then 417 echo "$msgprefix:Error: missing argument to option \`$opt_PREV'" 1>&2 418 echo "$msgprefix:Hint: run \`$toolcmdhelp -h' or \`man shtool' for details" 1>&2 419 exit 1 420fi 421 422# process help option 423if [ ".$opt_h" = .yes ]; then 424 echo "Usage: $toolcmdhelp $str_usage" 425 exit 0 426fi 427 428# complain about incorrect number of arguments 429case $arg_MODE in 430 '=' ) 431 if [ $# -ne $arg_NUMS ]; then 432 echo "$msgprefix:Error: invalid number of arguments (exactly $arg_NUMS expected)" 1>&2 433 echo "$msgprefix:Hint: run \`$toolcmd -h' or \`man shtool' for details" 1>&2 434 exit 1 435 fi 436 ;; 437 '+' ) 438 if [ $# -lt $arg_NUMS ]; then 439 echo "$msgprefix:Error: invalid number of arguments (at least $arg_NUMS expected)" 1>&2 440 echo "$msgprefix:Hint: run \`$toolcmd -h' or \`man shtool' for details" 1>&2 441 exit 1 442 fi 443 ;; 444esac 445 446# establish a temporary file on request 447if [ ".$gen_tmpfile" = .yes ]; then 448 # create (explicitly) secure temporary directory 449 if [ ".$TMPDIR" != . ]; then 450 tmpdir="$TMPDIR" 451 elif [ ".$TEMPDIR" != . ]; then 452 tmpdir="$TEMPDIR" 453 else 454 tmpdir="/tmp" 455 fi 456 tmpdir="$tmpdir/.shtool.$$" 457 ( umask 077 458 rm -rf "$tmpdir" >/dev/null 2>&1 || true 459 mkdir "$tmpdir" >/dev/null 2>&1 460 if [ $? -ne 0 ]; then 461 echo "$msgprefix:Error: failed to create temporary directory \`$tmpdir'" 1>&2 462 exit 1 463 fi 464 ) 465 466 # create (implicitly) secure temporary file 467 tmpfile="$tmpdir/shtool.tmp" 468 touch "$tmpfile" 469fi 470 471# utility function: map string to lower case 472util_lower () { 473 echo "$1" | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' 474} 475 476# utility function: map string to upper case 477util_upper () { 478 echo "$1" | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 479} 480 481# cleanup procedure 482shtool_exit () { 483 rc="$1" 484 if [ ".$gen_tmpfile" = .yes ]; then 485 rm -rf "$tmpdir" >/dev/null 2>&1 || true 486 fi 487 exit $rc 488} 489 490## 491## DISPATCH INTO SCRIPT BODY 492## 493 494case $tool in 495 496echo ) 497 ## 498 ## echo -- Print string with optional construct expansion 499 ## Copyright (c) 1998-2006 Ralf S. Engelschall <rse@engelschall.com> 500 ## 501 502 text="$*" 503 504 # check for broken escape sequence expansion 505 seo='' 506 bytes=`echo '\1' | wc -c | awk '{ printf("%s", $1); }'` 507 if [ ".$bytes" != .3 ]; then 508 bytes=`echo -E '\1' | wc -c | awk '{ printf("%s", $1); }'` 509 if [ ".$bytes" = .3 ]; then 510 seo='-E' 511 fi 512 fi 513 514 # check for existing -n option (to suppress newline) 515 minusn='' 516 bytes=`echo -n 123 2>/dev/null | wc -c | awk '{ printf("%s", $1); }'` 517 if [ ".$bytes" = .3 ]; then 518 minusn='-n' 519 fi 520 521 # determine terminal bold sequence 522 term_bold='' 523 term_norm='' 524 if [ ".$opt_e" = .yes ] && [ ".`echo $text | grep '%[Bb]'`" != . ]; then 525 case $TERM in 526 # for the most important terminal types we directly know the sequences 527 xterm|xterm*|vt220|vt220*) 528 term_bold=`awk 'BEGIN { printf("%c%c%c%c", 27, 91, 49, 109); }' </dev/null 2>/dev/null` 529 term_norm=`awk 'BEGIN { printf("%c%c%c", 27, 91, 109); }' </dev/null 2>/dev/null` 530 ;; 531 vt100|vt100*|cygwin) 532 term_bold=`awk 'BEGIN { printf("%c%c%c%c%c%c", 27, 91, 49, 109, 0, 0); }' </dev/null 2>/dev/null` 533 term_norm=`awk 'BEGIN { printf("%c%c%c%c%c", 27, 91, 109, 0, 0); }' </dev/null 2>/dev/null` 534 ;; 535 # for all others, we try to use a possibly existing `tput' or `tcout' utility 536 * ) 537 paths=`echo $PATH | sed -e 's/:/ /g'` 538 for tool in tput tcout; do 539 for dir in $paths; do 540 if [ -r "$dir/$tool" ]; then 541 for seq in bold md smso; do # 'smso' is last 542 bold="`$dir/$tool $seq 2>/dev/null`" 543 if [ ".$bold" != . ]; then 544 term_bold="$bold" 545 break 546 fi 547 done 548 if [ ".$term_bold" != . ]; then 549 for seq in sgr0 me rmso init reset; do # 'reset' is last 550 norm="`$dir/$tool $seq 2>/dev/null`" 551 if [ ".$norm" != . ]; then 552 term_norm="$norm" 553 break 554 fi 555 done 556 fi 557 break 558 fi 559 done 560 if [ ".$term_bold" != . ] && [ ".$term_norm" != . ]; then 561 break; 562 fi 563 done 564 ;; 565 esac 566 if [ ".$term_bold" = . ] || [ ".$term_norm" = . ]; then 567 echo "$msgprefix:Warning: unable to determine terminal sequence for bold mode" 1>&2 568 term_bold='' 569 term_norm='' 570 fi 571 fi 572 573 # determine user name 574 username='' 575 if [ ".$opt_e" = .yes ] && [ ".`echo $text | grep '%[uUgG]'`" != . ]; then 576 username="`(id -un) 2>/dev/null`" 577 if [ ".$username" = . ]; then 578 str="`(id) 2>/dev/null`" 579 if [ ".`echo $str | grep '^uid[ ]*=[ ]*[0-9]*('`" != . ]; then 580 username=`echo $str | sed -e 's/^uid[ ]*=[ ]*[0-9]*(//' -e 's/).*$//'` 581 fi 582 if [ ".$username" = . ]; then 583 username="$LOGNAME" 584 if [ ".$username" = . ]; then 585 username="$USER" 586 if [ ".$username" = . ]; then 587 username="`(whoami) 2>/dev/null |\ 588 awk '{ printf("%s", $1); }'`" 589 if [ ".$username" = . ]; then 590 username="`(who am i) 2>/dev/null |\ 591 awk '{ printf("%s", $1); }'`" 592 if [ ".$username" = . ]; then 593 username='unknown' 594 fi 595 fi 596 fi 597 fi 598 fi 599 fi 600 fi 601 602 # determine user id 603 userid='' 604 if [ ".$opt_e" = .yes ] && [ ".`echo $text | grep '%U'`" != . ]; then 605 userid="`(id -u) 2>/dev/null`" 606 if [ ".$userid" = . ]; then 607 userid="`(id -u ${username}) 2>/dev/null`" 608 if [ ".$userid" = . ]; then 609 str="`(id) 2>/dev/null`" 610 if [ ".`echo $str | grep '^uid[ ]*=[ ]*[0-9]*('`" != . ]; then 611 userid=`echo $str | sed -e 's/^uid[ ]*=[ ]*//' -e 's/(.*$//'` 612 fi 613 if [ ".$userid" = . ]; then 614 userid=`(getent passwd ${username}) 2>/dev/null | \ 615 sed -e 's/[^:]*:[^:]*://' -e 's/:.*$//'` 616 if [ ".$userid" = . ]; then 617 userid=`grep "^${username}:" /etc/passwd 2>/dev/null | \ 618 sed -e 's/[^:]*:[^:]*://' -e 's/:.*$//'` 619 if [ ".$userid" = . ]; then 620 userid=`(ypcat passwd) 2>/dev/null | 621 grep "^${username}:" | \ 622 sed -e 's/[^:]*:[^:]*://' -e 's/:.*$//'` 623 if [ ".$userid" = . ]; then 624 userid='?' 625 fi 626 fi 627 fi 628 fi 629 fi 630 fi 631 fi 632 633 # determine (primary) group id 634 groupid='' 635 if [ ".$opt_e" = .yes ] && [ ".`echo $text | grep '%[gG]'`" != . ]; then 636 groupid="`(id -g ${username}) 2>/dev/null`" 637 if [ ".$groupid" = . ]; then 638 str="`(id) 2>/dev/null`" 639 if [ ".`echo $str | grep 'gid[ ]*=[ ]*[0-9]*('`" != . ]; then 640 groupid=`echo $str | sed -e 's/^.*gid[ ]*=[ ]*//' -e 's/(.*$//'` 641 fi 642 if [ ".$groupid" = . ]; then 643 groupid=`(getent passwd ${username}) 2>/dev/null | \ 644 sed -e 's/[^:]*:[^:]*:[^:]*://' -e 's/:.*$//'` 645 if [ ".$groupid" = . ]; then 646 groupid=`grep "^${username}:" /etc/passwd 2>/dev/null | \ 647 sed -e 's/[^:]*:[^:]*:[^:]*://' -e 's/:.*$//'` 648 if [ ".$groupid" = . ]; then 649 groupid=`(ypcat passwd) 2>/dev/null | grep "^${username}:" | \ 650 sed -e 's/[^:]*:[^:]*:[^:]*://' -e 's/:.*$//'` 651 if [ ".$groupid" = . ]; then 652 groupid='?' 653 fi 654 fi 655 fi 656 fi 657 fi 658 fi 659 660 # determine (primary) group name 661 groupname='' 662 if [ ".$opt_e" = .yes ] && [ ".`echo $text | grep '%g'`" != . ]; then 663 groupname="`(id -gn ${username}) 2>/dev/null`" 664 if [ ".$groupname" = . ]; then 665 str="`(id) 2>/dev/null`" 666 if [ ".`echo $str | grep 'gid[ ]*=[ ]*[0-9]*('`" != . ]; then 667 groupname=`echo $str | sed -e 's/^.*gid[ ]*=[ ]*[0-9]*(//' -e 's/).*$//'` 668 fi 669 if [ ".$groupname" = . ]; then 670 groupname=`(getent group) 2>/dev/null | \ 671 grep "^[^:]*:[^:]*:${groupid}:" | \ 672 sed -e 's/:.*$//'` 673 if [ ".$groupname" = . ]; then 674 groupname=`grep "^[^:]*:[^:]*:${groupid}:" /etc/group 2>/dev/null | \ 675 sed -e 's/:.*$//'` 676 if [ ".$groupname" = . ]; then 677 groupname=`(ypcat group) 2>/dev/null | \ 678 grep "^[^:]*:[^:]*:${groupid}:" | \ 679 sed -e 's/:.*$//'` 680 if [ ".$groupname" = . ]; then 681 groupname='?' 682 fi 683 fi 684 fi 685 fi 686 fi 687 fi 688 689 # determine host and domain name 690 hostname='' 691 domainname='' 692 if [ ".$opt_e" = .yes ] && [ ".`echo $text | grep '%h'`" != . ]; then 693 hostname="`(uname -n) 2>/dev/null |\ 694 awk '{ printf("%s", $1); }'`" 695 if [ ".$hostname" = . ]; then 696 hostname="`(hostname) 2>/dev/null |\ 697 awk '{ printf("%s", $1); }'`" 698 if [ ".$hostname" = . ]; then 699 hostname='unknown' 700 fi 701 fi 702 case $hostname in 703 *.* ) 704 domainname=".`echo $hostname | cut -d. -f2-`" 705 hostname="`echo $hostname | cut -d. -f1`" 706 ;; 707 esac 708 fi 709 if [ ".$opt_e" = .yes ] && [ ".`echo $text | grep '%d'`" != . ]; then 710 if [ ".$domainname" = . ]; then 711 if [ -f /etc/resolv.conf ]; then 712 domainname="`grep '^[ ]*domain' /etc/resolv.conf | sed -e 'q' |\ 713 sed -e 's/.*domain//' \ 714 -e 's/^[ ]*//' -e 's/^ *//' -e 's/^ *//' \ 715 -e 's/^\.//' -e 's/^/./' |\ 716 awk '{ printf("%s", $1); }'`" 717 if [ ".$domainname" = . ]; then 718 domainname="`grep '^[ ]*search' /etc/resolv.conf | sed -e 'q' |\ 719 sed -e 's/.*search//' \ 720 -e 's/^[ ]*//' -e 's/^ *//' -e 's/^ *//' \ 721 -e 's/ .*//' -e 's/ .*//' \ 722 -e 's/^\.//' -e 's/^/./' |\ 723 awk '{ printf("%s", $1); }'`" 724 fi 725 fi 726 fi 727 fi 728 729 # determine current time 730 time_day='' 731 time_month='' 732 time_year='' 733 time_monthname='' 734 if [ ".$opt_e" = .yes ] && [ ".`echo $text | grep '%[DMYm]'`" != . ]; then 735 time_day=`date '+%d'` 736 time_month=`date '+%m'` 737 time_year=`date '+%Y' 2>/dev/null` 738 if [ ".$time_year" = . ]; then 739 time_year=`date '+%y'` 740 case $time_year in 741 [5-9][0-9]) time_year="19$time_year" ;; 742 [0-4][0-9]) time_year="20$time_year" ;; 743 esac 744 fi 745 case $time_month in 746 1|01) time_monthname='Jan' ;; 747 2|02) time_monthname='Feb' ;; 748 3|03) time_monthname='Mar' ;; 749 4|04) time_monthname='Apr' ;; 750 5|05) time_monthname='May' ;; 751 6|06) time_monthname='Jun' ;; 752 7|07) time_monthname='Jul' ;; 753 8|08) time_monthname='Aug' ;; 754 9|09) time_monthname='Sep' ;; 755 10) time_monthname='Oct' ;; 756 11) time_monthname='Nov' ;; 757 12) time_monthname='Dec' ;; 758 esac 759 fi 760 761 # expand special ``%x'' constructs 762 if [ ".$opt_e" = .yes ]; then 763 text=`echo $seo "$text" |\ 764 sed -e "s/%B/${term_bold}/g" \ 765 -e "s/%b/${term_norm}/g" \ 766 -e "s/%u/${username}/g" \ 767 -e "s/%U/${userid}/g" \ 768 -e "s/%g/${groupname}/g" \ 769 -e "s/%G/${groupid}/g" \ 770 -e "s/%h/${hostname}/g" \ 771 -e "s/%d/${domainname}/g" \ 772 -e "s/%D/${time_day}/g" \ 773 -e "s/%M/${time_month}/g" \ 774 -e "s/%Y/${time_year}/g" \ 775 -e "s/%m/${time_monthname}/g" 2>/dev/null` 776 fi 777 778 # create output 779 if [ .$opt_n = .no ]; then 780 echo $seo "$text" 781 else 782 # the harder part: echo -n is best, because 783 # awk may complain about some \xx sequences. 784 if [ ".$minusn" != . ]; then 785 echo $seo $minusn "$text" 786 else 787 echo dummy | awk '{ printf("%s", TEXT); }' TEXT="$text" 788 fi 789 fi 790 791 shtool_exit 0 792 ;; 793 794install ) 795 ## 796 ## install -- Install a program, script or datafile 797 ## Copyright (c) 1997-2006 Ralf S. Engelschall <rse@engelschall.com> 798 ## 799 800 # special case: "shtool install -d <dir> [...]" internally 801 # maps to "shtool mkdir -f -p -m 755 <dir> [...]" 802 if [ "$opt_d" = yes ]; then 803 cmd="$0 mkdir -f -p -m 755" 804 if [ ".$opt_o" != . ]; then 805 cmd="$cmd -o '$opt_o'" 806 fi 807 if [ ".$opt_g" != . ]; then 808 cmd="$cmd -g '$opt_g'" 809 fi 810 if [ ".$opt_v" = .yes ]; then 811 cmd="$cmd -v" 812 fi 813 if [ ".$opt_t" = .yes ]; then 814 cmd="$cmd -t" 815 fi 816 for dir in "$@"; do 817 eval "$cmd $dir" || shtool_exit $? 818 done 819 shtool_exit 0 820 fi 821 822 # determine source(s) and destination 823 argc=$# 824 srcs="" 825 while [ $# -gt 1 ]; do 826 srcs="$srcs $1" 827 shift 828 done 829 dstpath="$1" 830 831 # type check for destination 832 dstisdir=0 833 if [ -d $dstpath ]; then 834 dstpath=`echo "$dstpath" | sed -e 's:/$::'` 835 dstisdir=1 836 fi 837 838 # consistency check for destination 839 if [ $argc -gt 2 ] && [ $dstisdir = 0 ]; then 840 echo "$msgprefix:Error: multiple sources require destination to be directory" 1>&2 841 shtool_exit 1 842 fi 843 844 # iterate over all source(s) 845 for src in $srcs; do 846 dst=$dstpath 847 848 # if destination is a directory, append the input filename 849 if [ $dstisdir = 1 ]; then 850 dstfile=`echo "$src" | sed -e 's;.*/\([^/]*\)$;\1;'` 851 dst="$dst/$dstfile" 852 fi 853 854 # check for correct arguments 855 if [ ".$src" = ".$dst" ]; then 856 echo "$msgprefix:Warning: source and destination are the same - skipped" 1>&2 857 continue 858 fi 859 if [ -d "$src" ]; then 860 echo "$msgprefix:Warning: source \`$src' is a directory - skipped" 1>&2 861 continue 862 fi 863 864 # make a temp file name in the destination directory 865 dsttmp=`echo $dst |\ 866 sed -e 's;[^/]*$;;' -e 's;\(.\)/$;\1;' -e 's;^$;.;' \ 867 -e "s;\$;/#INST@$$#;"` 868 869 # verbosity 870 if [ ".$opt_v" = .yes ]; then 871 echo "$src -> $dst" 1>&2 872 fi 873 874 # copy or move the file name to the temp name 875 # (because we might be not allowed to change the source) 876 if [ ".$opt_C" = .yes ]; then 877 opt_c=yes 878 fi 879 if [ ".$opt_c" = .yes ]; then 880 if [ ".$opt_t" = .yes ]; then 881 echo "cp $src $dsttmp" 1>&2 882 fi 883 cp $src $dsttmp || shtool_exit $? 884 else 885 if [ ".$opt_t" = .yes ]; then 886 echo "mv $src $dsttmp" 1>&2 887 fi 888 mv $src $dsttmp || shtool_exit $? 889 fi 890 891 # adjust the target file 892 if [ ".$opt_e" != . ]; then 893 sed='sed' 894 OIFS="$IFS"; IFS="$ASC_NL"; set -- $opt_e; IFS="$OIFS" 895 for e 896 do 897 sed="$sed -e '$e'" 898 done 899 cp $dsttmp $dsttmp.old 900 chmod u+w $dsttmp 901 eval "$sed <$dsttmp.old >$dsttmp" || shtool_exit $? 902 rm -f $dsttmp.old 903 fi 904 if [ ".$opt_s" = .yes ]; then 905 if [ ".$opt_t" = .yes ]; then 906 echo "strip $dsttmp" 1>&2 907 fi 908 strip $dsttmp || shtool_exit $? 909 fi 910 if [ ".$opt_o" != . ]; then 911 if [ ".$opt_t" = .yes ]; then 912 echo "chown $opt_o $dsttmp" 1>&2 913 fi 914 chown $opt_o $dsttmp || shtool_exit $? 915 fi 916 if [ ".$opt_g" != . ]; then 917 if [ ".$opt_t" = .yes ]; then 918 echo "chgrp $opt_g $dsttmp" 1>&2 919 fi 920 chgrp $opt_g $dsttmp || shtool_exit $? 921 fi 922 if [ ".$opt_m" != ".-" ]; then 923 if [ ".$opt_t" = .yes ]; then 924 echo "chmod $opt_m $dsttmp" 1>&2 925 fi 926 chmod $opt_m $dsttmp || shtool_exit $? 927 fi 928 929 # determine whether to do a quick install 930 # (has to be done _after_ the strip was already done) 931 quick=no 932 if [ ".$opt_C" = .yes ]; then 933 if [ -r $dst ]; then 934 if cmp -s $src $dst; then 935 quick=yes 936 fi 937 fi 938 fi 939 940 # finally, install the file to the real destination 941 if [ $quick = yes ]; then 942 if [ ".$opt_t" = .yes ]; then 943 echo "rm -f $dsttmp" 1>&2 944 fi 945 rm -f $dsttmp 946 else 947 if [ ".$opt_t" = .yes ]; then 948 echo "rm -f $dst && mv $dsttmp $dst" 1>&2 949 fi 950 rm -f $dst && mv $dsttmp $dst 951 fi 952 done 953 954 shtool_exit 0 955 ;; 956 957mkdir ) 958 ## 959 ## mkdir -- Make one or more directories 960 ## Copyright (c) 1996-2006 Ralf S. Engelschall <rse@engelschall.com> 961 ## 962 963 errstatus=0 964 for p in ${1+"$@"}; do 965 # if the directory already exists... 966 if [ -d "$p" ]; then 967 if [ ".$opt_f" = .no ] && [ ".$opt_p" = .no ]; then 968 echo "$msgprefix:Error: directory already exists: $p" 1>&2 969 errstatus=1 970 break 971 else 972 continue 973 fi 974 fi 975 # if the directory has to be created... 976 if [ ".$opt_p" = .no ]; then 977 if [ ".$opt_t" = .yes ]; then 978 echo "mkdir $p" 1>&2 979 fi 980 mkdir $p || errstatus=$? 981 if [ ".$opt_o" != . ]; then 982 if [ ".$opt_t" = .yes ]; then 983 echo "chown $opt_o $p" 1>&2 984 fi 985 chown $opt_o $p || errstatus=$? 986 fi 987 if [ ".$opt_g" != . ]; then 988 if [ ".$opt_t" = .yes ]; then 989 echo "chgrp $opt_g $p" 1>&2 990 fi 991 chgrp $opt_g $p || errstatus=$? 992 fi 993 if [ ".$opt_m" != . ]; then 994 if [ ".$opt_t" = .yes ]; then 995 echo "chmod $opt_m $p" 1>&2 996 fi 997 chmod $opt_m $p || errstatus=$? 998 fi 999 else 1000 # the smart situation 1001 set fnord `echo ":$p" |\ 1002 sed -e 's/^:\//%/' \ 1003 -e 's/^://' \ 1004 -e 's/\// /g' \ 1005 -e 's/^%/\//'` 1006 shift 1007 pathcomp='' 1008 for d in ${1+"$@"}; do 1009 pathcomp="$pathcomp$d" 1010 case "$pathcomp" in 1011 -* ) pathcomp="./$pathcomp" ;; 1012 esac 1013 if [ ! -d "$pathcomp" ]; then 1014 if [ ".$opt_t" = .yes ]; then 1015 echo "mkdir $pathcomp" 1>&2 1016 fi 1017 mkdir $pathcomp || errstatus=$? 1018 if [ ".$opt_o" != . ]; then 1019 if [ ".$opt_t" = .yes ]; then 1020 echo "chown $opt_o $pathcomp" 1>&2 1021 fi 1022 chown $opt_o $pathcomp || errstatus=$? 1023 fi 1024 if [ ".$opt_g" != . ]; then 1025 if [ ".$opt_t" = .yes ]; then 1026 echo "chgrp $opt_g $pathcomp" 1>&2 1027 fi 1028 chgrp $opt_g $pathcomp || errstatus=$? 1029 fi 1030 if [ ".$opt_m" != . ]; then 1031 if [ ".$opt_t" = .yes ]; then 1032 echo "chmod $opt_m $pathcomp" 1>&2 1033 fi 1034 chmod $opt_m $pathcomp || errstatus=$? 1035 fi 1036 fi 1037 pathcomp="$pathcomp/" 1038 done 1039 fi 1040 done 1041 1042 shtool_exit $errstatus 1043 ;; 1044 1045fixperm ) 1046 ## 1047 ## fixperm -- Fix file permissions inside a source tree 1048 ## Copyright (c) 1996-2006 Ralf S. Engelschall <rse@engelschall.com> 1049 ## 1050 1051 paths="$*" 1052 1053 # check whether the test command supports the -x option 1054 if [ -x /bin/sh ] 2>/dev/null; then 1055 minusx="-x" 1056 else 1057 minusx="-r" 1058 fi 1059 1060 # iterate over paths 1061 for p in $paths; do 1062 for file in `find $p -depth -print`; do 1063 if [ -f $file ]; then 1064 if [ $minusx $file ]; then 1065 if [ ".$opt_v" = .yes ]; then 1066 echo "-rwxr-xr-x $file" 2>&1 1067 fi 1068 if [ ".$opt_t" = .yes ]; then 1069 echo "chmod 755 $file" 2>&1 1070 fi 1071 chmod 755 $file 1072 else 1073 if [ ".$opt_v" = .yes ]; then 1074 echo "-rw-r--r-- $file" 2>&1 1075 fi 1076 if [ ".$opt_t" = .yes ]; then 1077 echo "chmod 644 $file" 2>&1 1078 fi 1079 chmod 644 $file 1080 fi 1081 continue 1082 fi 1083 if [ -d $file ]; then 1084 if [ ".$opt_v" = .yes ]; then 1085 echo "drwxr-xr-x $file" 2>&1 1086 fi 1087 if [ ".$opt_t" = .yes ]; then 1088 echo "chmod 755 $file" 2>&1 1089 fi 1090 chmod 755 $file 1091 continue 1092 fi 1093 if [ ".$opt_v" = .yes ]; then 1094 echo "?????????? $file" 2>&1 1095 fi 1096 done 1097 done 1098 1099 shtool_exit 0 1100 ;; 1101 1102tarball ) 1103 ## 1104 ## tarball -- Roll distribution tarballs 1105 ## Copyright (c) 1999-2006 Ralf S. Engelschall <rse@engelschall.com> 1106 ## 1107 1108 srcs="$*" 1109 1110 # check whether the test command supports the -x option 1111 if [ -x /bin/sh ] 2>/dev/null; then 1112 minusx="-x" 1113 else 1114 minusx="-r" 1115 fi 1116 1117 # find the tools 1118 paths="`echo $PATH |\ 1119 sed -e 's%/*:%:%g' -e 's%/*$%%' \ 1120 -e 's/^:/.:/' -e 's/::/:.:/g' -e 's/:$/:./' \ 1121 -e 's/:/ /g'`" 1122 for spec in find:gfind,find tar:gtar,tar tardy:tardy,tarcust; do 1123 prg=`echo $spec | sed -e 's/:.*$//'` 1124 tools=`echo $spec | sed -e 's/^.*://'` 1125 eval "prg_${prg}=''" 1126 # iterate over tools 1127 for tool in `echo $tools | sed -e 's/,/ /g'`; do 1128 # iterate over paths 1129 for path in $paths; do 1130 if [ $minusx "$path/$tool" ] && [ ! -d "$path/$tool" ]; then 1131 eval "prg_${prg}=\"$path/$tool\"" 1132 break 1133 fi 1134 done 1135 eval "val=\$prg_${prg}" 1136 if [ ".$val" != . ]; then 1137 break 1138 fi 1139 done 1140 done 1141 1142 # expand source paths 1143 exclude='' 1144 for pat in `echo $opt_e | sed 's/,/ /g'`; do 1145 exclude="$exclude | grep -v '$pat'" 1146 done 1147 if [ ".$opt_t" = .yes ]; then 1148 echo "cp /dev/null $tmpfile.lst" 1>&2 1149 fi 1150 cp /dev/null $tmpfile.lst 1151 for src in $srcs; do 1152 if [ -d $src ]; then 1153 if [ ".$opt_t" = .yes ]; then 1154 echo "(cd $src && $prg_find . -type f -depth -print) | sed -e 's:^\\.\$::' -e 's:^\\./::' | cat $exclude >>$tmpfile.lst" 1>&2 1155 fi 1156 (cd $src && $prg_find . -type f -depth -print) |\ 1157 sed -e 's:^\.$::' -e 's:^\./::' | eval cat $exclude >>$tmpfile.lst 1158 else 1159 if [ ".$opt_t" = .yes ]; then 1160 echo "echo $src >>$tmpfile.lst" 1>&2 1161 fi 1162 echo $src >>$tmpfile.lst 1163 fi 1164 done 1165 sort <$tmpfile.lst >$tmpfile.lst.n 1166 mv $tmpfile.lst.n $tmpfile.lst 1167 if [ ".$opt_v" = .yes ]; then 1168 cat $tmpfile.lst | sed -e 's/^/ /' 1>&2 1169 fi 1170 1171 # determine tarball file and directory name 1172 if [ ".$opt_o" != . ]; then 1173 tarfile="$opt_o" 1174 if [ ".$opt_d" != . ]; then 1175 tarname="$opt_d" 1176 else 1177 tarname=`echo $tarfile | sed -e 's/\.tar.*$//' -e 's;.*/\([^/]*\)$;\1;'` 1178 fi 1179 else 1180 if [ ".$opt_d" != . ]; then 1181 tarname="$opt_d" 1182 elif [ -d "$from" ]; then 1183 tarname=`echo $from | sed -e 's;.*/\([^/]*\)$;\1;'` 1184 else 1185 tarname="out" 1186 fi 1187 tarfile="$tarname.tar" 1188 fi 1189 1190 # roll the tarball 1191 compress='' 1192 if [ ".$opt_c" != . ]; then 1193 compress="| $opt_c" 1194 fi 1195 if [ ".$prg_tardy" != . ]; then 1196 # the elegant hackers way 1197 tardy_opt="--prefix=$tarname" 1198 tardy_opt="$tardy_opt --user_number=0 --group_number=0" # security! 1199 if [ ".$opt_u" != . ]; then 1200 tardy_opt="$tardy_opt --user_name=$opt_u" 1201 fi 1202 if [ ".$opt_g" != . ]; then 1203 tardy_opt="$tardy_opt --group_name=$opt_g" 1204 fi 1205 if [ ".$opt_t" = .yes ]; then 1206 echo "cat $tmpfile.lst | xargs $prg_tar cf - | $prg_tardy $tardy_opt | cat $compress >$tmpfile.out" 1>&2 1207 fi 1208 cat $tmpfile.lst |\ 1209 xargs $prg_tar cf - |\ 1210 $prg_tardy $tardy_opt |\ 1211 eval cat $compress >$tmpfile.out 1212 if [ ".$opt_t" = .yes ]; then 1213 echo "cp $tmpfile.out $tarfile" 1>&2 1214 fi 1215 cp $tmpfile.out $tarfile 1216 else 1217 # the portable standard way 1218 if [ ".$opt_t" = .yes ]; then 1219 echo "mkdir $tmpdir/$tarname" 1>&2 1220 fi 1221 mkdir $tmpdir/$tarname || shtool_exit 1 1222 if [ ".$opt_t" = .yes ]; then 1223 echo "cat $tmpfile.lst | xargs $prg_tar cf - | (cd $tmpdir/$tarname && $prg_tar xf -)" 1>&2 1224 fi 1225 cat $tmpfile.lst |\ 1226 xargs $prg_tar cf - |\ 1227 (cd $tmpdir/$tarname && $prg_tar xf -) 1228 if [ ".$opt_u" != . ]; then 1229 if [ ".$opt_t" = .yes ]; then 1230 echo "chown -R $opt_u $tmpdir/$tarname >/dev/null 2>&1" 2>&1 1231 fi 1232 chown -R $opt_u $tmpdir/$tarname >/dev/null 2>&1 ||\ 1233 echo "$msgprefix:Warning: cannot set user name \`$opt_u' (would require root privileges)" 1234 fi 1235 if [ ".$opt_g" != . ]; then 1236 if [ ".$opt_t" = .yes ]; then 1237 echo "chgrp -R $opt_g $tmpdir/$tarname >/dev/null 2>&1" 2>&1 1238 fi 1239 chgrp -R $opt_g $tmpdir/$tarname >/dev/null 2>&1 ||\ 1240 echo "$msgprefix:Warning: cannot set group name \`$opt_g' (would require root privileges)" 1241 fi 1242 if [ ".$opt_t" = .yes ]; then 1243 echo "(cd $tmpdir && $prg_find $tarname -type f -depth -print | sort | xargs $prg_tar cf -) | cat $compress >$tmpfile.out" 1>&2 1244 fi 1245 (cd $tmpdir && $prg_find $tarname -type f -depth -print | sort | xargs $prg_tar cf -) |\ 1246 eval cat $compress >$tmpfile.out 1247 if [ ".$opt_t" = .yes ]; then 1248 echo "cp $tmpfile.out $tarfile" 1>&2 1249 fi 1250 cp $tmpfile.out $tarfile 1251 if [ ".$opt_t" = .yes ]; then 1252 echo "rm -rf $tmpdir/$tarname" 1>&2 1253 fi 1254 rm -rf $tmpdir/$tarname 1255 fi 1256 1257 # cleanup 1258 if [ ".$opt_t" = .yes ]; then 1259 echo "rm -f $tmpfile.lst $tmpfile.out" 1>&2 1260 fi 1261 rm -f $tmpfile.lst $tmpfile.out 1262 1263 shtool_exit 0 1264 ;; 1265 1266scpp ) 1267 ## 1268 ## scpp -- Sharing C Pre-Processor 1269 ## Copyright (c) 1999-2006 Ralf S. Engelschall <rse@engelschall.com> 1270 ## 1271 1272 srcs="$*" 1273 output="${opt_o}.n" 1274 1275 # find a reasonable Awk 1276 awk='' 1277 paths=`echo $PATH |\ 1278 sed -e 's%/*:%:%g' -e 's%/$%%' \ 1279 -e 's/^:/.:/' -e 's/::/:.:/g' -e 's/:$/:./' \ 1280 -e 's/:/ /g'` 1281 for name in gawk nawk awk; do 1282 for path in $paths; do 1283 if [ -r "$path/$name" ]; then 1284 awk="$path/$name" 1285 break 1286 fi 1287 done 1288 if [ ".$awk" != . ]; then 1289 break 1290 fi 1291 done 1292 if [ ".$awk" = . ]; then 1293 echo "$msgprefix:Error: cannot find a reasonable Awk" 1>&2 1294 shtool_exit 1 1295 fi 1296 1297 # parse source file(s) 1298 if [ ".$opt_v" = .yes ]; then 1299 echo "Parsing:" | $awk '{ printf("%s", $0); }' 1>&2 1300 fi 1301 for src in $srcs; do 1302 if [ ".$opt_v" = .yes ]; then 1303 echo $src | $awk '{ printf(" %s", $0); }' 1>&2 1304 fi 1305 if [ ".$opt_f" != . ]; then 1306 inputcmd="sed" 1307 OIFS="$IFS"; IFS="$ASC_NL"; set -- $opt_f; IFS="$OIFS" 1308 for e 1309 do 1310 inputcmd="$inputcmd -e '$e'" 1311 done 1312 inputcmd="$inputcmd '$src'" 1313 else 1314 inputcmd="cat '$src'" 1315 fi 1316 eval $inputcmd |\ 1317 $awk ' 1318 BEGIN { 1319 ln = 0; 1320 fln = 0; 1321 level = 0; 1322 mode = ""; 1323 store = ""; 1324 } 1325 { 1326 ln++; 1327 } 1328 /^#if.*/ { 1329 level++; 1330 } 1331 /^#if [a-zA-Z_][a-zA-Z0-9_]* *$/ { 1332 if ($2 == define) { 1333 mode = "D"; 1334 printf("D:#line %d \"%s\"\n", ln, src); 1335 next; 1336 } 1337 } 1338 /^#endif.*/ { 1339 level--; 1340 if (mode == "D" && level == 0) { 1341 mode = ""; 1342 next; 1343 } 1344 } 1345 /^[a-zA-Z_][a-zA-Z0-9_].*;.*/ { 1346 if ($1 == class) { 1347 printf("V:#line %d \"%s\"\n", ln, src); 1348 printf("V:%s\n", $0); 1349 printf("J:%s\n", $0); 1350 next; 1351 } 1352 } 1353 /^[a-zA-Z_][a-zA-Z0-9_].*=.*/ { 1354 if ($1 == class) { 1355 printf("V:#line %d \"%s\"\n", ln, src); 1356 printf("V:%s\n", $0); 1357 printf("J:%s\n", $0); 1358 next; 1359 } 1360 } 1361 /^[a-zA-Z_][a-zA-Z0-9_]*/ { 1362 if ($1 == class) { 1363 fln = ln; 1364 store = $0; 1365 mode = "F"; 1366 next; 1367 } 1368 } 1369 /^\{ *$/ { 1370 if (mode == "F") { 1371 printf("F:#line %d \"%s\"\n", fln, src); 1372 printf("F:%s;\n", store); 1373 printf("I:%s;\n", store); 1374 store = ""; 1375 mode = ""; 1376 next; 1377 } 1378 } 1379 { 1380 if (mode == "D") 1381 printf("D:%s\n", $0); 1382 else if (mode == "F") 1383 store = store " " $0; 1384 } 1385 ' "src=$src" "define=$opt_D" "class=$opt_C" >>$tmpfile 1386 done 1387 if [ ".$opt_v" = .yes ]; then 1388 echo "" 1>&2 1389 fi 1390 1391 # start generating output header 1392 echo "/* $opt_o -- autogenerated from $opt_t, DO NOT EDIT! */" >$output 1393 echo "#line 1 \"$opt_t\"" >>$output 1394 sed <$opt_t -e "1,/^${opt_M} *\$/p" -e 'd' |\ 1395 sed -e "/^${opt_M} *\$/d" >>$output 1396 1397 # merge in the define blocks 1398 grep '^D:' $tmpfile | sed -e 's/^D://' >>$output 1399 1400 # generate standard prolog 1401 echo "#line 1 \"_ON_THE_FLY_\"" >>$output 1402 echo "" >>$output 1403 echo "/* make sure the scpp source extensions are skipped */" >>$output 1404 echo "#define $opt_D 0" >>$output 1405 echo "#define $opt_C /**/" >>$output 1406 1407 # generate namespace hiding for variables 1408 echo "" >>$output 1409 echo "/* move intern variables to hidden namespace */" >>$output 1410 grep '^J:' $tmpfile | sed >>$output \ 1411 -e 's/^J://' \ 1412 -e 's/ */ /g' \ 1413 -e 's/^[^=;]*[ *]\([a-zA-Z0-9_]*\)\[\];.*$/#define \1 __\1/' \ 1414 -e 's/^[^=;]*[ *]\([a-zA-Z0-9_]*\)\[\] =.*$/#define \1 __\1/' \ 1415 -e 's/^[^=;]*[ *]\([a-zA-Z0-9_]*\);.*$/#define \1 __\1/' \ 1416 -e 's/^[^=;]*[ *]\([a-zA-Z0-9_]*\) =.*$/#define \1 __\1/' 1417 1418 # generate namespace hiding for functions 1419 echo "" >>$output 1420 echo "/* move intern functions to hidden namespace */" >>$output 1421 grep '^I:' $tmpfile | sed >>$output \ 1422 -e 's/^I://' \ 1423 -e 's/\([ (]\) */\1/g' \ 1424 -e 's/ *\([),]\)/\1/g' \ 1425 -e 's/^[^(]*[ *]\([a-zA-Z0-9_]*\)(.*$/#define \1 __\1/' 1426 1427 # generate prototypes for variables 1428 echo "" >>$output 1429 echo "/* prototypes for intern variables */" >>$output 1430 grep '^V:' $tmpfile | sed >>$output \ 1431 -e 's/^V://' \ 1432 -e 's/ */ /g' \ 1433 -e 's/^\([^=;]*[ *][a-zA-Z0-9_]*\[\]\);.*$/\1;/' \ 1434 -e 's/^\([^=;]*[ *][a-zA-Z0-9_]*\[\]\) =.*$/\1;/' \ 1435 -e 's/^\([^=;]*[ *][a-zA-Z0-9_]*\);.*$/\1;/' \ 1436 -e 's/^\([^=;]*[ *][a-zA-Z0-9_]*\) =.*$/\1;/' \ 1437 -e 's/ ;/;/g' \ 1438 -e "s/^$opt_C /extern /" 1439 1440 # generate prototypes for functions 1441 echo "" >>$output 1442 echo "/* prototypes for intern functions */" >>$output 1443 grep '^F:' $tmpfile | sed >>$output \ 1444 -e 's/^F://' \ 1445 -e 's/\([ (]\) */\1/g' \ 1446 -e 's/ *\([),]\)/\1/g' \ 1447 -e 's/\([* ]\)[a-zA-Z0-9_]*,/\1,/g' \ 1448 -e 's/\([* ]\)[a-zA-Z0-9_]*);/\1);/g' \ 1449 -e 's/(\*[a-zA-Z0-9_]*)(/(*)(/g' \ 1450 -e 's/\([ (]\) */\1/g' \ 1451 -e 's/ *\([),]\)/\1/g' \ 1452 -e "s/^$opt_C /extern /" 1453 1454 # finish generating output header 1455 n=`(echo ''; sed <$opt_t -e "1,/^${opt_M} *\$/p" -e 'd') |\ 1456 wc -l | sed -e 's;^ *\([0-9]*\) *$;\1;'` 1457 echo "#line $n \"$opt_t\"" >>$output 1458 sed <$opt_t -e "/^${opt_M} *\$/,\$p" -e 'd' |\ 1459 sed -e "/^${opt_M} *\$/d" >>$output 1460 1461 # create final output file 1462 if [ -f $opt_o ]; then 1463 if [ ".$opt_p" = .yes ]; then 1464 grep -v '^#line' $opt_o >$tmpfile.o 1465 grep -v '^#line' $output >$tmpfile.n 1466 out_old="$tmpfile.o" 1467 out_new="$tmpfile.n" 1468 else 1469 out_old="$opt_o" 1470 out_new="$output" 1471 fi 1472 if cmp -s $out_old $out_new; then 1473 : 1474 else 1475 cp $output $opt_o 1476 fi 1477 else 1478 cp $output $opt_o 1479 fi 1480 rm -f $output 1481 rm -f $tmpfile $tmpfile.* >/dev/null 2>&1 1482 1483 shtool_exit 0 1484 ;; 1485 1486version ) 1487 ## 1488 ## version -- Maintain a version information file 1489 ## Copyright (c) 1994-2006 Ralf S. Engelschall <rse@engelschall.com> 1490 ## 1491 1492 file="$1" 1493 1494 # determine prefix and name 1495 name="$opt_n" 1496 prefix="$opt_p" 1497 1498 # determine current version 1499 triple="$opt_s" 1500 if [ ".$triple" != . ]; then 1501 # use given triple 1502 if [ ".`echo $triple | grep '[0-9]*.[0-9]*[sabp.][0-9]*'`" = . ]; then 1503 echo "$msgprefix:Error: invalid argument to option \`-s': \`$opt_s'" 1>&2 1504 shtool_exit 1 1505 fi 1506 eval `echo $triple |\ 1507 sed -e 's%\([0-9]*\)\.\([0-9]*\)\([sabp.]\)\([0-9]*\).*%\ 1508 ver="\1";rev="\2";typ="\3";lev="\4"%'` 1509 tim=calc 1510 elif [ -r $file ]; then 1511 # determine triple from given file 1512 eval `grep 'Version [0-9]*.[0-9]*[sabp.][0-9]* ([0-9]*-[a-zA-Z]*-[0-9]*)' $file |\ 1513 sed -e 's%.*Version \([0-9]*\)\.\([0-9]*\)\([sabp.]\)\([0-9]*\) (\([0-9]*-[a-zA-Z]*-[0-9]*\)).*%\ 1514 ver="\1";rev="\2";typ="\3";lev="\4";tim="\5"%' -e 'q'` 1515 else 1516 # intialise to first version 1517 ver=0 1518 rev=1 1519 typ=. 1520 lev=0 1521 tim=calc 1522 fi 1523 1524 # determine new version in batch 1525 if [ ".$opt_i" != . ]; then 1526 case $opt_i in 1527 v ) ver=`expr $ver + 1` 1528 rev=0 1529 lev=0 1530 ;; 1531 r ) rev=`expr $rev + 1` 1532 lev=0 1533 ;; 1534 l ) lev=`expr $lev + 1` 1535 ;; 1536 * ) echo "$msgprefix:Error: invalid argument to option \`-i': \`$opt_i'" 1>&2 1537 shtool_exit 1 1538 ;; 1539 esac 1540 tim=calc 1541 fi 1542 1543 # determine new version interactively 1544 if [ ".$opt_e" = .yes ]; then 1545 echo "old version: ${ver}.${rev}${typ}${lev}" 1546 while [ 1 ]; do 1547 echo dummy | awk '{ printf("new version: "); }' 1548 read triple 1549 case $triple in 1550 [0-9]*.[0-9]*[sabp.][0-9]* ) 1551 ;; 1552 * ) echo "$msgprefix:Error: invalid version string entered: \`$triple'" 1>&2 1553 continue 1554 ;; 1555 esac 1556 break 1557 done 1558 eval `echo $triple |\ 1559 sed -e 's%^\([0-9]*\)\.\([0-9]*\)\([sabp.]\)\([0-9]*\)$%\ 1560 ver="\1";rev="\2";typ="\3";lev="\4"%'` 1561 tim=calc 1562 fi 1563 1564 # determine hexadecimal and libtool value of version 1565 case $typ in 1566 a ) typnum=0; levnum=$lev ;; 1567 b ) typnum=1; levnum=$lev ;; 1568 p | . ) typnum=2; levnum=$lev ;; 1569 s ) typnum=15; levnum=255 ;; # snapshots are special 1570 esac 1571 hex=`echo "$ver:$rev:$typnum:$levnum" |\ 1572 awk -F: '{ printf("0x%x%02x%1x%02x", $1, $2, $3, $4); }' |\ 1573 tr 'abcdef' 'ABCDEF'` 1574 ltv=`echo "$ver:$rev:$typnum:$levnum" |\ 1575 awk -F: '{ printf("%d:%d", $1*10 + $2, $3*10 + $4); }'` 1576 1577 # determine date 1578 if [ ".$tim" = .calc ]; then 1579 day=`date '+%d'` 1580 month=`date '+%m'` 1581 year=`date '+%Y' 2>/dev/null` 1582 if [ ".$time_year" = . ]; then 1583 year=`date '+%y'` 1584 case $year in 1585 [5-9][0-9]) year="19$year" ;; 1586 [0-4][0-9]) year="20$year" ;; 1587 esac 1588 fi 1589 case $month in 1590 1|01) month='Jan' ;; 1591 2|02) month='Feb' ;; 1592 3|03) month='Mar' ;; 1593 4|04) month='Apr' ;; 1594 5|05) month='May' ;; 1595 6|06) month='Jun' ;; 1596 7|07) month='Jul' ;; 1597 8|08) month='Aug' ;; 1598 9|09) month='Sep' ;; 1599 10) month='Oct' ;; 1600 11) month='Nov' ;; 1601 12) month='Dec' ;; 1602 esac 1603 tim="${day}-${month}-${year}" 1604 fi 1605 1606 # perform result actions 1607 mode=show 1608 if [ ".$opt_i" != . ]; then 1609 mode=edit 1610 elif [ ".$opt_e" = .yes ]; then 1611 mode=edit 1612 elif [ ".$opt_s" != . ]; then 1613 mode=edit 1614 fi 1615 if [ ".$mode" = .show ]; then 1616 # just display the current version 1617 case $opt_d in 1618 short ) 1619 echo "${ver}.${rev}${typ}${lev}" 1620 ;; 1621 long ) 1622 echo "${ver}.${rev}${typ}${lev} ($tim)" 1623 ;; 1624 libtool ) 1625 echo "${ltv}" 1626 ;; 1627 hex ) 1628 echo "${hex}" 1629 ;; 1630 * ) echo "$msgprefix:Error: invalid argument to option \`-d': \`$opt_d'" 1>&2 1631 shtool_exit 1 1632 ;; 1633 esac 1634 else 1635 # update the version file 1636 1637 # pre-generate various strings 1638 triple="${ver}.${rev}${typ}${lev}" 1639 vHex="$hex" 1640 vShort="${triple}" 1641 vLong="${triple} (${tim})" 1642 vTeX="This is ${name}, Version ${triple} (${tim})" 1643 vGNU="${name} ${triple} (${tim})" 1644 vWeb="${name}/${triple}" 1645 vSCCS="@(#)${name} ${triple} (${tim})" 1646 vRCS="\$Id: ${name} ${triple} (${tim}) \$" 1647 1648 # determine string out of filename 1649 # (do NOT try to optimize this in any way because of portability) 1650 filestr=`util_upper "$file" | tr './%+' '____' | sed -e 's/-/_/g'` 1651 1652 # generate uppercase prefix 1653 prefixupper=`util_upper "$prefix"` 1654 1655 # create the version file according the the selected language 1656 echo "new version: ${vLong}" 1657 1658 cp /dev/null $file 1659 case $opt_l in 1660 txt ) 1661 echo >>$file "" 1662 echo >>$file " ${file} -- Version Information for ${name} (syntax: Text)" 1663 echo >>$file " [automatically generated and maintained by GNU shtool]" 1664 echo >>$file "" 1665 echo >>$file " $vTeX" 1666 echo >>$file "" 1667 ;; 1668 c ) 1669 echo >>$file "/*" 1670 echo >>$file "** ${file} -- Version Information for ${name} (syntax: C/C++)" 1671 echo >>$file "** [automatically generated and maintained by GNU shtool]" 1672 echo >>$file "*/" 1673 echo >>$file "" 1674 echo >>$file "#ifdef _${filestr}_AS_HEADER_" 1675 echo >>$file "" 1676 echo >>$file "#ifndef _${filestr}_" 1677 echo >>$file "#define _${filestr}_" 1678 echo >>$file "" 1679 echo >>$file "#define ${prefixupper}VERSION ${vHex}" 1680 echo >>$file "" 1681 echo >>$file "typedef struct {" 1682 echo >>$file " const int v_hex;" 1683 echo >>$file " const char *v_short;" 1684 echo >>$file " const char *v_long;" 1685 echo >>$file " const char *v_tex;" 1686 echo >>$file " const char *v_gnu;" 1687 echo >>$file " const char *v_web;" 1688 echo >>$file " const char *v_sccs;" 1689 echo >>$file " const char *v_rcs;" 1690 echo >>$file "} ${prefix}version_t;" 1691 echo >>$file "" 1692 echo >>$file "extern ${prefix}version_t ${prefix}version;" 1693 echo >>$file "" 1694 echo >>$file "#endif /* _${filestr}_ */" 1695 echo >>$file "" 1696 echo >>$file "#else /* _${filestr}_AS_HEADER_ */" 1697 echo >>$file "" 1698 echo >>$file "#define _${filestr}_AS_HEADER_" 1699 echo >>$file "#include \"${file}\"" 1700 echo >>$file "#undef _${filestr}_AS_HEADER_" 1701 echo >>$file "" 1702 echo >>$file "${prefix}version_t ${prefix}version = {" 1703 echo >>$file " ${vHex}," 1704 echo >>$file " \"${vShort}\"," 1705 echo >>$file " \"${vLong}\"," 1706 echo >>$file " \"${vTeX}\"," 1707 echo >>$file " \"${vGNU}\"," 1708 echo >>$file " \"${vWeb}\"," 1709 echo >>$file " \"${vSCCS}\"," 1710 echo >>$file " \"${vRCS}\"" 1711 echo >>$file "};" 1712 echo >>$file "" 1713 echo >>$file "#endif /* _${filestr}_AS_HEADER_ */" 1714 echo >>$file "" 1715 ;; 1716 m4 ) 1717 echo >>$file "##" 1718 echo >>$file "## ${file} -- Version Information for ${name} (syntax: M4)" 1719 echo >>$file "## [automatically generated and maintained by GNU shtool]" 1720 echo >>$file "##" 1721 echo >>$file "" 1722 echo >>$file "m4_define([v_hex], [${vHex}])" 1723 echo >>$file "m4_define([v_short], [${vShort}])" 1724 echo >>$file "m4_define([v_long], [${vLong}])" 1725 echo >>$file "m4_define([v_tex], [${vTeX}])" 1726 echo >>$file "m4_define([v_gnu], [${vGNU}])" 1727 echo >>$file "m4_define([v_web], [${vWeb}])" 1728 echo >>$file "m4_define([v_sccs], [${vSCCS}])" 1729 echo >>$file "m4_define([v_rcs], [${vRCS}])" 1730 echo >>$file "" 1731 ;; 1732 perl ) 1733 echo >>$file "##" 1734 echo >>$file "## ${file} -- Version Information for ${name} (syntax: Perl)" 1735 echo >>$file "## [automatically generated and maintained by GNU shtool]" 1736 echo >>$file "##" 1737 echo >>$file "" 1738 echo >>$file "our \$${prefix}version = {" 1739 echo >>$file " 'v_hex' => ${vHex}," 1740 echo >>$file " 'v_short' => \"${vShort}\"," 1741 echo >>$file " 'v_long' => \"${vLong}\"," 1742 echo >>$file " 'v_tex' => \"${vTeX}\"," 1743 echo >>$file " 'v_gnu' => \"${vGNU}\"," 1744 echo >>$file " 'v_web' => \"${vWeb}\"," 1745 echo >>$file " 'v_sccs' => \"${vSCCS}\"," 1746 echo >>$file " 'v_rcs' => \"\\${vRCS}/\"" 1747 echo >>$file "};" 1748 echo >>$file "" 1749 echo >>$file "1;" 1750 echo >>$file "" 1751 ;; 1752 python ) 1753 echo >>$file "##" 1754 echo >>$file "## ${file} -- Version Information for ${name} (syntax: Python)" 1755 echo >>$file "## [automatically generated and maintained by GNU shtool]" 1756 echo >>$file "##" 1757 echo >>$file "" 1758 echo >>$file "class ${prefix}version:" 1759 echo >>$file " v_hex = ${vHex}" 1760 echo >>$file " v_short = \"${vShort}\"" 1761 echo >>$file " v_long = \"${vLong}\"" 1762 echo >>$file " v_tex = \"${vTeX}\"" 1763 echo >>$file " v_gnu = \"${vGNU}\"" 1764 echo >>$file " v_web = \"${vWeb}\"" 1765 echo >>$file " v_sccs = \"${vSCCS}\"" 1766 echo >>$file " v_rcs = \"${vRCS}\"" 1767 echo >>$file "" 1768 ;; 1769 * ) echo "$msgprefix:Error: invalid argument to option \`-l': \`$opt_l'" 1>&2 1770 shtool_exit 1 1771 ;; 1772 esac 1773 fi 1774 1775 shtool_exit 0 1776 ;; 1777 1778esac 1779 1780shtool_exit 0 1781 1782