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

Contents of /trunk/src/librc.c

Parent Directory Parent Directory | Revision Log Revision Log


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

  ViewVC Help
Powered by ViewVC 1.1.20