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