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

Contents of /trunk/src/librc.c

Parent Directory Parent Directory | Revision Log Revision Log


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

  ViewVC Help
Powered by ViewVC 1.1.20