functions 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488
  1. #!/bin/sh
  2. # From Slackware 11
  3. # Standard functions for launching daemons
  4. COL_SUCCESS="echo -en \\033[70G"
  5. COL_FAILURE="echo -en \\033[70G"
  6. NORMAL="echo -en \\033[0;39m"
  7. SUCCESS="echo -en \\033[1;32m"
  8. FAILURE="echo -en \\033[1;31m"
  9. echon ()
  10. {
  11. echo -n $@
  12. }
  13. # The evaluate_retval function evaluates the return value of the process
  14. # that was run just before this function was called. If the return value
  15. # was 0, indicating success, the print_status function is called with
  16. # the 'success' parameter. Otherwise the print_status function is called
  17. # with the failure parameter
  18. evaluate_retval()
  19. {
  20. if [ $? = 0 ]
  21. then
  22. print_status success
  23. else
  24. print_status failure
  25. fi
  26. }
  27. #
  28. # The print_status prints [ OK ] or [FAILED] to the screen. OK appears
  29. # in the colour defined by the SUCCESS variable and FAILED appears in
  30. # the colour defined by the FAILURE variable. Both are printed starting
  31. # in the column defined by the COL variable.
  32. print_status()
  33. {
  34. #
  35. # If no parameters are given to the print_status function, print usage
  36. # information.
  37. #
  38. if [ $# = 0 ]
  39. then
  40. echo "Usage: print_status {success|failure}"
  41. return 1
  42. fi
  43. case "$1" in
  44. success)
  45. $COL_SUCCESS
  46. echo -n "[ "
  47. $SUCCESS
  48. echo -n "OK"
  49. $NORMAL
  50. echo " ]"
  51. true
  52. ;;
  53. failure)
  54. $COL_FAILURE
  55. echo -n "["
  56. $FAILURE
  57. echo -n "FAILED"
  58. $NORMAL
  59. echo "]"
  60. false
  61. ;;
  62. esac
  63. }
  64. #
  65. # The loadproc function starts a process (often a daemon) with
  66. # proper error checking
  67. loadproc()
  68. {
  69. #
  70. # If no parameters are given to the print_status function, print usage
  71. # information.
  72. #
  73. if [ $# = 0 ]
  74. then
  75. echo "Usage: loadproc {program}"
  76. exit 1
  77. fi
  78. #
  79. # Find the basename of the first parameter (the daemon's name without
  80. # the path
  81. # that was provided so /usr/sbin/syslogd becomes plain 'syslogd' after
  82. # basename ran)
  83. #
  84. base=$(/usr/bin/basename $1)
  85. #
  86. # the pidlist variable will contains the output of the pidof command.
  87. # pidof will try to find the PID's that belong to a certain string;
  88. # $base in this case
  89. #
  90. pidlist=$(/sbin/pidof -o $$ -o $PPID -o %PPID -x $base)
  91. pid=""
  92. for apid in $pidlist
  93. do
  94. if [ -d /proc/$apid ]
  95. then
  96. pid="$pid $apid"
  97. fi
  98. done
  99. #
  100. # If the $pid variable contains anything (from the previous for loop) it
  101. # means the daemon is already running
  102. #
  103. if [ ! -n "$pid" ]
  104. then
  105. #
  106. # Empty $pid variable means it's not running, so we run $* (all
  107. # parameters giving to this function from the script) and then check the
  108. # return value
  109. #
  110. $*
  111. evaluate_retval
  112. else
  113. #
  114. # The variable $pid was not empty, meaning it was already running. We
  115. # print [FAILED] now
  116. #
  117. print_status failure
  118. fi
  119. }
  120. #
  121. # The killproc function kills a process with proper error checking
  122. #
  123. killproc()
  124. {
  125. #
  126. # If no parameters are given to the print_status function, print usage
  127. # information.
  128. #
  129. if [ $# = 0 ]
  130. then
  131. echo "Usage: killproc {program} [signal]"
  132. exit 1
  133. fi
  134. #
  135. # Find the basename of the first parameter (the daemon's name without
  136. # the path
  137. # that was provided so /usr/sbin/syslogd becomes plain 'syslogd' after
  138. # basename ran)
  139. #
  140. base=$(/usr/bin/basename $1)
  141. #
  142. # Check if we gave a signal to kill the process with (like -HUP, -TERM,
  143. # -KILL, etc) to this function (the second parameter). If no second
  144. # parameter was provided set the nolevel variable. Else set the
  145. # killlevel variable to the value of $2 (the second parameter)
  146. #
  147. if [ "$2" != "" ]
  148. then
  149. killlevel=-$2
  150. else
  151. nolevel=1
  152. fi
  153. #
  154. # the pidlist variable will contains the output of the pidof command.
  155. # pidof will try to find the PID's that belong to a certain string;
  156. # $base in this case
  157. #
  158. pidlist=$(/sbin/pidof -o $$ -o $PPID -o %PPID -x $base)
  159. pid=""
  160. for apid in $pidlist
  161. do
  162. if [ -d /proc/$apid ]
  163. then
  164. pid="$pid $apid"
  165. fi
  166. done
  167. #
  168. # If $pid contains something from the previous for loop it means one or
  169. # more PID's were found that belongs to the processes to be killed
  170. #
  171. if [ -n "$pid" ]
  172. then
  173. #
  174. # If no kill level was specified we'll try -TERM first and then sleep
  175. # for 2 seconds to allow the kill to be completed
  176. #
  177. if [ "$nolevel" = 1 ]
  178. then
  179. /bin/kill -TERM $pid
  180. #
  181. # If after -TERM the PID still exists we'll wait 2 seconds before
  182. # trying to kill it with -KILL. If the PID still exist after that, wait
  183. # two more seconds. If the PIDs still exist by then it's safe to assume
  184. # that we cannot kill these PIDs.
  185. #
  186. if /bin/ps h $pid >/dev/null 2>&1
  187. then
  188. /bin/sleep 2
  189. if /bin/ps h $pid > /dev/null 2>&1
  190. then
  191. /bin/kill -KILL $pid
  192. if /bin/ps h $pid > /dev/null 2>&1
  193. then
  194. /bin/sleep 2
  195. fi
  196. fi
  197. fi
  198. /bin/ps h $pid >/dev/null 2>&1
  199. if [ $? = 0 ]
  200. then
  201. #
  202. # If after the -KILL it still exists it can't be killed for some reason
  203. # and we'll print [FAILED]
  204. #
  205. print_status failure
  206. else
  207. #
  208. # It was killed, remove possible stale PID file in /var/run and
  209. # print [ OK ]
  210. #
  211. /bin/rm -f /var/run/$base.pid
  212. print_status success
  213. fi
  214. else
  215. #
  216. # A kill level was provided. Kill with the provided kill level and wait
  217. # for 2 seconds to allow the kill to be completed
  218. #
  219. /bin/kill $killlevel $pid
  220. if /bin/ps h $pid > /dev/null 2>&1
  221. then
  222. /bin/sleep 2
  223. fi
  224. /bin/ps h $pid >/dev/null 2>&1
  225. if [ $? = 0 ]
  226. then
  227. #
  228. # If ps' return value is 0 it means it ran ok which indicates that the
  229. # PID still exists. This means the process wasn't killed properly with
  230. # the signal provided. Print [FAILED]
  231. #
  232. print_status failure
  233. else
  234. #
  235. # If the return value was 1 or higher it means the PID didn't exist
  236. # anymore which means it was killed successfully. Remove possible stale
  237. # PID file and print [ OK ]
  238. #
  239. /bin/rm -f /var/run/$base.pid
  240. print_status success
  241. fi
  242. fi
  243. else
  244. #
  245. # The PID didn't exist so we can't attempt to kill it. Print [FAILED]
  246. #
  247. print_status failure
  248. fi
  249. }
  250. #
  251. # The reloadproc functions sends a signal to a daemon telling it to
  252. # reload it's configuration file. This is almost identical to the
  253. # killproc function with the exception that it won't try to kill it with
  254. # a -KILL signal (aka -9)
  255. #
  256. reloadproc()
  257. {
  258. #
  259. # If no parameters are given to the print_status function, print usage
  260. # information.
  261. #
  262. if [ $# = 0 ]
  263. then
  264. echo "Usage: reloadproc {program} [signal]"
  265. exit 1
  266. fi
  267. #
  268. # Find the basename of the first parameter (the daemon's name without
  269. # the path that was provided so /usr/sbin/syslogd becomes plain 'syslogd'
  270. # after basename ran)
  271. #
  272. base=$(/usr/bin/basename $1)
  273. #
  274. # Check if we gave a signal to send to the process (like -HUP)
  275. # to this function (the second parameter). If no second
  276. # parameter was provided set the nolevel variable. Else set the
  277. # killlevel variable to the value of $2 (the second parameter)
  278. #
  279. if [ -n "$2" ]
  280. then
  281. killlevel=-$2
  282. else
  283. nolevel=1
  284. fi
  285. #
  286. # the pidlist variable will contains the output of the pidof command.
  287. # pidof will try to find the PID's that belong to a certain string;
  288. # $base in this case
  289. #
  290. pidlist=$(/sbin/pidof -o $$ -o $PPID -o %PPID -x $base)
  291. pid=""
  292. for apid in $pidlist
  293. do
  294. if [ -d /proc/$apid ]
  295. then
  296. pid="$pid $apid"
  297. fi
  298. done
  299. #
  300. # If $pid contains something from the previous for loop it means one or
  301. # more PID's were found that belongs to the processes to be reloaded
  302. #
  303. if [ -n "$pid" ]
  304. then
  305. #
  306. # If nolevel was set we will use the default reload signal SIGHUP.
  307. #
  308. if [ "$nolevel" = 1 ]
  309. then
  310. /bin/kill -SIGHUP $pid
  311. evaluate_retval
  312. else
  313. #
  314. # Else we will use the provided signal
  315. #
  316. /bin/kill $killlevel $pid
  317. evaluate_retval
  318. fi
  319. else
  320. #
  321. # If $pid is empty no PID's have been found that belong to the process
  322. # and print [FAILED]
  323. #
  324. print_status failure
  325. fi
  326. }
  327. #
  328. # The checkloadproc functions start a daemon if it is not running
  329. checkloadproc()
  330. {
  331. #
  332. # If no parameters are given to the print_status function, print usage
  333. # information.
  334. #
  335. if [ $# = 0 ]
  336. then
  337. echo "Usage: checkloadproc {program} [ param ..]"
  338. exit 1
  339. fi
  340. #
  341. # Find the basename of the first parameter (the daemon's name without
  342. # the path that was provided so /usr/sbin/syslogd becomes plain 'syslogd'
  343. # after basename ran)
  344. #
  345. base=$(/usr/bin/basename $1)
  346. #
  347. # the pidlist variable will contains the output of the pidof command.
  348. # pidof will try to find the PID's that belong to a certain string;
  349. # $base in this case
  350. #
  351. pidlist=$(/sbin/pidof -o $$ -o $PPID -o %PPID -x $base)
  352. pid=""
  353. for apid in $pidlist
  354. do
  355. if [ -d /proc/$apid ]
  356. then
  357. pid="$pid $apid"
  358. fi
  359. done
  360. #
  361. # If $pid contains something from the previous for loop it means one or
  362. # more PID's were found that belongs to the processes. Dont start it
  363. #
  364. if [ -n "$pid" ]
  365. then
  366. print_status success
  367. else
  368. # Start it
  369. loadproc $*
  370. fi
  371. }
  372. #
  373. # The statusproc function will try to find out if a process is running
  374. # or not
  375. #
  376. statusproc()
  377. {
  378. #
  379. # If no parameters are given to the print_status function, print usage
  380. # information.
  381. #
  382. if [ $# = 0 ]
  383. then
  384. echo "Usage: status {program}"
  385. return 1
  386. fi
  387. #
  388. # $pid will contain a list of PID's that belong to a process
  389. #
  390. pid=$(/sbin/pidof -o $$ -o $PPID -o %PPID -x $1)
  391. if [ -n "$pid" ]
  392. then
  393. #
  394. # If $pid contains something, the process is running, print the contents
  395. # of the $pid variable
  396. #
  397. echo "$1 running with Process ID $pid"
  398. return 0
  399. fi
  400. #
  401. # If $pid doesn't contain it check if a PID file exists and inform the
  402. # user about this stale file.
  403. #
  404. if [ -f /var/run/$1.pid ]
  405. then
  406. pid=$(/usr/bin/head -1 /var/run/$1.pid)
  407. if [ -n "$pid" ]
  408. then
  409. echo "$1 not running but /var/run/$1.pid exists"
  410. return 1
  411. fi
  412. else
  413. echo "$1 is not running"
  414. return 1
  415. fi
  416. }
  417. # End /etc/init.d/functions