rc 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651
  1. #!@l_prefix@/lib/openpkg/bash --noprofile
  2. ##
  3. ## rc -- OpenPKG Run-Command Processor
  4. ## Copyright (c) 2000-2003 The OpenPKG Project <http://www.openpkg.org/>
  5. ## Copyright (c) 2000-2003 Ralf S. Engelschall <rse@engelschall.com>
  6. ## Copyright (c) 2000-2003 Cable & Wireless <http://www.cw.com/>
  7. ##
  8. ## Permission to use, copy, modify, and distribute this software for
  9. ## any purpose with or without fee is hereby granted, provided that
  10. ## the above copyright notice and this permission notice appear in all
  11. ## copies.
  12. ##
  13. ## THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
  14. ## WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  15. ## MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  16. ## IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR
  17. ## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  18. ## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  19. ## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  20. ## USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  21. ## ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  22. ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  23. ## OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  24. ## SUCH DAMAGE.
  25. ##
  26. ##
  27. ## configuration
  28. ##
  29. # program name, version and date
  30. progname="rc"
  31. progvers="1.2.0"
  32. progdate="28-Jul-2003"
  33. # path to OpenPKG instance
  34. prefix="@l_prefix@"
  35. # path to GNU bash and GNU shtool
  36. bash="$prefix/lib/openpkg/bash"
  37. shtool="$prefix/lib/openpkg/shtool"
  38. # path to rc.d, rc.conf and rc.func
  39. rcdir="$prefix/etc/rc.d"
  40. rcconf="$prefix/etc/rc.conf"
  41. rcfunc="$prefix/etc/rc.func"
  42. # helper variables
  43. NL="
  44. "
  45. # provide hook for "openpkg-rc" package which contains the
  46. # new OSSP rc implementation as a replacement for this script.
  47. if [ -f "$prefix/lib/openpkg/rcng" ]; then
  48. exec "$prefix/lib/openpkg/rcng" ${1+"$@"}
  49. fi
  50. ##
  51. ## command line option parsing
  52. ##
  53. # default parameters
  54. silent=0
  55. verbose=0
  56. debug=0
  57. help=0
  58. print=0
  59. eval=0
  60. config=0
  61. query=0
  62. # iterate over argument line
  63. while [ $# -gt 0 ]; do
  64. opt=$1
  65. case $opt in
  66. -*=*) arg=${opt/-*=/} ;;
  67. *) arg='' ;;
  68. esac
  69. case $opt in
  70. -s|--silent ) silent=1 ;;
  71. -v|--verbose ) verbose=1 ;;
  72. -d|--debug ) debug=1 ;;
  73. -h|--help ) help="Usage" ;;
  74. -p|--print ) print=1 ;;
  75. -e|--eval ) eval=1 ;;
  76. -c|--config ) config=1 ;;
  77. -q|--query ) query=1 ;;
  78. -* ) help="Invalid option \`$opt'"; break ;;
  79. * ) break ;;
  80. esac
  81. shift
  82. done
  83. # display error or usage message
  84. if [ ".$help" != .0 ]; then
  85. if [ ".$help" != ".Usage" ]; then
  86. echo "$progname:ERROR: $help" 1>&2
  87. fi
  88. echo "Usage: $progname [-s|--silent] [-v|--verbose] [-d|--debug] [-h|--help]" 1>&2
  89. echo " [-p|--print] [-e|--eval] [-c|--config] [-q|--query]" 1>&2
  90. echo " <package> <command> [<command> ...]" 1>&2
  91. if [ ".$help" != ".Usage" ]; then
  92. exit 1
  93. else
  94. exit 0
  95. fi
  96. fi
  97. # determine a reasonable default silent/verbose situation in case
  98. # nothing was explicitly specified or a conflicting situation was
  99. # specified. Else is silent either disabled by default or was
  100. # explicitly enabled.
  101. if [ $silent -eq $verbose ]; then
  102. if [ -t 2 ]; then
  103. # stdout connected to a terminal device, so no need to be silent
  104. silent=0
  105. else
  106. # stdout NOT connected to a terminal device, so be silent
  107. silent=1
  108. fi
  109. fi
  110. # extend run-time environment with local OpenPKG tools (shtool, rpmtool, etc)
  111. PATH_ORIG="$PATH"
  112. PATH="$prefix/bin:$PATH"
  113. PATH="$prefix/sbin:$PATH"
  114. PATH="$prefix/lib/openpkg:$PATH"
  115. # establish secure temporary directory
  116. i=0
  117. while [ $i -lt 10 ]; do
  118. tmpdir="/tmp/rc-`date '+%Y%m%d%H%M%S'`-$$"
  119. (umask 022; mkdir $tmpdir >/dev/null 2>&1) && break
  120. i=$(($i + 1))
  121. sleep 1
  122. done
  123. if [ $i -eq 10 ]; then
  124. echo "openpkg:rc:ERROR: unable to establish secure temporary directory" 1>&2
  125. exit 1
  126. fi
  127. declare -r tmpdir
  128. trap "trap - EXIT INT ABRT QUIT TERM; rm -rf $tmpdir >/dev/null 2>&1 || true" EXIT INT ABRT QUIT TERM
  129. # determine reasonable temporary files
  130. tmpfile="$tmpdir/rc.tmp"
  131. outfile="$tmpdir/rc.out"
  132. errfile="$tmpdir/rc.err"
  133. allfile="$tmpdir/rc.all"
  134. # handle --query option
  135. if [ ".$query" = .1 ]; then
  136. # suck in all %config sections of all scripts
  137. # (rc.openpkg is special: has to be first and requires pre-inclusion of rc.conf)
  138. touch $tmpfile
  139. sed <$rcdir/rc.openpkg >>$tmpfile -e "1,/^%config/d" -e '/^%.*/,$d'
  140. echo ". $rcconf" >>$tmpfile
  141. scripts=`/bin/ls $rcdir/rc.* | sed -e "s;^$rcdir/rc\.;;" | egrep -v '^openpkg$'`
  142. for s_name in $scripts; do
  143. sed <$rcdir/rc.$s_name >>$tmpfile -e "1,/^%config/d" -e '/^%.*/,$d'
  144. done
  145. . $tmpfile
  146. # apply override values to get effective values
  147. . $rcconf
  148. # display variable value
  149. for var in $*; do
  150. eval "echo \${$var}"
  151. done
  152. # stop processing immediately
  153. exit 0
  154. fi
  155. # handle --config option
  156. if [ ".$config" = .1 ]; then
  157. # suck in all %config sections of all scripts
  158. # (rc.openpkg is special: has to be first and requires pre-inclusion of rc.conf)
  159. touch $tmpfile
  160. sed <$rcdir/rc.openpkg >>$tmpfile -e "1,/^%config/d" -e '/^%.*/,$d'
  161. echo ". $rcconf" >>$tmpfile
  162. scripts=`/bin/ls $rcdir/rc.* | sed -e "s;^$rcdir/rc\.;;" | egrep -v '^openpkg$'`
  163. for s_name in $scripts; do
  164. sed <$rcdir/rc.$s_name >>$tmpfile -e "1,/^%config/d" -e '/^%.*/,$d'
  165. done
  166. . $tmpfile
  167. # remember default values
  168. vars=""
  169. OIFS="$IFS"; IFS="$NL"
  170. for assign in `egrep '[ ]*[a-zA-Z_][a-zA-Z_0-9]*=' $tmpfile | sort`; do
  171. var=`echo "$assign" | sed -e 's;^[ ]*\([a-zA-Z_][a-zA-Z_0-9]*\)=.*;\1;'`
  172. vars="$vars $var"
  173. eval "${var}_def=\"\$$var\""
  174. done
  175. IFS="$OIFS"
  176. # apply override values to get effective values
  177. . $rcconf
  178. # determine how to print in bold mode in case output
  179. # is connected to a terminal device
  180. if [ -t 1 ]; then
  181. begin_bold=`$shtool echo -e '%B'`
  182. end_bold=`$shtool echo -e '%b'`
  183. else
  184. begin_bold=""
  185. end_bold=""
  186. fi
  187. # iterate over all variables and display name, default and effective value
  188. echo "${begin_bold}Configuration Variable Effective Value Default Value${end_bold}"
  189. echo "------------------------ ------------------------- -- -------------------------"
  190. for var in . $vars; do
  191. test ".$var" = .. && continue
  192. eval "val=\"\$$var\""
  193. eval "def=\"\$${var}_def\""
  194. tag="!="
  195. begin="$begin_bold"
  196. end="$end_bold"
  197. if [ ".$val" = ".$def" ]; then
  198. tag="=="
  199. begin=""
  200. end=""
  201. fi
  202. printf "%s%-24s %-25s %s %-25s%s\n" "$begin" "$var" "\"$val\"" "$tag" "\"$def\"" "$end"
  203. done
  204. # stop processing immediately
  205. exit 0
  206. fi
  207. # determine script(s) to use and make sure they exist
  208. if [ $# -lt 1 ]; then
  209. echo "openpkg:rc:ERROR: no package and command(s) specified" 1>&2
  210. exit 1
  211. fi
  212. if [ $# -lt 2 ]; then
  213. echo "openpkg:rc:ERROR: no command(s) specified for package" 1>&2
  214. exit 1
  215. fi
  216. scripts="${1/*rc./}"
  217. shift
  218. isall=0
  219. if [ ".$scripts" = ".all" ]; then
  220. isall=1
  221. . $rcconf
  222. if [ ".$openpkg_runall" != . ]; then
  223. # backward compatibility only
  224. echo "openpkg:rc:WARNING: variable \"openpkg_runall\" was renamed to \"openpkg_rc_all\"." 1>&2
  225. echo "openpkg:rc:WARNING: value of deprecated variable \"openpkg_runall\" taken over for compatibility." 1>&2
  226. echo "openpkg:rc:WARNING: please update your local configuration in \"$rcconf\"." 1>&2
  227. openpkg_rc_all="$openpkg_runall"
  228. fi
  229. case "$openpkg_rc_all" in
  230. [Nn][Oo] | [Ff][Aa][Ll][Ss][Ee] | [Oo][Ff][Ff] | 0 ) exit 0 ;;
  231. esac
  232. scripts=`/bin/ls $rcdir/rc.* | sed -e "s;^$rcdir/rc\.;;"`
  233. else
  234. if [ ! -f "$rcdir/rc.$scripts" ]; then
  235. echo "openpkg:rc:ERROR: package \"$scripts\" not found" 1>&2
  236. exit 1
  237. fi
  238. fi
  239. # determine current run-time user
  240. user=`(id -un) 2>/dev/null ||\
  241. (id | sed -e 's;^[^(]*(\([^)]*\)).*;\1;') 2>/dev/null ||\
  242. (whoami) 2>/dev/null ||\
  243. (who am i | cut "-d " -f1) 2>/dev/null ||\
  244. echo ${LOGNAME:-${USER}}`
  245. if [ ".$user" = . ]; then
  246. echo "openpkg:rc:ERROR: unable to determine current username" 1>&2
  247. exit 1
  248. fi
  249. # iterate over the specified commands
  250. rv=0
  251. cmds="$*"
  252. for cmd in $cmds; do
  253. # create "all outputs" file for execution operation (i.e. not --print and --eval)
  254. if [ ".$print" = .0 -a ".$eval" = .0 ]; then
  255. rm -f $allfile
  256. touch $allfile
  257. fi
  258. # find scripts which contain the command and determine
  259. # their individual user/priority settings
  260. list=''
  261. for s_name in $scripts; do
  262. enable=yes
  263. # check for upgraded package with unresolved configuration file conflicts
  264. if [ -d "$prefix/etc/$s_name" -a ".$eval" != .1 ]; then
  265. if [ ".`find $prefix/etc/$s_name -print 2>/dev/null | egrep '.*\.rpm(new|orig|save)$'`" != . ]; then
  266. case "$cmd" in
  267. start|restart ) type="ERROR" ;;
  268. * ) type="WARNING" ;;
  269. esac
  270. echo "openpkg:rc:${type}: package \"$s_name\" has unresolved configuration file conflicts" 1>&2
  271. echo "openpkg:rc:${type}: indicated by \"*.rpm(new|orig|save)\" files in \"$prefix/etc/$s_name\"" 1>&2
  272. if [ ".$type" = .ERROR ]; then
  273. continue
  274. fi
  275. fi
  276. fi
  277. # parse global script options
  278. # (currently unused in OpenPKG)
  279. #shebangline=`head -1 $rcdir/rc.$s_name | grep "^#!rc"`
  280. #if [ ".$shebangline" != . ]; then
  281. # shebangopts=`echo "$shebangline" | sed -e "s;^#!rc *;;"`
  282. # set -- $shebangopts;
  283. # prev=''
  284. # for opt
  285. # do
  286. # if [ ".$prev" != . ]; then
  287. # opt="$prev$opt"
  288. # prev=''
  289. # fi
  290. # case $opt in
  291. # -*=* ) arg=`echo "$opt" | sed 's/^[-_a-zA-Z0-9]*=//'` ;;
  292. # -[a-zA-Z]* ) arg=`echo "$opt" | sed 's/^-[a-zA-Z0-9]//'` ;;
  293. # *) arg='' ;;
  294. # esac
  295. # case $opt in
  296. # -e|--enable ) enable=yes ;;
  297. # -d|--disable ) enable=no ;;
  298. # * ) echo "openpkg:rc:WARNING: invalid global option \"$opt\" in \"$rcdir/rc.$s_name:#!rc\""; break ;;
  299. # esac
  300. # shift
  301. # done
  302. #fi
  303. # check whether command exists in script at all
  304. cmdline=`grep "^%$cmd" $rcdir/rc.$s_name`
  305. if [ ".$cmdline" != . ]; then
  306. # parse local command options
  307. cmdopts=`echo "$cmdline" | sed -e "s;^%$cmd *;;"`
  308. s_user=$user
  309. s_prio=500
  310. s_output=no
  311. set -- $cmdopts
  312. prev=''
  313. for opt
  314. do
  315. if [ ".$prev" != . ]; then
  316. opt="$prev$opt"
  317. prev=''
  318. fi
  319. case $opt in
  320. -*=* ) arg=${opt/-*=/} ;;
  321. -[a-zA-Z]* ) arg=${opt/-[a-zA-Z0-9]/} ;;
  322. *) arg='' ;;
  323. esac
  324. case $opt in
  325. -u|-p ) prev=$opt ;;
  326. -e|--enable ) enable=yes ;;
  327. -d|--disable ) enable=no ;;
  328. -o|--output ) s_output=yes ;;
  329. -u*|--user=* ) s_user=$arg ;;
  330. -p*|--prio=* ) s_prio=$arg ;;
  331. * ) echo "openpkg:rc:WARNING: invalid local option \"$opt\" in \"$rcdir/rc.$s_name:%$cmd\""; break ;;
  332. esac
  333. shift
  334. done
  335. # sanity check: is operation supported by current environment?
  336. if [ ".$s_user" != ".$user" -a ".$user" != ".root" ]; then
  337. echo "openpkg:rc:ERROR: $s_name:%$cmd: require root privileges to run as user \"$s_user\"" 1>&2
  338. exit 1
  339. fi
  340. # skip this script if script is disabled
  341. if [ ".$enable" != .yes ]; then
  342. continue
  343. fi
  344. # accumulate the determined information
  345. list="$list,$s_prio:$s_name:$s_user:$s_output"
  346. else
  347. # command not found in script
  348. if [ ".$isall" = .0 ]; then
  349. echo "openpkg:rc:ERROR: $s_name: command \"$cmd\" not found" 1>&2
  350. exit 1
  351. fi
  352. fi
  353. done
  354. # if operating on all scripts, complain if a non-standard command
  355. # was used and it was not found in any(!) script at all. The
  356. # standard commands are accepted to perform no operation if no
  357. # packages are currently installed which provide such commands.
  358. if [ ".$list" = . -a ".$isall" = .1 ]; then
  359. case "$cmd" in
  360. start|stop|monthly|weekly|daily|hourly|quarterly )
  361. ;;
  362. * )
  363. echo "openpkg:rc:ERROR: command \"$cmd\" not found in any script" 1>&2
  364. rv=1
  365. break
  366. ;;
  367. esac
  368. fi
  369. # generate global (loop invariant) header for script in case of
  370. # --print and --eval (for the execution approach we cannot do
  371. # this, because there a new script is generated from scratch for
  372. # each package.
  373. if [ ".$print" = .1 -o ".$eval" = .1 ]; then
  374. rm -f $tmpfile
  375. touch $tmpfile
  376. # generate: optionally enable shell debugging
  377. if [ ".$debug" = .1 ]; then
  378. echo "set -x" >>$tmpfile
  379. fi
  380. # generate: inclusion of the run-command helper functions
  381. echo ". $rcfunc" >>$tmpfile
  382. # generate: all %config sections of all(!) scripts. We cannot
  383. # just include those which have the current command in it
  384. # because by design all command scripts see the %config
  385. # section of all(!) scripts. Because of $openpkg_rc_def the
  386. # variable, we place the %config section of "openpkg" to the front.
  387. # And we have to extra pre-include the rc.conf to allow
  388. # rc.conf to override the default of $openpkg_rc_def, too.
  389. sed <$rcdir/rc.openpkg >>$tmpfile -e "1,/^%config/d" -e '/^%.*/,$d'
  390. echo ". $rcconf" >>$tmpfile
  391. l_scripts=`/bin/ls $rcdir/rc.* | sed -e "s;^$rcdir/rc\.;;" | egrep -v '^openpkg$'`
  392. for l_name in $l_scripts; do
  393. sed <$rcdir/rc.$l_name >>$tmpfile -e "1,/^%config/d" -e '/^%.*/,$d'
  394. done
  395. # generate: inclusion of the application of override variables
  396. echo ". $rcconf" >>$tmpfile
  397. # for --eval redirect stderr and stdout (but remember stdout)
  398. if [ ".$eval" = .1 ]; then
  399. echo "exec 3<&1- 1>/dev/null 2>/dev/null" >>$tmpfile
  400. fi
  401. fi
  402. # iterate over all packages (in priority order!) where the command
  403. # was found n order to execute, print, or evaluate their scripts
  404. verbose_pos=0
  405. for entry in `echo $list | tr ',' '\012' | sort -n`; do
  406. [ ".$entry" = . ] && continue
  407. # re-determine the script name, script and whether to print output
  408. eval `echo $entry | sed -e 's%^[0-9]*:\(.*\):\(.*\):\(.*\)$%s_name="\1"; s_user="\2"; s_output="\3";%'`
  409. # display verbose progress message parts
  410. if [ ".$print" = .0 -a ".$eval" = .0 -a ".$silent" = .0 ]; then
  411. # line break if we already have output more than 70
  412. # characters (notice that usually already more characters
  413. # where printed, because of the name of the last script)
  414. if [ $verbose_pos -gt 70 ]; then
  415. verbose_pos=0
  416. echo "" 1>&2
  417. fi
  418. # display verbose message parts: prefix (on first), separator and package
  419. if [ $verbose_pos -eq 0 ]; then
  420. output=$(printf "OpenPKG: %s: " "$cmd")
  421. echo -n "$output" 1>&2
  422. verbose_pos=$(($verbose_pos + ${#output}))
  423. output_prefix=""
  424. else
  425. output_prefix=", "
  426. fi
  427. output=$(printf "%s%s" "$output_prefix" "$s_name")
  428. echo -n "$output" 1>&2
  429. verbose_pos=$(($verbose_pos + ${#output}))
  430. fi
  431. # now operate on the particular script
  432. if [ ".$print" = .1 ]; then
  433. # special case: under --print we just add the %common and
  434. # command scripts to the generated output script and do
  435. # not execute anything at this point.
  436. sed <$rcdir/rc.$s_name >>$tmpfile -e "1,/^%common/d" -e '/^%.*/,$d'
  437. sed <$rcdir/rc.$s_name >>$tmpfile -e "1,/^%$cmd/d" -e '/^%.*/,$d'
  438. elif [ ".$eval" = .1 ]; then
  439. # special case: under --eval we just add the %common and
  440. # command scripts to the generated output script and do
  441. # not execute anything at this point. Additionally, we
  442. # emulate a real sub-shell environment.
  443. sed <$rcdir/rc.$s_name >>$tmpfile -e "1,/^%common/d" -e '/^%.*/,$d'
  444. echo "while [ 1 ]; do" >>$tmpfile
  445. sed <$rcdir/rc.$s_name >>$tmpfile -e "1,/^%$cmd/d" -e '/^%.*/,$d' \
  446. -e 's/^exit[^;]*/break 99/' -e 's/\([^a-zA-Z0-9_]\)exit[^;]*/\1break 99/g' \
  447. -e 's/^return[^;]*/break 99/' -e 's/\([^a-zA-Z0-9_]\)return[^;]*/\1break 99/g'
  448. echo "break" >>$tmpfile
  449. echo "done" >>$tmpfile
  450. else
  451. # the regular case of executing the command script directly
  452. # prepare temporary files
  453. rm -f $tmpfile $outfile $errfile
  454. touch $tmpfile $outfile $errfile
  455. # generate: optionally enable shell debugging
  456. if [ ".$debug" = .1 ]; then
  457. echo "set -x" >>$tmpfile
  458. fi
  459. # generate: inclusion of the run-command helper functions
  460. echo ". $rcfunc" >>$tmpfile
  461. # generate: all %config sections of all(!) scripts. We cannot
  462. # just include those which have the current command in it
  463. # because by design all command scripts see the %config
  464. # section of all(!) scripts. Because of $openpkg_rc_def the
  465. # variable, we place the %config section of "openpkg" to the front.
  466. # And we have to extra pre-include the rc.conf to allow
  467. # rc.conf to override the default of $openpkg_rc_def, too.
  468. sed <$rcdir/rc.openpkg >>$tmpfile -e "1,/^%config/d" -e '/^%.*/,$d'
  469. echo ". $rcconf" >>$tmpfile
  470. l_scripts=`/bin/ls $rcdir/rc.* | sed -e "s;^$rcdir/rc\.;;" | egrep -v '^openpkg$'`
  471. for l_name in $l_scripts; do
  472. sed <$rcdir/rc.$l_name >>$tmpfile -e "1,/^%config/d" -e '/^%.*/,$d'
  473. done
  474. # generate: inclusion of the application of override variables
  475. echo ". $rcconf" >>$tmpfile
  476. # generate: %common section and particular command section
  477. sed <$rcdir/rc.$s_name >>$tmpfile -e "1,/^%common/d" -e '/^%.*/,$d'
  478. sed <$rcdir/rc.$s_name >>$tmpfile -e "1,/^%$cmd/d" -e '/^%.*/,$d'
  479. # execute the generated script with GNU Bash
  480. if [ ".$user" != ".$s_user" ]; then
  481. # execute as different user
  482. su - $s_user -c "PATH=\"$PATH\"; $bash $tmpfile" >$outfile 2>$errfile
  483. rc=$?
  484. else
  485. # execute as current user
  486. $bash $tmpfile >$outfile 2>$errfile
  487. rc=$?
  488. fi
  489. if [ $rc -ne 0 ]; then
  490. if [ ".$silent" = .0 ]; then
  491. # indicate failure of execution on verbose message line
  492. echo ":FAILED" 1>&2
  493. verbose_pos=0
  494. fi
  495. # give details of execution failure
  496. ( echo "openpkg:rc:WARNING: $prefix:$s_name:%$cmd: failed with return code $rc" 1>&2
  497. if [ ".`cat $outfile $errfile`" != . ]; then
  498. echo "+----Log:--------------------------------------------------------------"
  499. cat $outfile $errfile | sed -e 's;^;| ;'
  500. echo "+----------------------------------------------------------------------"
  501. fi
  502. ) 1>&2
  503. # enforce global return value
  504. rv=1
  505. else
  506. if [ ".$s_output" = .yes ]; then
  507. # accumulate script output for later display
  508. cat $outfile >>$allfile
  509. fi
  510. fi
  511. fi
  512. done
  513. # post-processing for each command
  514. if [ ".$print" = .1 ]; then
  515. # for --print just print the resulting script to stdout
  516. cat $tmpfile
  517. elif [ ".$eval" = .1 ]; then
  518. # finish generation of temporary script by restoring stdout
  519. # and printing the exported environment variables into a format
  520. # suitable for evaluation by the callers shell.
  521. echo "exec 1<&3-" >>$tmpfile
  522. echo "unset PWD SHLVL" >>$tmpfile
  523. echo "env |\\" >>$tmpfile
  524. echo "egrep '^[A-Z_][A-Z0-9_]*=.' |\\" >>$tmpfile
  525. echo "sed -e 's/\\\\/\\\\\\\\/g' -e 's/\"/\\\\\"/g' \\" >>$tmpfile
  526. case $SHELL in
  527. csh|*/csh|tcsh|*/tcsh )
  528. echo "-e 's/^\\([^=]*\\)=\\(.*\\)\$/setenv \\1 \"\\2\"/'" >>$tmpfile
  529. ;;
  530. * )
  531. echo "-e 's/^\\([^=]*\\)=\\(.*\\)\$/\\1=\"\\2\"; export \\1/'" >>$tmpfile
  532. ;;
  533. esac
  534. # prepare temporary files
  535. rm -f $outfile $errfile
  536. touch $outfile $errfile
  537. # now replace temporary script with its output
  538. # by executing it and capturing its output
  539. env -i \
  540. HOME="$HOME" \
  541. USER="$USER" \
  542. LOGNAME="$LOGNAME" \
  543. TERM="$TERM" \
  544. PATH="$PATH_ORIG" \
  545. MANPATH="$MANPATH" \
  546. INFOPATH="$INFOPATH" \
  547. LD_LIBRARY_PATH="$LD_LIBRARY_PATH" \
  548. $bash --norc --noprofile --posix \
  549. $tmpfile >$outfile 2>/dev/null
  550. cp $outfile $tmpfile
  551. # for --eval we cannot just print the resulting script because
  552. # not all Bourne-Shell implementations like to "eval" large
  553. # multi-line outputs. Hence we output a little one-liner which
  554. # "sources" the script instead and cleans up.
  555. case $SHELL in
  556. csh|*/csh|tcsh|*/tcsh )
  557. echo "source $tmpfile; rm -rf $tmpdir 2>/dev/null || true"
  558. ;;
  559. * )
  560. echo ". $tmpfile; rm -rf $tmpdir 2>/dev/null || true"
  561. ;;
  562. esac
  563. else
  564. # for the execution situation just make sure we
  565. # terminate the verbose message output.
  566. if [ ".$silent" = .0 -a $verbose_pos -gt 0 ]; then
  567. echo "." 1>&2
  568. fi
  569. # additionally, if a script wants its output to be displayed,
  570. # now do it. In case there was no such request, do not bother
  571. # -- we then just output an empty file and so can avoid an
  572. # extra test surrounding the next command.
  573. cat $allfile
  574. fi
  575. done
  576. # cleanup temporary files except the result script in
  577. # case of --eval (which is then removed by the caller).
  578. rm -f $outfile $errfile $allfile >/dev/null 2>&1 || true
  579. if [ ".$eval" = .0 ]; then
  580. rm -f $tmpfile >/dev/null 2>&1 || true
  581. rm -rf $tmpdir >/dev/null 2>&1 || true
  582. fi
  583. # now clean the exit trap and exit with the global return value
  584. # indicating to the caller whether all scripts were executed
  585. # successfully or at least one failed.
  586. trap - EXIT
  587. exit $rv