rc 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  1. #!@l_prefix@/lib/openpkg/bash
  2. ##
  3. ## @l_prefix@/etc/rc -- Run-Command Handling for OpenPKG Hierarchy
  4. ## Copyright (c) 2000-2001 Cable & Wireless Deutschland GmbH
  5. ## Copyright (c) 2000-2001 Ralf S. Engelschall <rse@engelschall.com>
  6. ##
  7. ## Permission to use, copy, modify, and distribute this software for
  8. ## any purpose with or without fee is hereby granted, provided that
  9. ## the above copyright notice and this permission notice appear in all
  10. ## copies.
  11. ##
  12. ## THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
  13. ## WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  14. ## MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  15. ## IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR
  16. ## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  17. ## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  18. ## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  19. ## USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  20. ## ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  21. ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  22. ## OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  23. ## SUCH DAMAGE.
  24. ##
  25. # program name, version and date
  26. progname="rc"
  27. progvers="1.0.8"
  28. progdate="02-Nov-2001"
  29. # helper variables
  30. NL="
  31. "
  32. ##
  33. ## command line option parsing
  34. ##
  35. # default parameters
  36. verbose=0
  37. help=0
  38. print=0
  39. eval=0
  40. config=0
  41. query=0
  42. raw=0
  43. rcdir="@l_prefix@/etc/rc.d"
  44. # iterate over argument line
  45. while [ $# -gt 0 ]; do
  46. opt=$1
  47. case $opt in
  48. -*=*) arg=`echo "$opt" | sed 's/^[-_a-zA-Z0-9]*=//'` ;;
  49. *) arg='' ;;
  50. esac
  51. case $opt in
  52. -v|--verbose ) verbose=1 ;;
  53. -h|--help ) help=1 ;;
  54. -p|--print ) print=1 ;;
  55. -e|--eval ) eval=1 ;;
  56. -c|--config ) config=1 ;;
  57. -q|--query ) query=1 ;;
  58. -r|--raw ) raw=1 ;;
  59. --rcdir=* ) rcdir=$arg ;;
  60. -* ) help="Invalid option \`$opt'"; break ;;
  61. * ) break ;;
  62. esac
  63. shift
  64. done
  65. # determine path to rc.conf
  66. rcconf="`echo $rcdir | sed -e 's;/rc.d$;/rc.conf;'`"
  67. rcfunc="`echo $rcdir | sed -e 's;/rc.d$;/rc.func;'`"
  68. # error or usage message
  69. if [ ".$help" != .0 ]; then
  70. if [ ".$help" != ".Usage" ]; then
  71. echo "$progname:ERROR: $help" 1>&2
  72. fi
  73. echo "Usage: $progname [-v|--verbose] [-h|--help]" 1>&2
  74. echo " [-p|--print] [-e|--eval] [-c|--config] [-q|--query] [-r|--raw]" 1>&2
  75. echo " <package> <command> [<command> ...]" 1>&2
  76. fi
  77. # extend run-time environment with our local tools (shtool, rpmtool, etc)
  78. PATH="@l_prefix@/bin:$PATH"
  79. PATH="@l_prefix@/sbin:$PATH"
  80. PATH="@l_prefix@/lib/openpkg:$PATH"
  81. # find a reasonable temporary location
  82. if [ ".$TMPDIR" != . ]; then
  83. tmpdir="$TMPDIR"
  84. elif [ ".$TEMPDIR" != . ]; then
  85. tmpdir="$TEMPDIR"
  86. else
  87. tmpdir="/tmp"
  88. fi
  89. tmpfile="$tmpdir/rc.$$.tmp"
  90. # handle --query option
  91. if [ ".$query" = .1 ]; then
  92. var="$1"
  93. scripts=`ls $rcdir/rc.* | sed -e "s;^$rcdir/rc\.;;"`
  94. rm -f $tmpfile
  95. touch $tmpfile
  96. for s_name in $scripts; do
  97. sed <$rcdir/rc.$s_name >>$tmpfile -e "1,/^%config/d" -e '/^%.*/,$d'
  98. done
  99. . $tmpfile
  100. . $rcconf
  101. eval "echo \${$var}"
  102. exit 0
  103. fi
  104. # handle --config option
  105. if [ ".$config" = .1 ]; then
  106. scripts=`ls $rcdir/rc.* | sed -e "s;^$rcdir/rc\.;;"`
  107. rm -f $tmpfile
  108. touch $tmpfile
  109. for s_name in $scripts; do
  110. sed <$rcdir/rc.$s_name >>$tmpfile -e "1,/^%config/d" -e '/^%.*/,$d'
  111. done
  112. vars=""
  113. . $tmpfile
  114. OIFS="$IFS"; IFS="$NL"
  115. for assign in `egrep '[ ]*[a-zA-Z_][a-zA-Z_0-9]*=' $tmpfile | sort`; do
  116. var=`echo "$assign" | sed -e 's;^[ ]*\([a-zA-Z_][a-zA-Z_0-9]*\)=.*;\1;'`
  117. vars="$vars $var"
  118. eval "${var}_def=\"\$$var\""
  119. done
  120. IFS="$OIFS"
  121. . $rcconf
  122. if [ ".$raw" = ".0" ]; then
  123. begin_bold=`@l_prefix@/lib/openpkg/shtool echo -e '%B'`
  124. end_bold=`@l_prefix@/lib/openpkg/shtool echo -e '%b'`
  125. else
  126. begin_bold=""
  127. end_bold=""
  128. fi
  129. echo "${begin_bold}Configuration Variable Effective Value Default Value${end_bold}"
  130. echo "------------------------ ------------------------- -- -------------------------"
  131. for var in . $vars; do
  132. test ".$var" = .. && continue
  133. eval "val=\"\$$var\""
  134. eval "def=\"\$${var}_def\""
  135. tag="!="
  136. begin="$begin_bold"
  137. end="$end_bold"
  138. if [ ".$val" = ".$def" ]; then
  139. tag="=="
  140. begin=""
  141. end=""
  142. fi
  143. echo dummy | awk '{ printf("%s%-24s %-25s %s %-25s%s\n", begin, var, val, tag, def, end); }' \
  144. begin="$begin" var="$var" tag="$tag" val="\"$val\"" def="\"$def\"" end="$end"
  145. done
  146. exit 0
  147. fi
  148. # determine script(s) to use
  149. if [ $# -lt 2 ]; then
  150. echo "$0:ERROR: no package and command(s) specified" 1>&2
  151. exit 1
  152. fi
  153. scripts=`echo "$1" | sed -e 's;^.*rc\.;;'`
  154. shift
  155. if [ ".$scripts" = ".all" ]; then
  156. scripts=`ls $rcdir/rc.* | sed -e "s;^$rcdir/rc\.;;"`
  157. else
  158. if [ ! -f "$rcdir/rc.$scripts" ]; then
  159. echo "$0:ERROR: script \`$rcdir/rc.$scripts' not found" 1>&2
  160. exit 1
  161. fi
  162. fi
  163. # determine current run-time user
  164. user="$LOGNAME"
  165. if [ ".$user" = . ]; then
  166. user="$USER"
  167. if [ ".$user" = . ]; then
  168. user="`(whoami) 2>/dev/null | awk '{ printf("%s", $1); }'`"
  169. if [ ".$user" = . ]; then
  170. user="`(who am i) 2>/dev/null | awk '{ printf("%s", $1); }'`"
  171. if [ ".$user" = . ]; then
  172. echo "$0:ERROR: unable to determine current username" 1>&2
  173. exit 1
  174. fi
  175. fi
  176. fi
  177. fi
  178. # iterate over the commands
  179. cmds="$*"
  180. for cmd in $cmds; do
  181. # find scripts which contain the command and determine
  182. # their individual user/prio settings
  183. list=''
  184. for s_name in $scripts; do
  185. enable=yes
  186. # check script options
  187. shebangline=`head -1 $rcdir/rc.$s_name | grep "^#!rc"`
  188. if [ ".$shebangline" != . ]; then
  189. shebangopts=`echo "$shebangline" | sed -e "s;^#!rc *;;"`
  190. set -- $shebangopts;
  191. prev=''
  192. for opt
  193. do
  194. if [ ".$prev" != . ]; then
  195. opt="$prev$opt"
  196. prev=''
  197. fi
  198. case $opt in
  199. -*=* ) arg=`echo "$opt" | sed 's/^[-_a-zA-Z0-9]*=//'` ;;
  200. -[a-zA-Z]* ) arg=`echo "$opt" | sed 's/^-[a-zA-Z0-9]//'` ;;
  201. *) arg='' ;;
  202. esac
  203. case $opt in
  204. -e|--enable ) enable=yes ;;
  205. -d|--disable ) enable=no ;;
  206. * ) echo "$0:ERROR: invalid option \`$opt' in \`$rcdir/rc.$s_name:#!rc'"; break ;;
  207. esac
  208. shift
  209. done
  210. fi
  211. # check whether command exists in script
  212. cmdline=`grep "^%$cmd" $rcdir/rc.$s_name`
  213. if [ ".$cmdline" != . ]; then
  214. cmdopts=`echo "$cmdline" | sed -e "s;^%$cmd *;;"`
  215. s_user=$user
  216. s_prio=500
  217. set -- $cmdopts;
  218. prev=''
  219. for opt
  220. do
  221. if [ ".$prev" != . ]; then
  222. opt="$prev$opt"
  223. prev=''
  224. fi
  225. case $opt in
  226. -*=* ) arg=`echo "$opt" | sed 's/^[-_a-zA-Z0-9]*=//'` ;;
  227. -[a-zA-Z]* ) arg=`echo "$opt" | sed 's/^-[a-zA-Z0-9]//'` ;;
  228. *) arg='' ;;
  229. esac
  230. case $opt in
  231. -u|-p ) prev=$opt ;;
  232. -e|--enable ) enable=yes ;;
  233. -d|--disable ) enable=no ;;
  234. -u*|--user=* ) s_user=$arg ;;
  235. -p*|--prio=* ) s_prio=$arg ;;
  236. * ) echo "$0:ERROR: invalid option \`$opt' in \`$rcdir/rc.$s_name'"; break ;;
  237. esac
  238. shift
  239. done
  240. if [ ".$s_user" != ".$user" -a ".$user" != ".root" ]; then
  241. echo "$0:ERROR: require root priviledges to run \`$rcdir/rc.$s_name:$cmd' as user \`$s_user'" 1>&2
  242. exit 1
  243. fi
  244. # skip script if disabled
  245. if [ ".$enable" != .yes ]; then
  246. continue
  247. fi
  248. list="$list,$s_prio:$s_name:$s_user"
  249. fi
  250. done
  251. # execute/print the scripts in order
  252. if [ ".$print" = .1 -o ".$eval" = .1 ]; then
  253. rm -f $tmpfile
  254. touch $tmpfile
  255. if [ ".$verbose" = .1 ]; then
  256. echo "set -x" >>$tmpfile
  257. fi
  258. fi
  259. for entry in `echo $list | tr ',' '\012' | sort`; do
  260. test ".$entry" = . && continue
  261. eval `echo $entry | sed -e 's%^[0-9]*:\(.*\):\(.*\)$%s_name="\1"; s_user="\2"%'`
  262. if [ ".$verbose" = .1 ]; then
  263. echo "$0: executing $rcdir/rc.$s_name [%$cmd] as user $s_user" 1>&2
  264. fi
  265. if [ ".$print" = .1 -o ".$eval" = .1 ]; then
  266. echo ". $rcfunc" >>$tmpfile
  267. sed <$rcdir/rc.$s_name >>$tmpfile -e "1,/^%config/d" -e '/^%.*/,$d'
  268. echo ". $rcconf" >>$tmpfile
  269. sed <$rcdir/rc.$s_name >>$tmpfile -e "1,/^%common/d" -e '/^%.*/,$d'
  270. sed <$rcdir/rc.$s_name >>$tmpfile -e "1,/^%$cmd/d" -e '/^%.*/,$d'
  271. continue
  272. fi
  273. rm -f $tmpfile
  274. touch $tmpfile
  275. if [ ".$verbose" = .1 ]; then
  276. echo "set -x" >>$tmpfile
  277. fi
  278. echo ". $rcfunc" >>$tmpfile
  279. sed <$rcdir/rc.$s_name >>$tmpfile -e "1,/^%config/d" -e '/^%.*/,$d'
  280. echo ". $rcconf" >>$tmpfile
  281. sed <$rcdir/rc.$s_name >>$tmpfile -e "1,/^%common/d" -e '/^%.*/,$d'
  282. sed <$rcdir/rc.$s_name >>$tmpfile -e "1,/^%$cmd/d" -e '/^%.*/,$d'
  283. sh='sh'
  284. if [ ".$user" != ".$s_user" ]; then
  285. su $s_user -c "sh $tmpfile"
  286. rc=$?
  287. else
  288. sh $tmpfile
  289. rc=$?
  290. fi
  291. if [ $rc -ne 0 ]; then
  292. echo "$0:WARNING: script \`$rcdir/rc.$s_name:$cmd' returned non-null ($#) return code" 1>&2
  293. fi
  294. done
  295. if [ ".$print" = .1 ]; then
  296. cat $tmpfile
  297. elif [ ".$eval" = .1 ]; then
  298. echo ". $tmpfile; rm -f $tmpfile 2>/dev/null || true"
  299. fi
  300. done
  301. # cleanup
  302. if [ ".$eval" = .0 ]; then
  303. rm -f $tmpfile >/dev/null 2>&1 || true
  304. fi