init-functions 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348
  1. #*******************************************************************************
  2. # Function - start_daemon [-f] [-n nicelevel] [-p pidfile] pathname [args]
  3. #
  4. # Purpose: This runs the specified program as a daemon
  5. #
  6. # Inputs: -f, run the program even if it is already running
  7. # -n nicelevel, specifies a nice level. See nice(1).
  8. # -p pidfile, uses the specified pidfile
  9. # pathname, pathname to the specified program
  10. # args, arguments to pass to specified program
  11. #
  12. # Outputs: return 0 - Success
  13. # return 2 - Invalid or excessive number of arguments,
  14. # warning in stdout
  15. # return 4 - Program or service status is unknown
  16. #
  17. # Dependencies: nice
  18. #
  19. # Todo: none
  20. #
  21. #*******************************************************************************
  22. start_daemon()
  23. {
  24. local pidfile=""
  25. local forcestart=""
  26. local nicelevel="0"
  27. while true
  28. do
  29. case "${1}" in
  30. -f)
  31. forcestart="1"
  32. shift 1
  33. ;;
  34. -n)
  35. nicelevel="${2}"
  36. shift 2
  37. ;;
  38. -p)
  39. pidfile="${2}"
  40. shift 2
  41. ;;
  42. -*)
  43. log_failure_msg "Unknown Option: ${1}"
  44. return 2
  45. ;;
  46. *)
  47. break
  48. ;;
  49. esac
  50. done
  51. if [ -z "${forcestart}" ]; then
  52. if [ -z "${pidfile}" ]; then
  53. pidofproc "${1}" > /dev/null
  54. else
  55. pidofproc -p "${pidfile}" "${1}" > /dev/null
  56. fi
  57. case "${?}" in
  58. 0)
  59. log_warning_msg "Unable to continue: ${1} is running"
  60. return 4
  61. ;;
  62. 1)
  63. log_warning_msg "Unable to continue: ${pidfile} exists"
  64. return 4
  65. ;;
  66. 3)
  67. ;;
  68. *)
  69. log_failure_msg "Unknown error code from pidofproc: ${?}"
  70. return 4
  71. ;;
  72. esac
  73. fi
  74. nice -n "${nicelevel}" "${@}"
  75. }
  76. #*******************************************************************************
  77. # Function - killproc [-p pidfile] pathname [signal]
  78. #
  79. # Purpose:
  80. #
  81. # Inputs: -p pidfile, uses the specified pidfile
  82. # pathname, pathname to the specified program
  83. # signal, send this signal to pathname
  84. #
  85. # Outputs: return 0 - Success
  86. # return 1 - Invalid or excessive number of arguments,
  87. # warning in stdout
  88. # return 4 - Unknown Status
  89. #
  90. # Dependencies: kill
  91. #
  92. # Todo: test
  93. #
  94. #*******************************************************************************
  95. killproc()
  96. {
  97. local pidfile=""
  98. local killsig=""
  99. local pidlist=""
  100. while true
  101. do
  102. case "${1}" in
  103. -p)
  104. pidfile="${2}"
  105. shift 2
  106. ;;
  107. -*)
  108. log_failure_msg "Unknown Option: ${1}"
  109. return 1
  110. ;;
  111. *)
  112. break
  113. ;;
  114. esac
  115. done
  116. if [ "${#}" = "2" ]; then
  117. killsig="${2}"
  118. elif [ "${#}" != "1" ]; then
  119. shift 2
  120. log_failure_msg "Excess Arguments: $@"
  121. return 1
  122. fi
  123. if [ -z "${pidfile}" ]; then
  124. pidlist=`pidofproc "${1}"`
  125. else
  126. pidlist=`pidofproc -p "${pidfile}" "${1}"`
  127. fi
  128. for pid in ${pidlist}
  129. do
  130. kill -${killsig:-TERM} ${pid} 2> /dev/null
  131. if [ -z "${killsig}" ]; then
  132. # Wait up to 3 seconds, for ${pid} to terminate
  133. local dtime=3
  134. while [ "${dtime}" != "0" ]
  135. do
  136. kill -0 ${pid} 2> /dev/null || break
  137. sleep 1
  138. dtime=$(( ${dtime} - 1))
  139. done
  140. # If ${pid} is still running, kill it
  141. kill -0 ${pid} 2> /dev/null && kill -KILL ${pid} 2> /dev/null
  142. fi
  143. done
  144. if [ -z "${killsig}" ]; then
  145. pidofproc "${1}" 2>&1 > /dev/null
  146. # Program was terminated
  147. if [ "$?" != "0" ]; then
  148. # Pidfile Exists
  149. if [ -f "${pidfile}" ]; then
  150. rm -f "${pidfile}" 2>&1 > /dev/null
  151. fi
  152. return 0
  153. else # Program is still running
  154. return 4 # Unknown Status
  155. fi
  156. else
  157. if [ -z "${pidfile}" ]; then
  158. pidofproc "${1}" 2> /dev/null
  159. else
  160. pidofproc -p "${pidfile}" "${1}" 2> /dev/null
  161. fi
  162. fi
  163. }
  164. #*******************************************************************************
  165. # Function - pidofproc [-p pidfile] pathname
  166. #
  167. # Purpose: This function returns one or more pid(s) for a particular daemon
  168. #
  169. # Inputs: -p pidfile, use the specified pidfile instead of pidof
  170. # pathname, path to the specified program
  171. #
  172. # Outputs: return 0 - Success, pid's in stdout
  173. # return 1 - Invalid or excessive number of arguments,
  174. # warning in stdout
  175. # return 1 - Program is dead, pidfile exists
  176. # return 3 - Program is not running
  177. #
  178. # Dependencies: pidof, echo
  179. #
  180. # Todo: - Invalid or excessive argments, and program is dead pidfile exists
  181. # conflict with eachother
  182. #
  183. #*******************************************************************************
  184. pidofproc()
  185. {
  186. local pidfile=""
  187. local lpids=""
  188. local pidlist=""
  189. while true
  190. do
  191. case "${1}" in
  192. -p)
  193. pidfile="${2}"
  194. shift 2
  195. ;;
  196. -*)
  197. log_failure_msg "Unknown Option: ${1}"
  198. return 1
  199. ;;
  200. *)
  201. break
  202. ;;
  203. esac
  204. done
  205. if [ "${#}" != "1" ]; then
  206. shift 1
  207. log_failure_msg "Excess Arguments: $@"
  208. return 1
  209. fi
  210. if [ -n "${pidfile}" ]; then
  211. if [ ! -r "${pidfile}" ]; then
  212. return 3 # Program is not running
  213. fi
  214. lpids=`head -n 1 ${pidfile}`
  215. for pid in ${lpids}
  216. do
  217. if [ "${pid}" -ne "$$" -a "${pid}" -ne "${PPID}" ]; then
  218. kill -0 "${pid}" 2> /dev/null &&
  219. pidlist="${pidlist} ${pid}"
  220. fi
  221. echo ${pidlist}
  222. test -z "${pidlist}" && return 1 # Program is dead, pidfile exists
  223. return 0
  224. done
  225. else
  226. pidof "${1}"
  227. fi
  228. if [ "$?" != "0" ]; then
  229. return 3 # Program is not running
  230. fi
  231. }
  232. # Screen Dimentions
  233. if [ -z "${COLUMNS}" ]; then
  234. COLUMNS=$(stty size)
  235. COLUMNS=${COLUMNS##* }
  236. fi
  237. # When using remote connections, such as a serial port, stty size returns 0
  238. if [ "${COLUMNS}" = "0" ]; then
  239. COLUMNS=80
  240. fi
  241. # Measurements for positioning result messages
  242. COL=$((${COLUMNS} - 8))
  243. WCOL=$((${COL} - 2))
  244. # Set Cursur Position Commands, used via echo -e
  245. SET_COL="\\033[${COL}G" # at the $COL char
  246. SET_WCOL="\\033[${WCOL}G" # at the $WCOL char
  247. CURS_UP="\\033[1A\\033[0G" # Up one line, at the 0'th char
  248. # Set color commands, used via echo -e
  249. # Please consult `man console_codes` for more information
  250. # under the "Set Graphics Resolution" section
  251. #
  252. # Warning, when switching from a 8bit to a 9bit font,
  253. # the linux console will reinterpret the bold (1;) to
  254. # the top 256 glyphs of the 9bit font. This does
  255. # not affect framebuffer consoles
  256. NORMAL="\\033[0;39m" # Standard console grey
  257. SUCCESS="\\033[1;32m" # Success is green
  258. WARNING="\\033[1;33m" # Warnings are yellow
  259. FAILURE="\\033[1;31m" # Failures are red
  260. INFO="\\033[1;36m" # Information is light cyan
  261. BRACKET="\\033[1;34m" # Brackets are blue
  262. BOOTMESG_PREFIX=" * " # Text at the beginning of every line
  263. #*******************************************************************************
  264. # Function - log_success_msg "message"
  265. #
  266. # Purpose: Print a success message
  267. #
  268. # Inputs:
  269. #
  270. # Outputs:
  271. #
  272. # Dependencies: echo
  273. #
  274. # Todo: logging
  275. #
  276. #*******************************************************************************
  277. log_success_msg()
  278. {
  279. echo -n -e "${BOOTMESG_PREFIX}${@}"
  280. echo -e "${SET_COL}""${BRACKET}""[""${SUCCESS}"" OK ""${BRACKET}""]""${NORMAL}"
  281. return 0
  282. }
  283. #*******************************************************************************
  284. # Function - log_failure_msg "message"
  285. #
  286. # Purpose: Print a failure message
  287. #
  288. # Inputs: $@ - Message
  289. #
  290. # Outputs: Text output to screen
  291. #
  292. # Dependencies: echo
  293. #
  294. # Todo: logging
  295. #
  296. #*******************************************************************************
  297. log_failure_msg() {
  298. echo -n -e "${BOOTMESG_PREFIX}${@}"
  299. echo -e "${SET_COL}""${BRACKET}""[""${FAILURE}"" FAIL ""${BRACKET}""]""${NORMAL}"
  300. return 0
  301. }
  302. #*******************************************************************************
  303. # Function - log_warning_msg "message"
  304. #
  305. # Purpose: print a warning message
  306. #
  307. # Inputs: $@ - Message
  308. #
  309. # Outputs: Text output to screen
  310. #
  311. # Dependencies: echo
  312. #
  313. # Todo: logging
  314. #
  315. #*******************************************************************************
  316. log_warning_msg() {
  317. echo -n -e "${BOOTMESG_PREFIX}${@}"
  318. echo -e "${SET_COL}""${BRACKET}""[""${WARNING}"" WARN ""${BRACKET}""]""${NORMAL}"
  319. return 0
  320. }