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

Contents of /trunk/src/librc.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2577 - (hide annotations) (download) (as text)
Wed Apr 11 12:44:47 2007 UTC (7 years ago) by uberlord
File MIME type: text/x-csrc
File size: 16725 byte(s)
Cuddle up to LKML C style
1 uberlord 2547 /*
2     librc
3     core RC functions
4     Copyright 2007 Gentoo Foundation
5     Released under the GPLv2
6     */
7    
8     #include <sys/types.h>
9     #include <sys/select.h>
10     #include <sys/time.h>
11     #include <sys/stat.h>
12     #include <sys/wait.h>
13     #include <errno.h>
14     #ifndef __linux__
15     /* Although linux should work fine, gcc likes to bitch with our default
16     CFLAGS so we just don't include the file and use the GNU one defined
17     in string.h */
18     #include <libgen.h>
19     #endif
20     #include <limits.h>
21     #include <stdarg.h>
22     #include <stdbool.h>
23     #include <stdio.h>
24     #include <stdlib.h>
25     #include <string.h>
26     #include <unistd.h>
27    
28     #include "einfo.h"
29     #include "rc.h"
30     #include "rc-misc.h"
31     #include "strlist.h"
32    
33     /* usecs to wait while we poll the fifo */
34     #define WAIT_INTERVAL 20000
35    
36     /* max secs to wait until a service comes up */
37     #define WAIT_MAX 60
38    
39     #define SOFTLEVEL RC_SVCDIR "softlevel"
40    
41     static const char *rc_service_state_names[] = {
42 uberlord 2577 "started",
43     "stopped",
44     "starting",
45     "stopping",
46     "inactive",
47     "wasinactive",
48     "coldplugged",
49     "failed",
50     "scheduled",
51     NULL
52 uberlord 2547 };
53    
54     bool rc_runlevel_starting (void)
55     {
56 uberlord 2577 return (rc_is_dir (RC_SVCDIR "softscripts.old"));
57 uberlord 2547 }
58    
59     bool rc_runlevel_stopping (void)
60     {
61 uberlord 2577 return (rc_is_dir (RC_SVCDIR "softscripts.new"));
62 uberlord 2547 }
63    
64     char **rc_get_runlevels (void)
65     {
66 uberlord 2577 char **dirs = rc_ls_dir (NULL, RC_RUNLEVELDIR, 0);
67     char **runlevels = NULL;
68     int i;
69     char *dir;
70 uberlord 2547
71 uberlord 2577 STRLIST_FOREACH (dirs, dir, i) {
72     char *path = rc_strcatpaths (RC_RUNLEVELDIR, dir, (char *) NULL);
73     if (rc_is_dir (path))
74     runlevels = rc_strlist_addsort (runlevels, dir);
75     free (path);
76     }
77     rc_strlist_free (dirs);
78 uberlord 2547
79 uberlord 2577 return (runlevels);
80 uberlord 2547 }
81    
82     char *rc_get_runlevel (void)
83     {
84 uberlord 2577 FILE *fp;
85     static char buffer [PATH_MAX];
86 uberlord 2547
87 uberlord 2577 if (! (fp = fopen (SOFTLEVEL, "r"))) {
88     snprintf (buffer, sizeof (buffer), "sysinit");
89     return (buffer);
90     }
91 uberlord 2547
92 uberlord 2577 if (fgets (buffer, PATH_MAX, fp)) {
93     int i = strlen (buffer) - 1;
94     if (buffer[i] == '\n')
95     buffer[i] = 0;
96     fclose (fp);
97     return (buffer);
98     }
99 uberlord 2547
100 uberlord 2577 fclose (fp);
101     snprintf (buffer, sizeof (buffer), "sysinit");
102     return (buffer);
103 uberlord 2547 }
104    
105     void rc_set_runlevel (const char *runlevel)
106     {
107 uberlord 2577 FILE *fp = fopen (SOFTLEVEL, "w");
108     if (! fp)
109     eerrorx ("failed to open `" SOFTLEVEL "': %s", strerror (errno));
110     fprintf (fp, "%s", runlevel);
111     fclose (fp);
112 uberlord 2547 }
113    
114     bool rc_runlevel_exists (const char *runlevel)
115     {
116 uberlord 2577 char *path;
117     bool retval;
118 uberlord 2547
119 uberlord 2577 if (! runlevel)
120     return (false);
121 uberlord 2547
122 uberlord 2577 path = rc_strcatpaths (RC_RUNLEVELDIR, runlevel, (char *) NULL);
123     retval = rc_is_dir (path);
124     free (path);
125     return (retval);
126 uberlord 2547 }
127    
128     /* Resolve a service name to it's full path */
129     char *rc_resolve_service (const char *service)
130     {
131 uberlord 2577 char buffer[PATH_MAX];
132     char *file;
133     int r = 0;
134 uberlord 2547
135 uberlord 2577 if (! service)
136     return (NULL);
137 uberlord 2547
138 uberlord 2577 if (service[0] == '/')
139     return (strdup (service));
140 uberlord 2547
141 uberlord 2577 file = rc_strcatpaths (RC_SVCDIR, "started", service, (char *) NULL);
142     if (! rc_is_link (file)) {
143     free (file);
144     file = rc_strcatpaths (RC_SVCDIR, "inactive", service, (char *) NULL);
145     if (! rc_is_link (file)) {
146     free (file);
147     file = NULL;
148     }
149     }
150 uberlord 2547
151 uberlord 2577 memset (buffer, 0, sizeof (buffer));
152     if (file) {
153     r = readlink (file, buffer, sizeof (buffer));
154     free (file);
155     if (r > 0)
156     return strdup (buffer);
157     }
158 uberlord 2547
159 uberlord 2577 snprintf (buffer, sizeof (buffer), RC_INITDIR "%s", service);
160     return (strdup (buffer));
161 uberlord 2547 }
162    
163     bool rc_service_exists (const char *service)
164     {
165 uberlord 2577 char *file;
166     bool retval = false;
167     int len;
168 uberlord 2547
169 uberlord 2577 if (! service)
170     return (false);
171 uberlord 2547
172 uberlord 2577 len = strlen (service);
173 uberlord 2547
174 uberlord 2577 /* .sh files are not init scripts */
175     if (len > 2 && service[len - 3] == '.' &&
176     service[len - 2] == 's' &&
177     service[len - 1] == 'h')
178     return (false);
179 uberlord 2547
180 uberlord 2577 file = rc_resolve_service (service);
181     if (rc_exists (file))
182     retval = rc_is_exec (file);
183     free (file);
184     return (retval);
185 uberlord 2547 }
186    
187     bool rc_service_in_runlevel (const char *service, const char *runlevel)
188     {
189 uberlord 2577 char *file;
190     bool retval;
191 uberlord 2547
192 uberlord 2577 if (! runlevel || ! service)
193     return (false);
194 uberlord 2547
195 uberlord 2577 if (! rc_service_exists (service))
196     return (false);
197 uberlord 2547
198 uberlord 2577 file = rc_strcatpaths (RC_RUNLEVELDIR, runlevel, basename (service),
199     (char *) NULL);
200     retval = rc_exists (file);
201     free (file);
202 uberlord 2547
203 uberlord 2577 return (retval);
204 uberlord 2547 }
205    
206     bool rc_mark_service (const char *service, const rc_service_state_t state)
207     {
208 uberlord 2577 char *file;
209     int i = 0;
210     int skip_state = -1;
211     char *base;
212     char *init = rc_resolve_service (service);
213     bool skip_wasinactive = false;
214 uberlord 2547
215 uberlord 2577 if (! service)
216     return (false);
217 uberlord 2547
218 uberlord 2577 base = basename (service);
219 uberlord 2547
220 uberlord 2577 if (state != rc_service_stopped) {
221     if (! rc_is_file(init)) {
222     free (init);
223     return (false);
224     }
225 uberlord 2547
226 uberlord 2577 file = rc_strcatpaths (RC_SVCDIR, rc_service_state_names[state], base,
227     (char *) NULL);
228     if (rc_exists (file))
229     unlink (file);
230     i = symlink (init, file);
231     if (i != 0) {
232     free (file);
233     free (init);
234     einfo ("%d %s %s", state, rc_service_state_names[state], base);
235     eerror ("symlink `%s' to `%s': %s", init, file, strerror (errno));
236     return (false);
237     }
238 uberlord 2547
239 uberlord 2577 free (file);
240     skip_state = state;
241     }
242 uberlord 2547
243 uberlord 2577 if (state == rc_service_coldplugged) {
244     free (init);
245     return (true);
246     }
247 uberlord 2547
248 uberlord 2577 /* Remove any old states now */
249     i = 0;
250     while (rc_service_state_names[i]) {
251     if ((i != skip_state &&
252     i != rc_service_stopped &&
253     i != rc_service_coldplugged &&
254     i != rc_service_scheduled &&
255     i != rc_service_crashed) &&
256     (! skip_wasinactive || i != rc_service_wasinactive))
257     {
258     file = rc_strcatpaths (RC_SVCDIR, rc_service_state_names[i], base,
259     (char *) NULL);
260     if (rc_exists (file)) {
261     if ((state == rc_service_starting ||
262     state == rc_service_stopping) &&
263     i == rc_service_inactive)
264     {
265     char *wasfile = rc_strcatpaths (RC_SVCDIR,
266     rc_service_state_names[rc_service_wasinactive],
267     base, (char *) NULL);
268 uberlord 2547
269 uberlord 2577 if (symlink (init, wasfile) != 0)
270     eerror ("symlink `%s' to `%s': %s", init, wasfile,
271     strerror (errno));
272 uberlord 2547
273 uberlord 2577 skip_wasinactive = true;
274     free (wasfile);
275     }
276 uberlord 2547
277 uberlord 2577 errno = 0;
278     if (unlink (file) != 0 && errno != ENOENT)
279     eerror ("failed to delete `%s': %s", file,
280     strerror (errno));
281     }
282     free (file);
283     }
284     i++;
285     }
286 uberlord 2547
287 uberlord 2577 /* Remove the exclusive state if we're inactive */
288     if (state == rc_service_started ||
289     state == rc_service_stopped ||
290     state == rc_service_inactive)
291     {
292     file = rc_strcatpaths (RC_SVCDIR, "exclusive", base, (char *) NULL);
293     if (rc_exists (file))
294     if (unlink (file) != 0)
295     eerror ("unlink `%s': %s", file, strerror (errno));
296     free (file);
297     }
298 uberlord 2547
299 uberlord 2577 /* Remove any options and daemons the service may have stored */
300     if (state == rc_service_stopped) {
301     char *dir = rc_strcatpaths (RC_SVCDIR, "options", base, (char *) NULL);
302 uberlord 2547
303 uberlord 2577 if (rc_is_dir (dir))
304     rc_rm_dir (dir, true);
305     free (dir);
306 uberlord 2547
307 uberlord 2577 dir = rc_strcatpaths (RC_SVCDIR, "daemons", base, (char *) NULL);
308     if (rc_is_dir (dir))
309     rc_rm_dir (dir, true);
310     free (dir);
311 uberlord 2569
312 uberlord 2577 rc_schedule_clear (service);
313     }
314 uberlord 2547
315 uberlord 2577 /* These are final states, so remove us from scheduled */
316     if (state == rc_service_started || state == rc_service_stopped) {
317     char *sdir = rc_strcatpaths (RC_SVCDIR, "scheduled", (char *) NULL);
318     char **dirs = rc_ls_dir (NULL, sdir, 0);
319     char *dir;
320     int serrno;
321 uberlord 2547
322 uberlord 2577 STRLIST_FOREACH (dirs, dir, i) {
323     char *bdir = rc_strcatpaths (sdir, dir, (char *) NULL);
324     file = rc_strcatpaths (bdir, base, (char *) NULL);
325     if (rc_exists (file))
326     if (unlink (file) != 0)
327     eerror ("unlink `%s': %s", file, strerror (errno));
328     free (file);
329 uberlord 2547
330 uberlord 2577 /* Try and remove the dir - we don't care about errors */
331     serrno = errno;
332     rmdir (bdir);
333     errno = serrno;
334     free (bdir);
335     }
336     rc_strlist_free (dirs);
337     free (sdir);
338     }
339 uberlord 2547
340 uberlord 2577 free (init);
341     return (true);
342 uberlord 2547 }
343    
344     bool rc_service_state (const char *service, const rc_service_state_t state)
345     {
346 uberlord 2577 char *file;
347     bool retval;
348 uberlord 2547
349 uberlord 2577 /* If the init script does not exist then we are stopped */
350     if (! rc_service_exists (service))
351     return (state == rc_service_stopped ? true : false);
352 uberlord 2547
353 uberlord 2577 /* We check stopped state by not being in any of the others */
354     if (state == rc_service_stopped)
355     return ( ! (rc_service_state (service, rc_service_started) ||
356     rc_service_state (service, rc_service_starting) ||
357     rc_service_state (service, rc_service_stopping) ||
358     rc_service_state (service, rc_service_inactive)));
359 uberlord 2547
360 uberlord 2577 /* The crashed state and scheduled states are virtual */
361     if (state == rc_service_crashed)
362     return (rc_service_daemons_crashed (service));
363     else if (state == rc_service_scheduled) {
364     char **services = rc_services_scheduled_by (service);
365     retval = (services);
366     if (services)
367     free (services);
368     return (retval);
369     }
370 uberlord 2547
371 uberlord 2577 /* Now we just check if a file by the service name rc_exists
372     in the state dir */
373     file = rc_strcatpaths (RC_SVCDIR, rc_service_state_names[state],
374     basename (service), (char*) NULL);
375     retval = rc_exists (file);
376     free (file);
377     return (retval);
378 uberlord 2547 }
379    
380     bool rc_get_service_option (const char *service, const char *option,
381 uberlord 2577 char *value)
382 uberlord 2547 {
383 uberlord 2577 FILE *fp;
384     char buffer[RC_LINEBUFFER];
385     char *file = rc_strcatpaths (RC_SVCDIR, "options", service, option,
386     (char *) NULL);
387     bool retval = false;
388 uberlord 2547
389 uberlord 2577 if (rc_exists (file)) {
390     if ((fp = fopen (file, "r")) == NULL)
391     eerror ("fopen `%s': %s", file, strerror (errno));
392     else {
393     memset (buffer, 0, sizeof (buffer));
394     while (fgets (buffer, RC_LINEBUFFER, fp)) {
395     memcpy (value, buffer, strlen (buffer));
396     value += strlen (buffer);
397     }
398     fclose (fp);
399     retval = true;
400     }
401     }
402 uberlord 2547
403 uberlord 2577 free (file);
404     return (retval);
405 uberlord 2547 }
406    
407     bool rc_set_service_option (const char *service, const char *option,
408 uberlord 2577 const char *value)
409 uberlord 2547 {
410 uberlord 2577 FILE *fp;
411     char *path = rc_strcatpaths (RC_SVCDIR, "options", service, (char *) NULL);
412     char *file = rc_strcatpaths (path, option, (char *) NULL);
413     bool retval = false;
414 uberlord 2547
415 uberlord 2577 if (! rc_is_dir (path)) {
416     if (mkdir (path, 0755) != 0) {
417     eerror ("mkdir `%s': %s", path, strerror (errno));
418     free (path);
419     free (file);
420     return (false);
421     }
422     }
423 uberlord 2547
424 uberlord 2577 if ((fp = fopen (file, "w")) == NULL)
425     eerror ("fopen `%s': %s", file, strerror (errno));
426     else {
427     if (value)
428     fprintf (fp, "%s", value);
429     fclose (fp);
430     retval = true;
431     }
432 uberlord 2547
433 uberlord 2577 free (path);
434     free (file);
435     return (retval);
436 uberlord 2547 }
437    
438     static pid_t _exec_service (const char *service, const char *arg)
439     {
440 uberlord 2577 char *file;
441     char *fifo;
442     pid_t pid = -1;
443     pid_t savedpid;
444     int status;
445 uberlord 2547
446 uberlord 2577 file = rc_resolve_service (service);
447     if (! rc_is_file (file)) {
448     rc_mark_service (service, rc_service_stopped);
449     free (file);
450     return (0);
451     }
452 uberlord 2547
453 uberlord 2577 /* We create a fifo so that other services can wait until we complete */
454     fifo = rc_strcatpaths (RC_SVCDIR, "exclusive", basename (service),
455     (char *) NULL);
456 uberlord 2547
457 uberlord 2577 if (mkfifo (fifo, 0600) != 0 && errno != EEXIST) {
458     eerror ("unable to create fifo `%s': %s", fifo, strerror (errno));
459     free (fifo);
460     free (file);
461     return (-1);
462     }
463 uberlord 2547
464 uberlord 2577 if ((pid = fork ()) == 0) {
465     char *myarg = strdup (arg);
466     int e = 0;
467     execl (file, file, myarg, (char *) NULL);
468     e = errno;
469     free (myarg);
470     unlink (fifo);
471     free (fifo);
472     eerrorx ("unable to exec `%s': %s", file, strerror (errno));
473     }
474 uberlord 2547
475 uberlord 2577 free (fifo);
476     free (file);
477 uberlord 2547
478 uberlord 2577 if (pid == -1) {
479     eerror ("unable to fork: %s", strerror (errno));
480     return (pid);
481     }
482 uberlord 2547
483 uberlord 2577 if (rc_is_env ("RC_PARALLEL_STARTUP", "yes"))
484     return (pid);
485 uberlord 2547
486 uberlord 2577 savedpid = pid;
487     errno = 0;
488     do {
489     pid = waitpid (savedpid, &status, 0);
490     if (pid < 0) {
491     if (errno != ECHILD)
492     eerror ("waitpid %d: %s", savedpid, strerror (errno));
493     return (-1);
494     }
495     } while (! WIFEXITED (status) && ! WIFSIGNALED (status));
496 uberlord 2547
497 uberlord 2577 return (0);
498 uberlord 2547 }
499    
500     pid_t rc_stop_service (const char *service)
501     {
502 uberlord 2577 if (rc_service_state (service, rc_service_stopped))
503     return (0);
504 uberlord 2547
505 uberlord 2577 return (_exec_service (service, "stop"));
506 uberlord 2547 }
507    
508    
509     pid_t rc_start_service (const char *service)
510     {
511 uberlord 2577 if (! rc_service_state (service, rc_service_stopped))
512     return (0);
513 uberlord 2547
514 uberlord 2577 return (_exec_service (service, "start"));
515 uberlord 2547 }
516    
517     void rc_schedule_start_service (const char *service,
518 uberlord 2577 const char *service_to_start)
519 uberlord 2547 {
520 uberlord 2577 char *dir;
521     char *init;
522     char *file;
523 uberlord 2547
524 uberlord 2577 /* service may be a provided service, like net */
525     if (! service || ! rc_service_exists (service_to_start))
526     return;
527 uberlord 2547
528 uberlord 2577 dir = rc_strcatpaths (RC_SVCDIR, "scheduled", basename (service),
529     (char *) NULL);
530     if (! rc_is_dir (dir))
531     if (mkdir (dir, 0755) != 0) {
532     eerror ("mkdir `%s': %s", dir, strerror (errno));
533     free (dir);
534     return;
535     }
536 uberlord 2547
537 uberlord 2577 init = rc_resolve_service (service_to_start);
538     file = rc_strcatpaths (dir, basename (service_to_start), (char *) NULL);
539     if (! rc_exists (file) && symlink (init, file) != 0)
540     eerror ("symlink `%s' to `%s': %s", init, file, strerror (errno));
541 uberlord 2547
542 uberlord 2577 free (init);
543     free (file);
544     free (dir);
545 uberlord 2547 }
546    
547     void rc_schedule_clear (const char *service)
548     {
549 uberlord 2577 char *dir = rc_strcatpaths (RC_SVCDIR, "scheduled", basename (service),
550     (char *) NULL);
551 uberlord 2547
552 uberlord 2577 if (rc_is_dir (dir))
553     rc_rm_dir (dir, true);
554     free (dir);
555 uberlord 2547 }
556    
557     bool rc_wait_service (const char *service)
558     {
559 uberlord 2577 char *fifo = rc_strcatpaths (RC_SVCDIR, "exclusive", basename (service),
560     (char *) NULL);
561     struct timeval tv;
562     struct timeval stopat;
563     struct timeval now;
564     bool retval = false;
565 uberlord 2547
566 uberlord 2577 if (gettimeofday (&stopat, NULL) != 0) {
567     eerror ("gettimeofday: %s", strerror (errno));
568     return (false);
569     }
570     stopat.tv_sec += WAIT_MAX;
571 uberlord 2547
572 uberlord 2577 while (true) {
573     if (! rc_exists (fifo)) {
574     retval = true;
575     break;
576     }
577 uberlord 2547
578 uberlord 2577 tv.tv_sec = 0;
579     tv.tv_usec = WAIT_INTERVAL;
580     if (select (0, 0, 0, 0, &tv) < 0) {
581     if (errno != EINTR)
582     eerror ("select: %s",strerror (errno));
583     break;
584     }
585 uberlord 2547
586 uberlord 2577 /* Don't hang around forever */
587     if (gettimeofday (&now, NULL) != 0) {
588     eerror ("gettimeofday: %s", strerror (errno));
589     break;
590     }
591 uberlord 2547
592 uberlord 2577 if (timercmp (&now, &stopat, >))
593     break;
594     }
595    
596     free (fifo);
597     return (retval);
598 uberlord 2547 }
599    
600     char **rc_services_in_runlevel (const char *runlevel)
601     {
602 uberlord 2577 char *dir;
603     char **list = NULL;
604 uberlord 2547
605 uberlord 2577 if (! runlevel)
606     return (rc_ls_dir (NULL, RC_INITDIR, RC_LS_INITD));
607 uberlord 2547
608 uberlord 2577 /* These special levels never contain any services */
609     if (strcmp (runlevel, RC_LEVEL_SYSINIT) == 0 ||
610     strcmp (runlevel, RC_LEVEL_SINGLE) == 0)
611     return (NULL);
612 uberlord 2547
613 uberlord 2577 dir = rc_strcatpaths (RC_RUNLEVELDIR, runlevel, (char *) NULL);
614     if (! rc_is_dir (dir))
615     eerror ("runlevel `%s' does not exist", runlevel);
616     else
617     list = rc_ls_dir (list, dir, RC_LS_INITD);
618 uberlord 2547
619 uberlord 2577 free (dir);
620     return (list);
621 uberlord 2547 }
622    
623     char **rc_services_in_state (rc_service_state_t state)
624     {
625 uberlord 2577 char *dir = rc_strcatpaths (RC_SVCDIR, rc_service_state_names[state],
626     (char *) NULL);
627     char **list = NULL;
628 uberlord 2547
629 uberlord 2577 if (state == rc_service_scheduled) {
630     char **dirs = rc_ls_dir (NULL, dir, 0);
631     char *d;
632     int i;
633 uberlord 2547
634 uberlord 2577 STRLIST_FOREACH (dirs, d, i) {
635     char *p = rc_strcatpaths (dir, d, (char *) NULL);
636     char **entries = rc_ls_dir (NULL, p, RC_LS_INITD);
637     char *e;
638     int j;
639 uberlord 2573
640 uberlord 2577 STRLIST_FOREACH (entries, e, j)
641     list = rc_strlist_addsortu (list, e);
642 uberlord 2573
643 uberlord 2577 if (entries)
644     free (entries);
645     }
646 uberlord 2573
647 uberlord 2577 if (dirs)
648     free (dirs);
649     } else {
650     if (rc_is_dir (dir))
651     list = rc_ls_dir (list, dir, RC_LS_INITD);
652     }
653 uberlord 2573
654 uberlord 2577 free (dir);
655     return (list);
656 uberlord 2547 }
657    
658     bool rc_service_add (const char *runlevel, const char *service)
659     {
660 uberlord 2577 bool retval;
661     char *init;
662     char *file;
663 uberlord 2547
664 uberlord 2577 if (! rc_runlevel_exists (runlevel)) {
665     errno = ENOENT;
666     return (false);
667     }
668 uberlord 2569
669 uberlord 2577 if (rc_service_in_runlevel (service, runlevel)) {
670     errno = EEXIST;
671     return (false);
672     }
673 uberlord 2547
674 uberlord 2577 init = rc_resolve_service (service);
675     file = rc_strcatpaths (RC_RUNLEVELDIR, runlevel, basename (service),
676     (char *) NULL);
677     retval = (symlink (init, file) == 0);
678     free (init);
679     free (file);
680     return (retval);
681 uberlord 2547 }
682    
683     bool rc_service_delete (const char *runlevel, const char *service)
684     {
685 uberlord 2577 char *file;
686     bool retval = false;
687 uberlord 2547
688 uberlord 2577 if (! runlevel || ! service)
689     return (false);
690 uberlord 2569
691 uberlord 2577 file = rc_strcatpaths (RC_RUNLEVELDIR, runlevel, basename (service),
692     (char *) NULL);
693     if (unlink (file) == 0)
694     retval = true;
695 uberlord 2569
696 uberlord 2577 free (file);
697     return (retval);
698 uberlord 2547 }
699    
700     char **rc_services_scheduled_by (const char *service)
701     {
702 uberlord 2577 char **dirs = rc_ls_dir (NULL, RC_SVCDIR "scheduled", 0);
703     char **list = NULL;
704     char *dir;
705     int i;
706 uberlord 2547
707 uberlord 2577 STRLIST_FOREACH (dirs, dir, i) {
708     char *file = rc_strcatpaths (RC_SVCDIR "scheduled", dir, service,
709     (char *) NULL);
710     if (rc_exists (file))
711     list = rc_strlist_add (list, file);
712     free (file);
713     }
714     rc_strlist_free (dirs);
715 uberlord 2569
716 uberlord 2577 return (list);
717 uberlord 2547 }
718    
719     char **rc_services_scheduled (const char *service)
720     {
721 uberlord 2577 char *dir = rc_strcatpaths (RC_SVCDIR, "scheduled", basename (service),
722     (char *) NULL);
723     char **list = NULL;
724 uberlord 2547
725 uberlord 2577 if (rc_is_dir (dir))
726     list = rc_ls_dir (list, dir, RC_LS_INITD);
727 uberlord 2547
728 uberlord 2577 free (dir);
729     return (list);
730 uberlord 2547 }
731    
732     bool rc_allow_plug (char *service)
733     {
734 uberlord 2577 char *list;
735     char *p;
736     char *star;
737     char *token;
738     bool allow = true;
739     char *match = getenv ("RC_PLUG_SERVICES");
740     if (! match)
741     return true;
742 uberlord 2547
743 uberlord 2577 list = strdup (match);
744     p = list;
745     while ((token = strsep (&p, " "))) {
746     bool truefalse = true;
747     if (token[0] == '!') {
748     truefalse = false;
749     token++;
750     }
751 uberlord 2547
752 uberlord 2577 star = strchr (token, '*');
753     if (star) {
754     if (strncmp (service, token, star - token) == 0) {
755     allow = truefalse;
756     break;
757     }
758     } else {
759     if (strcmp (service, token) == 0) {
760     allow = truefalse;
761     break;
762     }
763     }
764     }
765 uberlord 2547
766 uberlord 2577 free (list);
767     return (allow);
768 uberlord 2547 }

  ViewVC Help
Powered by ViewVC 1.1.20