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