| 1 #!@l_prefix@/lib/openpkg/bash --noprofile |
1 #!@l_prefix@/lib/openpkg/bash --noprofile |
| 2 ## |
2 ## |
| 3 ## rc -- OpenPKG Runcommand Processor |
3 ## rc -- OpenPKG Run-Command Processor |
| 4 ## Copyright (c) 2000-2007 OpenPKG Foundation e.V. <http://openpkg.net/> |
4 ## Copyright (c) 2000-2012 OpenPKG GmbH <http://openpkg.com/> |
| 5 ## Copyright (c) 2000-2007 Ralf S. Engelschall <http://engelschall.com/> |
5 ## |
| 6 ## |
6 ## This software is property of the OpenPKG GmbH, DE MUC HRB 160208. |
| 7 ## Permission to use, copy, modify, and distribute this software for |
7 ## All rights reserved. Licenses which grant limited permission to use, |
| 8 ## any purpose with or without fee is hereby granted, provided that |
8 ## copy, modify and distribute this software are available from the |
| 9 ## the above copyright notice and this permission notice appear in all |
9 ## OpenPKG GmbH. |
| 10 ## copies. |
10 ## |
| 11 ## |
11 ## THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED |
| 12 ## THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED |
|
| 13 ## WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
12 ## WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
| 14 ## MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
13 ## MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
| 15 ## IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR |
14 ## IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR |
| 16 ## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
15 ## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| 17 ## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
16 ## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| 45 rcfunc="$prefix/etc/rc.func" |
44 rcfunc="$prefix/etc/rc.func" |
| 46 |
45 |
| 47 # helper variables |
46 # helper variables |
| 48 NL=" |
47 NL=" |
| 49 " |
48 " |
| |
49 |
| |
50 ## |
| |
51 ## temporary file handling |
| |
52 ## |
| |
53 |
| |
54 # establish secure temporary directory |
| |
55 i=0 |
| |
56 while [ $i -lt 10 ]; do |
| |
57 tmpdir="/tmp/rc-`date '+%Y%m%d%H%M%S'`-$$" |
| |
58 (umask 022; mkdir $tmpdir >/dev/null 2>&1) && break |
| |
59 i=$(($i + 1)) |
| |
60 sleep 1 |
| |
61 done |
| |
62 if [ $i -eq 10 ]; then |
| |
63 echo "openpkg:rc:ERROR: unable to establish secure temporary directory" 1>&2 |
| |
64 exit 1 |
| |
65 fi |
| |
66 declare -r tmpdir |
| |
67 cleanup () { |
| |
68 if [ ".$tmpdir" != . ]; then |
| |
69 if [ -d $tmpdir ]; then |
| |
70 rm -rf $tmpdir >/dev/null 2>&1 || true |
| |
71 fi |
| |
72 fi |
| |
73 } |
| |
74 trap "cleanup; trap - EXIT INT ABRT QUIT TERM" EXIT INT ABRT QUIT TERM |
| |
75 |
| |
76 # determine reasonable temporary files |
| |
77 tmpfile="$tmpdir/rc.tmp" |
| |
78 outfile="$tmpdir/rc.out" |
| |
79 errfile="$tmpdir/rc.err" |
| |
80 allfile="$tmpdir/rc.all" |
| |
81 deffile="$tmpdir/rc.def" |
| |
82 |
| |
83 # initialize files |
| |
84 cp /dev/null $deffile |
| 50 |
85 |
| 51 ## |
86 ## |
| 52 ## command line option parsing |
87 ## command line option parsing |
| 53 ## |
88 ## |
| 54 |
89 |
| 63 config=0 |
98 config=0 |
| 64 query=0 |
99 query=0 |
| 65 |
100 |
| 66 # iterate over argument line |
101 # iterate over argument line |
| 67 while [ $# -gt 0 ]; do |
102 while [ $# -gt 0 ]; do |
| 68 opt=$1 |
103 case "$1" in |
| 69 case $opt in |
|
| 70 -*=*) arg=${opt/-*=/} ;; |
|
| 71 *) arg='' ;; |
|
| 72 esac |
|
| 73 case $opt in |
|
| 74 -s|--silent ) silent=1 ;; |
104 -s|--silent ) silent=1 ;; |
| 75 -v|--verbose ) verbose=1 ;; |
105 -v|--verbose ) verbose=1 ;; |
| 76 -d|--debug ) debug=1 ;; |
106 -d|--debug ) debug=1 ;; |
| 77 -h|--help ) help="Usage" ;; |
107 -h|--help ) help="Usage" ;; |
| 78 -k|--keep ) keep=1 ;; |
108 -k|--keep ) keep=1 ;; |
| 79 -p|--print ) print=1 ;; |
109 -p|--print ) print=1 ;; |
| 80 -e|--eval ) eval=1 ;; |
110 -e|--eval ) eval=1 ;; |
| 81 -c|--config ) config=1 ;; |
111 -c|--config ) config=1 ;; |
| 82 -q|--query ) query=1 ;; |
112 -q|--query ) query=1 ;; |
| 83 -* ) help="Invalid option \`$opt'"; break ;; |
113 -D|--define ) echo "@$2" | \ |
| 84 * ) break ;; |
114 sed -e "s;';\\\\';g" | \ |
| |
115 sed -e "s;^@\\([a-z][a-zA-Z0-9_]*\\)=\\(.*\\)\$;\1='\2';" \ |
| |
116 -e "s;^@.*;;" >>$deffile; shift ;; |
| |
117 -* ) help="Invalid option \`$1'"; break ;; |
| |
118 * ) break ;; |
| 85 esac |
119 esac |
| 86 shift |
120 shift |
| 87 done |
121 done |
| 88 |
122 |
| 89 # display error or usage message |
123 # display error or usage message |
| 90 if [ ".$help" != .0 ]; then |
124 if [ ".$help" != .0 ]; then |
| 91 if [ ".$help" != ".Usage" ]; then |
125 if [ ".$help" != ".Usage" ]; then |
| 92 echo "$progname:ERROR: $help" 1>&2 |
126 echo "$progname:ERROR: $help" 1>&2 |
| 93 fi |
127 fi |
| 94 echo "Usage: $progname [-s|--silent] [-v|--verbose] [-d|--debug] [-k|--keep] [-h|--help]" 1>&2 |
128 echo "Usage: $progname [-s|--silent] [-v|--verbose] [-d|--debug] [-k|--keep] [-h|--help]" 1>&2 |
| 95 echo " [-p|--print] [-e|--eval] [-c|--config] [-q|--query]" 1>&2 |
129 echo " [-p|--print] [-e|--eval] [-c|--config] [-q|--query] [-D|--define <name>=<value>]" 1>&2 |
| 96 echo " <package> <command> [<command> ...]" 1>&2 |
130 echo " <package> <command> [<command> ...]" 1>&2 |
| 97 if [ ".$help" != ".Usage" ]; then |
131 if [ ".$help" != ".Usage" ]; then |
| 98 exit 1 |
132 exit 1 |
| 99 else |
133 else |
| 100 exit 0 |
134 exit 0 |
| 115 fi |
149 fi |
| 116 fi |
150 fi |
| 117 |
151 |
| 118 # extend run-time environment with local OpenPKG tools (shtool, rpmtool, etc) |
152 # extend run-time environment with local OpenPKG tools (shtool, rpmtool, etc) |
| 119 PATH_ORIG="$PATH" |
153 PATH_ORIG="$PATH" |
| |
154 PATH="$prefix/lib/openpkg/fallback:$PATH" |
| 120 PATH="$prefix/bin:$PATH" |
155 PATH="$prefix/bin:$PATH" |
| 121 PATH="$prefix/sbin:$PATH" |
156 PATH="$prefix/sbin:$PATH" |
| 122 PATH="$prefix/lib/openpkg:$PATH" |
157 PATH="$prefix/lib/openpkg:$PATH" |
| 123 |
158 PATH="$prefix/lib/openpkg/override:$PATH" |
| 124 # establish secure temporary directory |
|
| 125 i=0 |
|
| 126 while [ $i -lt 10 ]; do |
|
| 127 tmpdir="/tmp/rc-`date '+%Y%m%d%H%M%S'`-$$" |
|
| 128 (umask 022; mkdir $tmpdir >/dev/null 2>&1) && break |
|
| 129 i=$(($i + 1)) |
|
| 130 sleep 1 |
|
| 131 done |
|
| 132 if [ $i -eq 10 ]; then |
|
| 133 echo "openpkg:rc:ERROR: unable to establish secure temporary directory" 1>&2 |
|
| 134 exit 1 |
|
| 135 fi |
|
| 136 declare -r tmpdir |
|
| 137 trap "trap - EXIT INT ABRT QUIT TERM; rm -rf $tmpdir >/dev/null 2>&1 || true" EXIT INT ABRT QUIT TERM |
|
| 138 |
|
| 139 # determine reasonable temporary files |
|
| 140 tmpfile="$tmpdir/rc.tmp" |
|
| 141 outfile="$tmpdir/rc.out" |
|
| 142 errfile="$tmpdir/rc.err" |
|
| 143 allfile="$tmpdir/rc.all" |
|
| 144 |
159 |
| 145 # handle --query option |
160 # handle --query option |
| 146 if [ ".$query" = .1 ]; then |
161 if [ ".$query" = .1 ]; then |
| 147 # suck in all %config sections of all scripts |
162 # suck in all %config sections of all scripts |
| 148 # (rc.openpkg is special: has to be first and requires pre-inclusion of rc.conf) |
163 # (rc.openpkg is special: has to be first and requires pre-inclusion of rc.conf) |
| 149 touch $tmpfile |
164 touch $tmpfile |
| 150 sed <$rcdir/rc.openpkg >>$tmpfile -e "1,/^%config/d" -e '/^%.*/,$d' |
165 sed <$rcdir/rc.openpkg >>$tmpfile -e "1,/^%config/d" -e '/^%.*/,$d' |
| 151 echo ". $rcconf" >>$tmpfile |
166 echo ". $rcconf" >>$tmpfile |
| |
167 echo ". $deffile" >>$tmpfile |
| 152 scripts=`/bin/ls $rcdir/rc.* | sed -e "s;^$rcdir/rc\.;;" | egrep -v '^openpkg$'` |
168 scripts=`/bin/ls $rcdir/rc.* | sed -e "s;^$rcdir/rc\.;;" | egrep -v '^openpkg$'` |
| 153 for s_name in $scripts; do |
169 for s_name in $scripts; do |
| 154 sed <$rcdir/rc.$s_name >>$tmpfile -e "1,/^%config/d" -e '/^%.*/,$d' |
170 sed <$rcdir/rc.$s_name >>$tmpfile -e "1,/^%config/d" -e '/^%.*/,$d' |
| 155 done |
171 done |
| 156 . $tmpfile |
172 . $tmpfile |
| 157 |
173 |
| 158 # apply override values to get effective values |
174 # apply override values to get effective values |
| 159 . $rcconf |
175 . $rcconf |
| |
176 . $deffile |
| 160 |
177 |
| 161 # display variable value |
178 # display variable value |
| 162 for var in $*; do |
179 for var in $*; do |
| 163 eval "echo \${$var}" |
180 eval "echo \${$var}" |
| 164 done |
181 done |
| 172 # suck in all %config sections of all scripts |
189 # suck in all %config sections of all scripts |
| 173 # (rc.openpkg is special: has to be first and requires pre-inclusion of rc.conf) |
190 # (rc.openpkg is special: has to be first and requires pre-inclusion of rc.conf) |
| 174 touch $tmpfile |
191 touch $tmpfile |
| 175 sed <$rcdir/rc.openpkg >>$tmpfile -e "1,/^%config/d" -e '/^%.*/,$d' |
192 sed <$rcdir/rc.openpkg >>$tmpfile -e "1,/^%config/d" -e '/^%.*/,$d' |
| 176 echo ". $rcconf" >>$tmpfile |
193 echo ". $rcconf" >>$tmpfile |
| |
194 echo ". $deffile" >>$tmpfile |
| 177 scripts=`/bin/ls $rcdir/rc.* | sed -e "s;^$rcdir/rc\.;;" | egrep -v '^openpkg$'` |
195 scripts=`/bin/ls $rcdir/rc.* | sed -e "s;^$rcdir/rc\.;;" | egrep -v '^openpkg$'` |
| 178 for s_name in $scripts; do |
196 for s_name in $scripts; do |
| 179 sed <$rcdir/rc.$s_name >>$tmpfile -e "1,/^%config/d" -e '/^%.*/,$d' |
197 sed <$rcdir/rc.$s_name >>$tmpfile -e "1,/^%config/d" -e '/^%.*/,$d' |
| 180 done |
198 done |
| 181 . $tmpfile |
199 . $tmpfile |
| 235 exit 1 |
254 exit 1 |
| 236 fi |
255 fi |
| 237 scripts="${1/*rc./}" |
256 scripts="${1/*rc./}" |
| 238 shift |
257 shift |
| 239 isall=0 |
258 isall=0 |
| |
259 if [ ".$scripts" = ".cron" ]; then |
| |
260 # "cron" is an "all" with a random delay (to ensure that multiple |
| |
261 # OpenPKG instances do not all startup at exactly the same time) |
| |
262 # plus a mutex lock to ensure that multiple OpenPKG cron tasks of |
| |
263 # the same OpenPKG instance do not stumble over each other). |
| |
264 |
| |
265 # determine delay range and timeout |
| |
266 case "${1-quarterly}" in |
| |
267 monthly ) delay=1800; timeout=28800 ;; # 30m / 8h |
| |
268 weekly ) delay=1800; timeout=14400 ;; # 30m / 4h |
| |
269 daily ) delay=900; timeout=7200 ;; # 15m / 2h |
| |
270 hourly ) delay=600; timeout=3600 ;; # 5m / 1h |
| |
271 quarterly|* ) delay=30; timeout=900 ;; # 30s / 15m |
| |
272 esac |
| |
273 |
| |
274 # apply random run-time delay |
| |
275 # (hint: $RANDOM is a random value 0..32767) |
| |
276 sleep $(( ($RANDOM * $delay) / 32767 )) |
| |
277 |
| |
278 # wrap ourself for mutual exclusion run-time |
| |
279 # and then perform the "all" command |
| |
280 cleanup |
| |
281 exec $prefix/lib/openpkg/mutex \ |
| |
282 -t $timeout $prefix/RPM/TMP/openpkg-rc-cron.mutex \ |
| |
283 sh -c "exec $0 all $*" || exit $? |
| |
284 fi |
| 240 if [ ".$scripts" = ".all" ]; then |
285 if [ ".$scripts" = ".all" ]; then |
| 241 isall=1 |
286 isall=1 |
| 242 . $rcconf |
287 . $rcconf |
| 243 if [ ".$openpkg_runall" != . ]; then |
288 . $deffile |
| 244 # backward compatibility only |
|
| 245 echo "openpkg:rc:WARNING: variable \"openpkg_runall\" was renamed to \"openpkg_rc_all\"." 1>&2 |
|
| 246 echo "openpkg:rc:WARNING: value of deprecated variable \"openpkg_runall\" taken over for compatibility." 1>&2 |
|
| 247 echo "openpkg:rc:WARNING: please update your local configuration in \"$rcconf\"." 1>&2 |
|
| 248 openpkg_rc_all="$openpkg_runall" |
|
| 249 fi |
|
| 250 case "$openpkg_rc_all" in |
289 case "$openpkg_rc_all" in |
| 251 [Nn][Oo] | [Ff][Aa][Ll][Ss][Ee] | [Oo][Ff][Ff] | 0 ) exit 0 ;; |
290 [Nn][Oo] | [Ff][Aa][Ll][Ss][Ee] | [Oo][Ff][Ff] | 0 ) exit 0 ;; |
| 252 esac |
291 esac |
| 253 scripts=`/bin/ls $rcdir/rc.* | sed -e "s;^$rcdir/rc\.;;"` |
292 scripts=`/bin/ls $rcdir/rc.* | sed -e "s;^$rcdir/rc\.;;"` |
| |
293 |
| |
294 # the "all" target is usually called from system startup scripts, |
| |
295 # and we really want to ensure that no potentially corrupt |
| |
296 # (because of an unclean shutdown of the system) RPM DB journal |
| |
297 # files are staying around and preventing the startup of the |
| |
298 # OpenPKG instance. When called manually it also doesn't hurt to |
| |
299 # cleanup. |
| |
300 rm -f $prefix/RPM/DB/__db.* >/dev/null 2>&1 || true |
| 254 else |
301 else |
| 255 if [ ! -f "$rcdir/rc.$scripts" ]; then |
302 if [ ! -f "$rcdir/rc.$scripts" ]; then |
| 256 echo "openpkg:rc:ERROR: package \"$scripts\" not found" 1>&2 |
303 echo "openpkg:rc:ERROR: package \"$scripts\" not found" 1>&2 |
| 257 exit 1 |
304 exit 1 |
| 258 fi |
305 fi |
| 395 # variable, we place the %config section of "openpkg" to the front. |
445 # variable, we place the %config section of "openpkg" to the front. |
| 396 # And we have to extra pre-include the rc.conf to allow |
446 # And we have to extra pre-include the rc.conf to allow |
| 397 # rc.conf to override the default of $openpkg_rc_def, too. |
447 # rc.conf to override the default of $openpkg_rc_def, too. |
| 398 sed <$rcdir/rc.openpkg >>$tmpfile -e "1,/^%config/d" -e '/^%.*/,$d' |
448 sed <$rcdir/rc.openpkg >>$tmpfile -e "1,/^%config/d" -e '/^%.*/,$d' |
| 399 echo ". $rcconf" >>$tmpfile |
449 echo ". $rcconf" >>$tmpfile |
| |
450 echo ". $deffile" >>$tmpfile |
| 400 l_scripts=`/bin/ls $rcdir/rc.* | sed -e "s;^$rcdir/rc\.;;" | egrep -v '^openpkg$'` |
451 l_scripts=`/bin/ls $rcdir/rc.* | sed -e "s;^$rcdir/rc\.;;" | egrep -v '^openpkg$'` |
| 401 for l_name in $l_scripts; do |
452 for l_name in $l_scripts; do |
| 402 sed <$rcdir/rc.$l_name >>$tmpfile -e "1,/^%config/d" -e '/^%.*/,$d' |
453 sed <$rcdir/rc.$l_name >>$tmpfile -e "1,/^%config/d" -e '/^%.*/,$d' |
| 403 done |
454 done |
| 404 |
455 |
| 405 # generate: inclusion of the application of override variables |
456 # generate: inclusion of the application of override variables |
| 406 echo ". $rcconf" >>$tmpfile |
457 echo ". $rcconf" >>$tmpfile |
| |
458 echo ". $deffile" >>$tmpfile |
| 407 |
459 |
| 408 # for --eval redirect stderr and stdout (but remember stdout) |
460 # for --eval redirect stderr and stdout (but remember stdout) |
| 409 # (let stderr pass unfiltered in case of debug mode) |
461 # (let stderr pass unfiltered in case of debug mode) |
| 410 if [ ".$eval" = .1 ]; then |
462 if [ ".$eval" = .1 ]; then |
| 411 if [ ".$debug" = .1 ]; then |
463 if [ ".$debug" = .1 ]; then |
| 490 # variable, we place the %config section of "openpkg" to the front. |
542 # variable, we place the %config section of "openpkg" to the front. |
| 491 # And we have to extra pre-include the rc.conf to allow |
543 # And we have to extra pre-include the rc.conf to allow |
| 492 # rc.conf to override the default of $openpkg_rc_def, too. |
544 # rc.conf to override the default of $openpkg_rc_def, too. |
| 493 sed <$rcdir/rc.openpkg >>$tmpfile -e "1,/^%config/d" -e '/^%.*/,$d' |
545 sed <$rcdir/rc.openpkg >>$tmpfile -e "1,/^%config/d" -e '/^%.*/,$d' |
| 494 echo ". $rcconf" >>$tmpfile |
546 echo ". $rcconf" >>$tmpfile |
| |
547 echo ". $deffile" >>$tmpfile |
| 495 l_scripts=`/bin/ls $rcdir/rc.* | sed -e "s;^$rcdir/rc\.;;" | egrep -v '^openpkg$'` |
548 l_scripts=`/bin/ls $rcdir/rc.* | sed -e "s;^$rcdir/rc\.;;" | egrep -v '^openpkg$'` |
| 496 for l_name in $l_scripts; do |
549 for l_name in $l_scripts; do |
| 497 sed <$rcdir/rc.$l_name >>$tmpfile -e "1,/^%config/d" -e '/^%.*/,$d' |
550 sed <$rcdir/rc.$l_name >>$tmpfile -e "1,/^%config/d" -e '/^%.*/,$d' |
| 498 done |
551 done |
| 499 |
552 |
| 500 # generate: inclusion of the application of override variables |
553 # generate: inclusion of the application of override variables |
| 501 echo ". $rcconf" >>$tmpfile |
554 echo ". $rcconf" >>$tmpfile |
| |
555 echo ". $deffile" >>$tmpfile |
| 502 |
556 |
| 503 # generate: %common section and particular command section |
557 # generate: %common section and particular command section |
| 504 sed <$rcdir/rc.$s_name >>$tmpfile -e "1,/^%common/d" -e '/^%.*/,$d' |
558 sed <$rcdir/rc.$s_name >>$tmpfile -e "1,/^%common/d" -e '/^%.*/,$d' |
| 505 sed <$rcdir/rc.$s_name >>$tmpfile -e "1,/^%$cmd/d" -e '/^%.*/,$d' |
559 sed <$rcdir/rc.$s_name >>$tmpfile -e "1,/^%$cmd/d" -e '/^%.*/,$d' |
| 506 |
560 |