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

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

  ViewVC Help
Powered by ViewVC 1.1.20