rc 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  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. ##
  30. ## command line option parsing
  31. ##
  32. # default parameters
  33. verbose=0
  34. help=0
  35. print=0
  36. eval=0
  37. config=0
  38. query=0
  39. raw=0
  40. rcdir="@l_prefix@/etc/rc.d"
  41. # iterate over argument line
  42. while [ $# -gt 0 ]; do
  43. opt=$1
  44. case $opt in
  45. -*=*) arg=`echo "$opt" | sed 's/^[-_a-zA-Z0-9]*=//'` ;;
  46. *) arg='' ;;
  47. esac
  48. case $opt in
  49. -v|--verbose ) verbose=1 ;;
  50. -h|--help ) help=1 ;;
  51. -p|--print ) print=1 ;;
  52. -e|--eval ) eval=1 ;;
  53. -c|--config ) config=1 ;;
  54. -q|--query ) query=1 ;;
  55. -r|--raw ) raw=1 ;;
  56. --rcdir=* ) rcdir=$arg ;;
  57. -* ) help="Invalid option \`$opt'"; break ;;
  58. * ) break ;;
  59. esac
  60. shift
  61. done
  62. # determine path to rc.conf
  63. rcconf="`echo $rcdir | sed -e 's;/rc.d$;/rc.conf;'`"
  64. rcfunc="`echo $rcdir | sed -e 's;/rc.d$;/rc.func;'`"
  65. # error or usage message
  66. if [ ".$help" != .0 ]; then
  67. if [ ".$help" != ".Usage" ]; then
  68. echo "$progname:ERROR: $help" 1>&2
  69. fi
  70. echo "Usage: $progname [-v|--verbose] [-h|--help]" 1>&2
  71. echo " [-p|--print] [-e|--eval] [-c|--config] [-q|--query] [-r|--raw]" 1>&2
  72. echo " <package> <command> [<command> ...]" 1>&2
  73. fi
  74. # extend run-time environment with our local tools (shtool, rpmtool, etc)
  75. PATH="@l_prefix@/bin:$PATH"
  76. PATH="@l_prefix@/sbin:$PATH"
  77. PATH="@l_prefix@/lib/openpkg:$PATH"
  78. # find a reasonable temporary location
  79. if [ ".$TMPDIR" != . ]; then
  80. tmpdir="$TMPDIR"
  81. elif [ ".$TEMPDIR" != . ]; then
  82. tmpdir="$TEMPDIR"
  83. else
  84. tmpdir="/tmp"
  85. fi
  86. tmpfile="$tmpdir/rc.$$.tmp"
  87. # handle --query option
  88. if [ ".$query" = .1 ]; then
  89. var="$1"
  90. scripts=`ls $rcdir/rc.* | sed -e "s;^$rcdir/rc\.;;"`
  91. rm -f $tmpfile
  92. touch $tmpfile
  93. for s_name in $scripts; do
  94. sed <$rcdir/rc.$s_name >>$tmpfile -e "1,/^%config/d" -e '/^%.*/,$d'
  95. done
  96. . $tmpfile
  97. . $rcconf
  98. eval "echo \${$var}"
  99. exit 0
  100. fi
  101. # handle --config option
  102. if [ ".$config" = .1 ]; then
  103. scripts=`ls $rcdir/rc.* | sed -e "s;^$rcdir/rc\.;;"`
  104. rm -f $tmpfile
  105. touch $tmpfile
  106. for s_name in $scripts; do
  107. sed <$rcdir/rc.$s_name >>$tmpfile -e "1,/^%config/d" -e '/^%.*/,$d'
  108. done
  109. vars=""
  110. . $tmpfile
  111. for assign in . `egrep '[ ]*[a-zA-Z_][a-zA-Z_0-9]*=' $tmpfile | sort`; do
  112. test ".$assign" = .. && continue
  113. var=`echo "$assign" | sed -e 's;^[ ]*\([a-zA-Z_][a-zA-Z_0-9]*\)=.*;\1;'`
  114. vars="$vars $var"
  115. eval "${var}_def=\"\$$var\""
  116. done
  117. . $rcconf
  118. if [ ".$raw" = ".0" ]; then
  119. begin_bold=`@l_prefix@/lib/openpkg/shtool echo -e '%B'`
  120. end_bold=`@l_prefix@/lib/openpkg/shtool echo -e '%b'`
  121. else
  122. begin_bold=""
  123. end_bold=""
  124. fi
  125. echo "${begin_bold}Configuration Variable Effective Value Default Value${end_bold}"
  126. echo "------------------------ ------------------------- -- -------------------------"
  127. for var in . $vars; do
  128. test ".$var" = .. && continue
  129. eval "val=\"\$$var\""
  130. eval "def=\"\$${var}_def\""
  131. tag="!="
  132. begin="$begin_bold"
  133. end="$end_bold"
  134. if [ ".$val" = ".$def" ]; then
  135. tag="=="
  136. begin=""
  137. end=""
  138. fi
  139. echo dummy | awk '{ printf("%s%-24s %-25s %s %-25s%s\n", begin, var, val, tag, def, end); }' \
  140. begin="$begin" var="$var" tag="$tag" val="\"$val\"" def="\"$def\"" end="$end"
  141. done
  142. exit 0
  143. fi
  144. # determine script(s) to use
  145. if [ $# -lt 2 ]; then
  146. echo "$0:ERROR: no package and command(s) specified" 1>&2
  147. exit 1
  148. fi
  149. scripts=`echo "$1" | sed -e 's;^.*rc\.;;'`
  150. shift
  151. if [ ".$scripts" = ".all" ]; then
  152. scripts=`ls $rcdir/rc.* | sed -e "s;^$rcdir/rc\.;;"`
  153. else
  154. if [ ! -f "$rcdir/rc.$scripts" ]; then
  155. echo "$0:ERROR: script \`$rcdir/rc.$scripts' not found" 1>&2
  156. exit 1
  157. fi
  158. fi
  159. # determine current run-time user
  160. user="$LOGNAME"
  161. if [ ".$user" = . ]; then
  162. user="$USER"
  163. if [ ".$user" = . ]; then
  164. user="`(whoami) 2>/dev/null | awk '{ printf("%s", $1); }'`"
  165. if [ ".$user" = . ]; then
  166. user="`(who am i) 2>/dev/null | awk '{ printf("%s", $1); }'`"
  167. if [ ".$user" = . ]; then
  168. echo "$0:ERROR: unable to determine current username" 1>&2
  169. exit 1
  170. fi
  171. fi
  172. fi
  173. fi
  174. # iterate over the commands
  175. cmds="$*"
  176. for cmd in $cmds; do
  177. # find scripts which contain the command and determine
  178. # their individual user/prio settings
  179. list=''
  180. for s_name in $scripts; do
  181. enable=yes
  182. # check script options
  183. shebangline=`head -1 $rcdir/rc.$s_name | grep "^#!rc"`
  184. if [ ".$shebangline" != . ]; then
  185. shebangopts=`echo "$shebangline" | sed -e "s;^#!rc *;;"`
  186. set -- $shebangopts;
  187. prev=''
  188. for opt
  189. do
  190. if [ ".$prev" != . ]; then
  191. opt="$prev$opt"
  192. prev=''
  193. fi
  194. case $opt in
  195. -*=* ) arg=`echo "$opt" | sed 's/^[-_a-zA-Z0-9]*=//'` ;;
  196. -[a-zA-Z]* ) arg=`echo "$opt" | sed 's/^-[a-zA-Z0-9]//'` ;;
  197. *) arg='' ;;
  198. esac
  199. case $opt in
  200. -e|--enable ) enable=yes ;;
  201. -d|--disable ) enable=no ;;
  202. * ) echo "$0:ERROR: invalid option \`$opt' in \`$rcdir/rc.$s_name:#!rc'"; break ;;
  203. esac
  204. shift
  205. done
  206. fi
  207. # check whether command exists in script
  208. cmdline=`grep "^%$cmd" $rcdir/rc.$s_name`
  209. if [ ".$cmdline" != . ]; then
  210. cmdopts=`echo "$cmdline" | sed -e "s;^%$cmd *;;"`
  211. s_user=$user
  212. s_prio=500
  213. set -- $cmdopts;
  214. prev=''
  215. for opt
  216. do
  217. if [ ".$prev" != . ]; then
  218. opt="$prev$opt"
  219. prev=''
  220. fi
  221. case $opt in
  222. -*=* ) arg=`echo "$opt" | sed 's/^[-_a-zA-Z0-9]*=//'` ;;
  223. -[a-zA-Z]* ) arg=`echo "$opt" | sed 's/^-[a-zA-Z0-9]//'` ;;
  224. *) arg='' ;;
  225. esac
  226. case $opt in
  227. -u|-p ) prev=$opt ;;
  228. -e|--enable ) enable=yes ;;
  229. -d|--disable ) enable=no ;;
  230. -u*|--user=* ) s_user=$arg ;;
  231. -p*|--prio=* ) s_prio=$arg ;;
  232. * ) echo "$0:ERROR: invalid option \`$opt' in \`$rcdir/rc.$s_name'"; break ;;
  233. esac
  234. shift
  235. done
  236. if [ ".$s_user" != ".$user" -a ".$user" != ".root" ]; then
  237. echo "$0:ERROR: require root priviledges to run \`$rcdir/rc.$s_name:$cmd' as user \`$s_user'" 1>&2
  238. exit 1
  239. fi
  240. # skip script if disabled
  241. if [ ".$enable" != .yes ]; then
  242. continue
  243. fi
  244. list="$list,$s_prio:$s_name:$s_user"
  245. fi
  246. done
  247. # execute/print the scripts in order
  248. if [ ".$print" = .1 -o ".$eval" = .1 ]; then
  249. rm -f $tmpfile
  250. touch $tmpfile
  251. if [ ".$verbose" = .1 ]; then
  252. echo "set -x" >>$tmpfile
  253. fi
  254. fi
  255. for entry in `echo $list | tr ',' '\012' | sort`; do
  256. test ".$entry" = . && continue
  257. eval `echo $entry | sed -e 's%^[0-9]*:\(.*\):\(.*\)$%s_name="\1"; s_user="\2"%'`
  258. if [ ".$verbose" = .1 ]; then
  259. echo "$0: executing $rcdir/rc.$s_name [%$cmd] as user $s_user" 1>&2
  260. fi
  261. if [ ".$print" = .1 -o ".$eval" = .1 ]; then
  262. echo ". $rcfunc" >>$tmpfile
  263. sed <$rcdir/rc.$s_name >>$tmpfile -e "1,/^%config/d" -e '/^%.*/,$d'
  264. echo ". $rcconf" >>$tmpfile
  265. sed <$rcdir/rc.$s_name >>$tmpfile -e "1,/^%common/d" -e '/^%.*/,$d'
  266. sed <$rcdir/rc.$s_name >>$tmpfile -e "1,/^%$cmd/d" -e '/^%.*/,$d'
  267. continue
  268. fi
  269. rm -f $tmpfile
  270. touch $tmpfile
  271. if [ ".$verbose" = .1 ]; then
  272. echo "set -x" >>$tmpfile
  273. fi
  274. echo ". $rcfunc" >>$tmpfile
  275. sed <$rcdir/rc.$s_name >>$tmpfile -e "1,/^%config/d" -e '/^%.*/,$d'
  276. echo ". $rcconf" >>$tmpfile
  277. sed <$rcdir/rc.$s_name >>$tmpfile -e "1,/^%common/d" -e '/^%.*/,$d'
  278. sed <$rcdir/rc.$s_name >>$tmpfile -e "1,/^%$cmd/d" -e '/^%.*/,$d'
  279. sh='sh'
  280. if [ ".$user" != ".$s_user" ]; then
  281. su $s_user -c "sh $tmpfile"
  282. rc=$?
  283. else
  284. sh $tmpfile
  285. rc=$?
  286. fi
  287. if [ $rc -ne 0 ]; then
  288. echo "$0:WARNING: script \`$rcdir/rc.$s_name:$cmd' returned non-null ($#) return code" 1>&2
  289. fi
  290. done
  291. if [ ".$print" = .1 ]; then
  292. cat $tmpfile
  293. elif [ ".$eval" = .1 ]; then
  294. echo ". $tmpfile; rm -f $tmpfile 2>/dev/null || true"
  295. fi
  296. done
  297. # cleanup
  298. if [ ".$eval" = .0 ]; then
  299. rm -f $tmpfile >/dev/null 2>&1 || true
  300. fi