/[baselayout]/trunk/src/librc-daemon.c
Gentoo

Diff of /trunk/src/librc-daemon.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

Revision 2547 Revision 2928
3 Finds PID for given daemon criteria 3 Finds PID for given daemon criteria
4 Copyright 2007 Gentoo Foundation 4 Copyright 2007 Gentoo Foundation
5 Released under the GPLv2 5 Released under the GPLv2
6 */ 6 */
7 7
8#include <sys/types.h>
9#include <sys/stat.h>
10
11#if defined(__FreeBSD__) || defined(__NetBSD__) || defined (__OpenBSD__)
12#include <sys/param.h>
13#include <sys/user.h>
14#include <sys/sysctl.h>
15#include <kvm.h>
16#include <limits.h>
17#endif
18
19#ifndef __linux__
20#include <libgen.h>
21#endif
22
23#include <dirent.h>
24#include <errno.h>
25#include <fcntl.h>
26#include <stdio.h>
27#include <stdlib.h>
28#include <string.h>
29#include <unistd.h>
30
31#include "einfo.h"
32#include "rc.h" 8#include "librc.h"
33#include "rc-misc.h"
34#include "strlist.h"
35 9
36#if defined(__linux__) 10#if defined(__linux__)
37static bool pid_is_cmd (pid_t pid, const char *cmd) 11static bool pid_is_cmd (pid_t pid, const char *cmd)
38{ 12{
39 char buffer[32]; 13 char buffer[32];
40 FILE *fp; 14 FILE *fp;
41 int c; 15 int c;
42 16
43 snprintf(buffer, sizeof (buffer), "/proc/%d/stat", pid); 17 snprintf(buffer, sizeof (buffer), "/proc/%d/stat", pid);
44 if ((fp = fopen (buffer, "r")) == NULL) 18 if ((fp = fopen (buffer, "r")) == NULL)
45 return (false); 19 return (false);
46 20
47 while ((c = getc (fp)) != EOF && c != '(') 21 while ((c = getc (fp)) != EOF && c != '(')
48 ; 22 ;
49 23
50 if (c != '(') 24 if (c != '(') {
51 { 25 fclose(fp);
52 fclose(fp);
53 return (false); 26 return (false);
54 } 27 }
55 28
56 while ((c = getc (fp)) != EOF && c == *cmd) 29 while ((c = getc (fp)) != EOF && c == *cmd)
57 cmd++; 30 cmd++;
58 31
59 fclose (fp); 32 fclose (fp);
60 33
61 return ((c == ')' && *cmd == '\0') ? true : false); 34 return ((c == ')' && *cmd == '\0') ? true : false);
62} 35}
63 36
64static bool pid_is_exec (pid_t pid, const char *exec) 37static bool pid_is_exec (pid_t pid, const char *exec)
65{ 38{
66 char cmdline[32]; 39 char cmdline[32];
67 char buffer[PATH_MAX]; 40 char buffer[PATH_MAX];
68 char *p; 41 char *p;
69 int fd = -1; 42 int fd = -1;
70 int r; 43 int r;
71 44
72 snprintf (cmdline, sizeof (cmdline), "/proc/%u/exe", pid); 45 snprintf (cmdline, sizeof (cmdline), "/proc/%u/exe", pid);
73 memset (buffer, 0, sizeof (buffer)); 46 memset (buffer, 0, sizeof (buffer));
74 if (readlink (cmdline, buffer, sizeof (buffer)) != -1) 47 if (readlink (cmdline, buffer, sizeof (buffer)) != -1) {
75 {
76 if (strcmp (exec, buffer) == 0) 48 if (strcmp (exec, buffer) == 0)
77 return (true);
78
79 /* We should cater for deleted binaries too */
80 if (strlen (buffer) > 10)
81 {
82 p = buffer + (strlen (buffer) - 10);
83 if (strcmp (p, " (deleted)") == 0)
84 {
85 *p = 0;
86 if (strcmp (buffer, exec) == 0)
87 return (true); 49 return (true);
88 } 50
51 /* We should cater for deleted binaries too */
52 if (strlen (buffer) > 10) {
53 p = buffer + (strlen (buffer) - 10);
54 if (strcmp (p, " (deleted)") == 0) {
55 *p = 0;
56 if (strcmp (buffer, exec) == 0)
57 return (true);
58 }
89 } 59 }
90 } 60 }
91 61
92 snprintf (cmdline, sizeof (cmdline), "/proc/%u/cmdline", pid); 62 snprintf (cmdline, sizeof (cmdline), "/proc/%u/cmdline", pid);
93 if ((fd = open (cmdline, O_RDONLY)) < 0) 63 if ((fd = open (cmdline, O_RDONLY)) < 0)
94 return (false); 64 return (false);
95 65
96 r = read(fd, buffer, sizeof (buffer)); 66 r = read(fd, buffer, sizeof (buffer));
97 close (fd); 67 close (fd);
98 68
99 if (r == -1) 69 if (r == -1)
100 return 0; 70 return 0;
101 71
102 buffer[r] = 0; 72 buffer[r] = 0;
103 return (strcmp (exec, buffer) == 0 ? true : false); 73 return (strcmp (exec, buffer) == 0 ? true : false);
104} 74}
105 75
106pid_t *rc_find_pids (const char *exec, const char *cmd, 76pid_t *rc_find_pids (const char *exec, const char *cmd,
107 uid_t uid, pid_t pid) 77 uid_t uid, pid_t pid)
108{ 78{
109 DIR *procdir; 79 DIR *procdir;
110 struct dirent *entry; 80 struct dirent *entry;
111 int npids = 0; 81 int npids = 0;
112 int foundany = false; 82 int foundany = false;
113 pid_t p; 83 pid_t p;
114 pid_t *pids = NULL; 84 pid_t *pids = NULL;
115 char buffer[PATH_MAX]; 85 char buffer[PATH_MAX];
116 struct stat sb; 86 struct stat sb;
117 pid_t runscript_pid = 0; 87 pid_t runscript_pid = 0;
118 char *pp; 88 char *pp;
119 89
120 if ((procdir = opendir ("/proc")) == NULL) 90 if ((procdir = opendir ("/proc")) == NULL)
121 eerrorx ("opendir `/proc': %s", strerror (errno)); 91 eerrorx ("opendir `/proc': %s", strerror (errno));
122 92
123 /* 93 /*
124 We never match RC_RUNSCRIPT_PID if present so we avoid the below 94 We never match RC_RUNSCRIPT_PID if present so we avoid the below
125 scenario 95 scenario
126 96
127 /etc/init.d/ntpd stop does 97 /etc/init.d/ntpd stop does
128 start-stop-daemon --stop --name ntpd 98 start-stop-daemon --stop --name ntpd
129 catching /etc/init.d/ntpd stop 99 catching /etc/init.d/ntpd stop
130 100
131 nasty 101 nasty
132 */ 102 */
133 103
134 if ((pp = getenv ("RC_RUNSCRIPT_PID"))) 104 if ((pp = getenv ("RC_RUNSCRIPT_PID"))) {
135 {
136 if (sscanf (pp, "%d", &runscript_pid) != 1) 105 if (sscanf (pp, "%d", &runscript_pid) != 1)
137 runscript_pid = 0; 106 runscript_pid = 0;
138 } 107 }
139 108
140 while ((entry = readdir (procdir)) != NULL) 109 while ((entry = readdir (procdir)) != NULL) {
141 {
142 if (sscanf (entry->d_name, "%d", &p) != 1) 110 if (sscanf (entry->d_name, "%d", &p) != 1)
143 continue; 111 continue;
144 foundany = true; 112 foundany = true;
145 113
146 if (runscript_pid != 0 && runscript_pid == p) 114 if (runscript_pid != 0 && runscript_pid == p)
147 continue; 115 continue;
148 116
149 if (pid != 0 && pid != p) 117 if (pid != 0 && pid != p)
150 continue; 118 continue;
151 119
152 if (uid) 120 if (uid) {
153 {
154 snprintf (buffer, sizeof (buffer), "/proc/%d", pid); 121 snprintf (buffer, sizeof (buffer), "/proc/%d", p);
155 if (stat (buffer, &sb) != 0 || sb.st_uid != uid) 122 if (stat (buffer, &sb) != 0 || sb.st_uid != uid)
156 continue; 123 continue;
157 } 124 }
158 125
159 if (cmd && ! pid_is_cmd (p, cmd)) 126 if (cmd && ! pid_is_cmd (p, cmd))
160 continue; 127 continue;
161 128
162 if (exec && ! cmd && ! pid_is_exec (p, exec)) 129 if (exec && ! cmd && ! pid_is_exec (p, exec))
163 continue; 130 continue;
164 131
165 pids = realloc (pids, sizeof (pid_t) * (npids + 2)); 132 pids = realloc (pids, sizeof (pid_t) * (npids + 2));
166 if (! pids) 133 if (! pids)
167 eerrorx ("memory exhausted"); 134 eerrorx ("memory exhausted");
168 135
169 pids[npids] = p; 136 pids[npids] = p;
170 pids[npids + 1] = 0; 137 pids[npids + 1] = 0;
171 npids++; 138 npids++;
172 } 139 }
173 closedir (procdir); 140 closedir (procdir);
174 141
175 if (! foundany) 142 if (! foundany)
176 eerrorx ("nothing in /proc"); 143 eerrorx ("nothing in /proc");
177 144
178 return (pids); 145 return (pids);
179} 146}
147librc_hidden_def(rc_find_pids)
180 148
181#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) 149#elif defined(__DragonFly__) || defined(__FreeBSD__) || \
150 defined(__NetBSD__) || defined(__OpenBSD__)
182 151
183# if defined(__FreeBSD__) 152# if defined(__DragonFly__) || defined(__FreeBSD__)
153# ifndef KERN_PROC_PROC
154# define KERN_PROC_PROC KERN_PROC_ALL
155# endif
184# define _KINFO_PROC kinfo_proc 156# define _KINFO_PROC kinfo_proc
185# define _KVM_GETPROCS kvm_getprocs
186# define _KVM_GETARGV kvm_getargv 157# define _KVM_GETARGV kvm_getargv
187# define _GET_KINFO_UID(kp) (kp.ki_ruid) 158# define _GET_KINFO_UID(kp) (kp.ki_ruid)
188# define _GET_KINFO_COMM(kp) (kp.ki_comm) 159# define _GET_KINFO_COMM(kp) (kp.ki_comm)
189# define _GET_KINFO_PID(kp) (kp.ki_pid) 160# define _GET_KINFO_PID(kp) (kp.ki_pid)
190# else 161# else
191# define _KINFO_PROC kinfo_proc2 162# define _KINFO_PROC kinfo_proc2
192# define _KVM_GETPROCS kvm_getprocs2
193# define _KVM_GETARGV kvm_getargv2 163# define _KVM_GETARGV kvm_getargv2
194# define _GET_KINFO_UID(kp) (kp.p_ruid) 164# define _GET_KINFO_UID(kp) (kp.p_ruid)
195# define _GET_KINFO_COMM(kp) (kp.p_comm) 165# define _GET_KINFO_COMM(kp) (kp.p_comm)
196# define _GET_KINFO_PID(kp) (kp.p_pid) 166# define _GET_KINFO_PID(kp) (kp.p_pid)
197# endif 167# endif
198 168
199pid_t *rc_find_pids (const char *exec, const char *cmd, 169pid_t *rc_find_pids (const char *exec, const char *cmd,
200 uid_t uid, pid_t pid) 170 uid_t uid, pid_t pid)
201{ 171{
202 static kvm_t *kd = NULL; 172 static kvm_t *kd = NULL;
203 char errbuf[_POSIX2_LINE_MAX]; 173 char errbuf[_POSIX2_LINE_MAX];
204 struct _KINFO_PROC *kp; 174 struct _KINFO_PROC *kp;
205 int i; 175 int i;
206 int processes = 0; 176 int processes = 0;
207 int argc = 0; 177 int argc = 0;
208 char **argv; 178 char **argv;
209 pid_t *pids = NULL; 179 pid_t *pids = NULL;
210 int npids = 0; 180 int npids = 0;
211 181
212 if ((kd = kvm_openfiles (NULL, NULL, NULL, O_RDONLY, errbuf)) == NULL) 182 if ((kd = kvm_openfiles (NULL, NULL, NULL, O_RDONLY, errbuf)) == NULL)
213 eerrorx ("kvm_open: %s", errbuf); 183 eerrorx ("kvm_open: %s", errbuf);
214 184
185#if defined(__DragonFly__) || defined( __FreeBSD__)
215 kp = _KVM_GETPROCS (kd, KERN_PROC_PROC, 0, &processes); 186 kp = kvm_getprocs (kd, KERN_PROC_PROC, 0, &processes);
187#else
188 kp = kvm_getproc2 (kd, KERN_PROC_ALL, 0, sizeof(struct kinfo_proc2),
189 &processes);
190#endif
216 for (i = 0; i < processes; i++) 191 for (i = 0; i < processes; i++) {
217 {
218 pid_t p = _GET_KINFO_PID (kp[i]); 192 pid_t p = _GET_KINFO_PID (kp[i]);
219 if (pid != 0 && pid != p) 193 if (pid != 0 && pid != p)
220 continue; 194 continue;
221 195
222 if (uid != 0 && uid != _GET_KINFO_UID (kp[i])) 196 if (uid != 0 && uid != _GET_KINFO_UID (kp[i]))
223 continue; 197 continue;
224 198
225 if (cmd) 199 if (cmd) {
226 {
227 if (! _GET_KINFO_COMM (kp[i]) || 200 if (! _GET_KINFO_COMM (kp[i]) ||
228 strcmp (cmd, _GET_KINFO_COMM (kp[i])) != 0) 201 strcmp (cmd, _GET_KINFO_COMM (kp[i])) != 0)
229 continue; 202 continue;
230 } 203 }
231 204
232 if (exec && ! cmd) 205 if (exec && ! cmd) {
233 {
234 if ((argv = _KVM_GETARGV (kd, &kp[i], argc)) == NULL || ! *argv) 206 if ((argv = _KVM_GETARGV (kd, &kp[i], argc)) == NULL || ! *argv)
235 continue; 207 continue;
236 208
237 if (strcmp (*argv, exec) != 0) 209 if (strcmp (*argv, exec) != 0)
238 continue; 210 continue;
239 } 211 }
240 212
241 pids = realloc (pids, sizeof (pid_t) * (npids + 2)); 213 pids = realloc (pids, sizeof (pid_t) * (npids + 2));
242 if (! pids) 214 if (! pids)
243 eerrorx ("memory exhausted"); 215 eerrorx ("memory exhausted");
244 216
245 pids[npids] = p; 217 pids[npids] = p;
246 pids[npids + 1] = 0; 218 pids[npids + 1] = 0;
247 npids++; 219 npids++;
248 } 220 }
249 kvm_close(kd); 221 kvm_close(kd);
250 222
251 return (pids); 223 return (pids);
252} 224}
225librc_hidden_def(rc_find_pids)
253 226
254#else 227#else
255# error "Platform not supported!" 228# error "Platform not supported!"
256#endif 229#endif
257 230
258static bool _match_daemon (const char *path, const char *file, 231static bool _match_daemon (const char *path, const char *file,
259 const char *mexec, const char *mname, 232 const char *mexec, const char *mname,
260 const char *mpidfile) 233 const char *mpidfile)
261{ 234{
262 char buffer[RC_LINEBUFFER]; 235 char buffer[RC_LINEBUFFER];
263 char *ffile = rc_strcatpaths (path, file, NULL); 236 char *ffile = rc_strcatpaths (path, file, (char *) NULL);
264 FILE *fp; 237 FILE *fp;
265 int lc = 0; 238 int lc = 0;
266 int m = 0; 239 int m = 0;
267 240
268 if (! rc_exists (ffile)) 241 if (! rc_exists (ffile)) {
269 {
270 free (ffile); 242 free (ffile);
271 return (false); 243 return (false);
272 } 244 }
273 245
274 if ((fp = fopen (ffile, "r")) == NULL) 246 if ((fp = fopen (ffile, "r")) == NULL) {
275 {
276 eerror ("fopen `%s': %s", ffile, strerror (errno)); 247 eerror ("fopen `%s': %s", ffile, strerror (errno));
277 free (ffile); 248 free (ffile);
278 return (false); 249 return (false);
279 } 250 }
280 251
281 if (! mname) 252 if (! mname)
282 m += 10; 253 m += 10;
283 if (! mpidfile) 254 if (! mpidfile)
284 m += 100; 255 m += 100;
285 256
286 memset (buffer, 0, sizeof (buffer)); 257 memset (buffer, 0, sizeof (buffer));
287 while ((fgets (buffer, RC_LINEBUFFER, fp))) 258 while ((fgets (buffer, RC_LINEBUFFER, fp))) {
288 {
289 int lb = strlen (buffer) - 1; 259 int lb = strlen (buffer) - 1;
290 if (buffer[lb] == '\n') 260 if (buffer[lb] == '\n')
291 buffer[lb] = 0; 261 buffer[lb] = 0;
292 262
293 if (strcmp (buffer, mexec) == 0) 263 if (strcmp (buffer, mexec) == 0)
294 m += 1; 264 m += 1;
295 else if (mname && strcmp (buffer, mname) == 0) 265 else if (mname && strcmp (buffer, mname) == 0)
296 m += 10; 266 m += 10;
297 else if (mpidfile && strcmp (buffer, mpidfile) == 0) 267 else if (mpidfile && strcmp (buffer, mpidfile) == 0)
298 m += 100; 268 m += 100;
299 269
300 if (m == 111) 270 if (m == 111)
301 break; 271 break;
302 272
303 lc++; 273 lc++;
304 if (lc > 5) 274 if (lc > 5)
305 break; 275 break;
306 } 276 }
307 fclose (fp); 277 fclose (fp);
308 free (ffile); 278 free (ffile);
309 279
310 return (m == 111 ? true : false); 280 return (m == 111 ? true : false);
311} 281}
312 282
313void rc_set_service_daemon (const char *service, const char *exec, 283void rc_set_service_daemon (const char *service, const char *exec,
314 const char *name, const char *pidfile, 284 const char *name, const char *pidfile,
315 bool started) 285 bool started)
316{ 286{
287 char *svc = rc_xstrdup (service);
317 char *dirpath = rc_strcatpaths (RC_SVCDIR, "daemons", basename (service), NULL); 288 char *dirpath = rc_strcatpaths (RC_SVCDIR, "daemons", basename (svc),
289 (char *) NULL);
318 char **files = NULL; 290 char **files = NULL;
319 char *file; 291 char *file;
320 char *ffile = NULL; 292 char *ffile = NULL;
321 int i; 293 int i;
322 char *mexec; 294 char *mexec;
323 char *mname; 295 char *mname;
324 char *mpidfile; 296 char *mpidfile;
325 int nfiles = 0; 297 int nfiles = 0;
326 298
299 free (svc);
327 if (! exec && ! name && ! pidfile) 300 if (! exec && ! name && ! pidfile)
328 return; 301 return;
329 302
330 if (exec) 303 if (exec) {
331 {
332 i = strlen (exec) + 6; 304 i = strlen (exec) + 6;
333 mexec = rc_xmalloc (sizeof (char *) * i); 305 mexec = rc_xmalloc (sizeof (char *) * i);
334 snprintf (mexec, i, "exec=%s", exec); 306 snprintf (mexec, i, "exec=%s", exec);
335 }
336 else 307 } else
337 mexec = strdup ("exec="); 308 mexec = rc_xstrdup ("exec=");
338 309
339 if (name) 310 if (name) {
340 {
341 i = strlen (name) + 6; 311 i = strlen (name) + 6;
342 mname = rc_xmalloc (sizeof (char *) * i); 312 mname = rc_xmalloc (sizeof (char *) * i);
343 snprintf (mname, i, "name=%s", name); 313 snprintf (mname, i, "name=%s", name);
344 }
345 else 314 } else
346 mname = strdup ("name="); 315 mname = rc_xstrdup ("name=");
347 316
348 if (pidfile) 317 if (pidfile) {
349 {
350 i = strlen (pidfile) + 9; 318 i = strlen (pidfile) + 9;
351 mpidfile = rc_xmalloc (sizeof (char *) * i); 319 mpidfile = rc_xmalloc (sizeof (char *) * i);
352 snprintf (mpidfile, i, "pidfile=%s", pidfile); 320 snprintf (mpidfile, i, "pidfile=%s", pidfile);
353 }
354 else 321 } else
355 mpidfile = strdup ("pidfile="); 322 mpidfile = rc_xstrdup ("pidfile=");
356 323
357 /* Regardless, erase any existing daemon info */ 324 /* Regardless, erase any existing daemon info */
358 if (rc_is_dir (dirpath)) 325 if (rc_is_dir (dirpath)) {
359 {
360 char *oldfile = NULL; 326 char *oldfile = NULL;
361 files = rc_ls_dir (NULL, dirpath, 0); 327 files = rc_ls_dir (dirpath, 0);
362 STRLIST_FOREACH (files, file, i) 328 STRLIST_FOREACH (files, file, i) {
363 {
364 ffile = rc_strcatpaths (dirpath, file, NULL); 329 ffile = rc_strcatpaths (dirpath, file, (char *) NULL);
365 nfiles++; 330 nfiles++;
366 331
367 if (! oldfile) 332 if (! oldfile) {
368 {
369 if (_match_daemon (dirpath, file, mexec, mname, mpidfile)) 333 if (_match_daemon (dirpath, file, mexec, mname, mpidfile)) {
370 {
371 unlink (ffile); 334 unlink (ffile);
335 oldfile = ffile;
336 nfiles--;
337 }
338 } else {
339 rename (ffile, oldfile);
340 free (oldfile);
372 oldfile = ffile; 341 oldfile = ffile;
373 nfiles--;
374 } 342 }
375 }
376 else
377 {
378 rename (ffile, oldfile);
379 free (oldfile);
380 oldfile = ffile;
381 }
382 } 343 }
383 if (ffile)
384 free (ffile); 344 free (ffile);
385 free (files); 345 rc_strlist_free (files);
386 } 346 }
387 347
388 /* Now store our daemon info */ 348 /* Now store our daemon info */
389 if (started) 349 if (started) {
390 {
391 char buffer[10]; 350 char buffer[10];
392 FILE *fp; 351 FILE *fp;
393 352
394 if (! rc_is_dir (dirpath)) 353 if (! rc_is_dir (dirpath))
395 if (mkdir (dirpath, 0755) != 0) 354 if (mkdir (dirpath, 0755) != 0)
396 eerror ("mkdir `%s': %s", dirpath, strerror (errno)); 355 eerror ("mkdir `%s': %s", dirpath, strerror (errno));
397 356
398 snprintf (buffer, sizeof (buffer), "%03d", nfiles + 1); 357 snprintf (buffer, sizeof (buffer), "%03d", nfiles + 1);
399 file = rc_strcatpaths (dirpath, buffer, NULL); 358 file = rc_strcatpaths (dirpath, buffer, (char *) NULL);
400 if ((fp = fopen (file, "w")) == NULL) 359 if ((fp = fopen (file, "w")) == NULL)
401 eerror ("fopen `%s': %s", file, strerror (errno)); 360 eerror ("fopen `%s': %s", file, strerror (errno));
402 else 361 else {
403 {
404 fprintf (fp, "%s\n%s\n%s\n", mexec, mname, mpidfile); 362 fprintf (fp, "%s\n%s\n%s\n", mexec, mname, mpidfile);
405 fclose (fp); 363 fclose (fp);
406 } 364 }
407 free (file); 365 free (file);
408 } 366 }
409 367
410 free (mexec); 368 free (mexec);
411 free (mname); 369 free (mname);
412 free (mpidfile); 370 free (mpidfile);
413 free (dirpath); 371 free (dirpath);
414} 372}
373librc_hidden_def(rc_set_service_daemon)
415 374
416bool rc_service_started_daemon (const char *service, const char *exec, 375bool rc_service_started_daemon (const char *service, const char *exec,
417 int indx) 376 int indx)
418{ 377{
419 char *dirpath; 378 char *dirpath;
420 char *file; 379 char *file;
421 int i; 380 int i;
422 char *mexec; 381 char *mexec;
423 bool retval = false; 382 bool retval = false;
383 char *svc;
424 384
425 if (! service || ! exec) 385 if (! service || ! exec)
426 return (false); 386 return (false);
427 387
388 svc = rc_xstrdup (service);
428 dirpath = rc_strcatpaths (RC_SVCDIR, "daemons", basename (service), NULL); 389 dirpath = rc_strcatpaths (RC_SVCDIR, "daemons", basename (svc),
390 (char *) NULL);
391 free (svc);
392
429 if (! rc_is_dir (dirpath)) 393 if (! rc_is_dir (dirpath)) {
430 {
431 free (dirpath); 394 free (dirpath);
432 return (false); 395 return (false);
433 } 396 }
434 397
435 i = strlen (exec) + 6; 398 i = strlen (exec) + 6;
436 mexec = rc_xmalloc (sizeof (char *) * i); 399 mexec = rc_xmalloc (sizeof (char *) * i);
437 snprintf (mexec, i, "exec=%s", exec); 400 snprintf (mexec, i, "exec=%s", exec);
438 401
439 if (indx > 0) 402 if (indx > 0) {
440 { 403 int len = sizeof (char *) * 10;
441 file = rc_xmalloc (sizeof (char *) * 10); 404 file = rc_xmalloc (len);
442 snprintf (file, sizeof (file), "%03d", indx); 405 snprintf (file, len, "%03d", indx);
443 retval = _match_daemon (dirpath, file, mexec, NULL, NULL);
444 free (file);
445 }
446 else
447 {
448 char **files = rc_ls_dir (NULL, dirpath, 0);
449 STRLIST_FOREACH (files, file, i)
450 {
451 retval = _match_daemon (dirpath, file, mexec, NULL, NULL); 406 retval = _match_daemon (dirpath, file, mexec, NULL, NULL);
407 free (file);
408 } else {
409 char **files = rc_ls_dir (dirpath, 0);
410 STRLIST_FOREACH (files, file, i) {
411 retval = _match_daemon (dirpath, file, mexec, NULL, NULL);
452 if (retval) 412 if (retval)
453 break; 413 break;
454 } 414 }
455 free (files); 415 rc_strlist_free (files);
456 } 416 }
457 417
458 free (mexec); 418 free (mexec);
459 return (retval); 419 return (retval);
460} 420}
421librc_hidden_def(rc_service_started_daemon)
461 422
462bool rc_service_daemons_crashed (const char *service) 423bool rc_service_daemons_crashed (const char *service)
463{ 424{
464 char *dirpath; 425 char *dirpath;
465 char **files; 426 char **files;
466 char *file; 427 char *file;
467 char *path; 428 char *path;
468 int i; 429 int i;
469 FILE *fp; 430 FILE *fp;
470 char buffer[RC_LINEBUFFER]; 431 char buffer[RC_LINEBUFFER];
471 char *exec = NULL; 432 char *exec = NULL;
472 char *name = NULL; 433 char *name = NULL;
473 char *pidfile = NULL; 434 char *pidfile = NULL;
474 pid_t pid = 0; 435 pid_t pid = 0;
475 pid_t *pids = NULL; 436 pid_t *pids = NULL;
476 char *p; 437 char *p;
477 char *token; 438 char *token;
478 bool retval = false; 439 bool retval = false;
440 char *svc;
479 441
480 if (! service) 442 if (! service)
481 return (false); 443 return (false);
482 444
445 svc = rc_xstrdup (service);
483 dirpath = rc_strcatpaths (RC_SVCDIR, "daemons", basename (service), NULL); 446 dirpath = rc_strcatpaths (RC_SVCDIR, "daemons", basename (svc),
447 (char *) NULL);
448 free (svc);
449
484 if (! rc_is_dir (dirpath)) 450 if (! rc_is_dir (dirpath)) {
485 {
486 free (dirpath); 451 free (dirpath);
487 return (false); 452 return (false);
488 } 453 }
489 454
490 memset (buffer, 0, sizeof (buffer)); 455 memset (buffer, 0, sizeof (buffer));
491 files = rc_ls_dir (NULL, dirpath, 0); 456 files = rc_ls_dir (dirpath, 0);
492 STRLIST_FOREACH (files, file, i) 457 STRLIST_FOREACH (files, file, i) {
493 {
494 path = rc_strcatpaths (dirpath, file, NULL); 458 path = rc_strcatpaths (dirpath, file, (char *) NULL);
495 fp = fopen (path, "r"); 459 fp = fopen (path, "r");
496 free (path); 460 free (path);
497 if (! fp) 461 if (! fp) {
498 {
499 eerror ("fopen `%s': %s", file, strerror (errno)); 462 eerror ("fopen `%s': %s", file, strerror (errno));
500 continue; 463 continue;
501 } 464 }
502 465
503 while ((fgets (buffer, RC_LINEBUFFER, fp))) 466 while ((fgets (buffer, RC_LINEBUFFER, fp))) {
504 {
505 int lb = strlen (buffer) - 1; 467 int lb = strlen (buffer) - 1;
506 if (buffer[lb] == '\n') 468 if (buffer[lb] == '\n')
507 buffer[lb] = 0; 469 buffer[lb] = 0;
508 470
509 p = buffer; 471 p = buffer;
510 if ((token = strsep (&p, "=")) == NULL || ! p) 472 if ((token = strsep (&p, "=")) == NULL || ! p)
511 continue; 473 continue;
512 474
513 if (strlen (p) == 0) 475 if (strlen (p) == 0)
514 continue; 476 continue;
515 477
516 if (strcmp (token, "exec") == 0) 478 if (strcmp (token, "exec") == 0) {
517 { 479 if (exec)
518 if (exec) 480 free (exec);
481 exec = rc_xstrdup (p);
482 } else if (strcmp (token, "name") == 0) {
483 if (name)
484 free (name);
485 name = rc_xstrdup (p);
486 } else if (strcmp (token, "pidfile") == 0) {
487 if (pidfile)
488 free (pidfile);
489 pidfile = rc_xstrdup (p);
490 }
491 }
492 fclose (fp);
493
494 pid = 0;
495 if (pidfile) {
496 if (! rc_exists (pidfile)) {
497 retval = true;
498 break;
499 }
500
501 if ((fp = fopen (pidfile, "r")) == NULL) {
502 eerror ("fopen `%s': %s", pidfile, strerror (errno));
503 retval = true;
504 break;
505 }
506
507 if (fscanf (fp, "%d", &pid) != 1) {
508 eerror ("no pid found in `%s'", pidfile);
509 fclose (fp);
510 retval = true;
511 break;
512 }
513
514 fclose (fp);
515 free (pidfile);
516 pidfile = NULL;
517
518 /* We have the pid, so no need to match on name */
519 free (exec);
520 exec = NULL;
521 free (name);
522 name = NULL;
523 }
524
525 if ((pids = rc_find_pids (exec, name, 0, pid)) == NULL) {
526 retval = true;
527 break;
528 }
529 free (pids);
530
519 free (exec); 531 free (exec);
520 exec = strdup (p); 532 exec = NULL;
521 }
522 else if (strcmp (token, "name") == 0)
523 {
524 if (name)
525 free (name); 533 free (name);
526 name = strdup (p); 534 name = NULL;
527 }
528 else if (strcmp (token, "pidfile") == 0)
529 {
530 if (pidfile)
531 free (pidfile);
532 pidfile = strdup (p);
533 }
534 } 535 }
535 fclose (fp);
536 536
537 pid = 0;
538 if (pidfile)
539 {
540 if (! rc_exists (pidfile))
541 {
542 retval = true;
543 break;
544 }
545
546 if ((fp = fopen (pidfile, "r")) == NULL)
547 {
548 eerror ("fopen `%s': %s", pidfile, strerror (errno));
549 retval = true;
550 break;
551 }
552
553 if (fscanf (fp, "%d", &pid) != 1)
554 {
555 eerror ("no pid found in `%s'", pidfile);
556 fclose (fp);
557 retval = true;
558 break;
559 }
560
561 fclose (fp);
562 free (pidfile);
563 pidfile = NULL;
564 }
565
566 if ((pids = rc_find_pids (exec, name, 0, pid)) == NULL)
567 {
568 retval = true;
569 break;
570 }
571 free (pids);
572
573 if (exec)
574 {
575 free (exec); 537 free (exec);
576 exec = NULL;
577 }
578 if (name)
579 {
580 free (name); 538 free (name);
581 name = NULL;
582 }
583 }
584
585 if (exec)
586 {
587 free (exec);
588 exec = NULL;
589 }
590 if (name)
591 {
592 free (name);
593 name = NULL;
594 }
595
596 free (dirpath); 539 free (dirpath);
597 rc_strlist_free (files); 540 rc_strlist_free (files);
598 541
599 return (retval); 542 return (retval);
600} 543}
544librc_hidden_def(rc_service_daemons_crashed)

Legend:
Removed from v.2547  
changed lines
  Added in v.2928

  ViewVC Help
Powered by ViewVC 1.1.20