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

Contents of /trunk/src/librc.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2643 - (hide annotations) (download) (as text)
Sat Apr 21 08:34:16 2007 UTC (8 years, 4 months ago) by uberlord
File MIME type: text/x-csrc
File size: 17744 byte(s)
Don't free in vfork
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 uberlord 2596 char *svc;
449 uberlord 2547
450 uberlord 2577 file = rc_resolve_service (service);
451     if (! rc_is_file (file)) {
452     rc_mark_service (service, rc_service_stopped);
453     free (file);
454     return (0);
455     }
456 uberlord 2547
457 uberlord 2577 /* We create a fifo so that other services can wait until we complete */
458 uberlord 2596 svc = rc_xstrdup (service);
459     fifo = rc_strcatpaths (RC_SVCDIR, "exclusive", basename (svc),
460 uberlord 2577 (char *) NULL);
461 uberlord 2596 free (svc);
462 uberlord 2547
463 uberlord 2577 if (mkfifo (fifo, 0600) != 0 && errno != EEXIST) {
464     eerror ("unable to create fifo `%s': %s", fifo, strerror (errno));
465     free (fifo);
466     free (file);
467     return (-1);
468     }
469 uberlord 2547
470 uberlord 2638 if ((pid = vfork ()) == 0) {
471 uberlord 2577 int e = 0;
472 uberlord 2638 execl (file, file, arg, (char *) NULL);
473 uberlord 2577 e = errno;
474     unlink (fifo);
475 uberlord 2638 eerror ("unable to exec `%s': %s", file, strerror (errno));
476     _exit (EXIT_FAILURE);
477 uberlord 2577 }
478 uberlord 2547
479 uberlord 2577 free (fifo);
480     free (file);
481 uberlord 2547
482 uberlord 2641 if (pid == -1)
483 uberlord 2638 eerror ("vfork: %s", strerror (errno));
484 uberlord 2641
485     return (pid);
486     }
487 uberlord 2547
488 uberlord 2641 int rc_waitpid (pid_t pid) {
489     int status = 0;
490     pid_t savedpid = pid;
491 uberlord 2547
492 uberlord 2577 errno = 0;
493     do {
494     pid = waitpid (savedpid, &status, 0);
495     if (pid < 0) {
496     if (errno != ECHILD)
497     eerror ("waitpid %d: %s", savedpid, strerror (errno));
498     return (-1);
499     }
500     } while (! WIFEXITED (status) && ! WIFSIGNALED (status));
501 uberlord 2641
502     return (WIFEXITED (status) ? WEXITSTATUS (status) : EXIT_FAILURE);
503 uberlord 2547 }
504    
505     pid_t rc_stop_service (const char *service)
506     {
507 uberlord 2577 if (rc_service_state (service, rc_service_stopped))
508     return (0);
509 uberlord 2547
510 uberlord 2577 return (_exec_service (service, "stop"));
511 uberlord 2547 }
512 vapier 2597 librc_hidden_def(rc_stop_service)
513 uberlord 2547
514     pid_t rc_start_service (const char *service)
515     {
516 uberlord 2577 if (! rc_service_state (service, rc_service_stopped))
517     return (0);
518 uberlord 2547
519 uberlord 2577 return (_exec_service (service, "start"));
520 uberlord 2547 }
521 vapier 2597 librc_hidden_def(rc_start_service)
522 uberlord 2547
523     void rc_schedule_start_service (const char *service,
524 uberlord 2577 const char *service_to_start)
525 uberlord 2547 {
526 uberlord 2577 char *dir;
527     char *init;
528     char *file;
529 uberlord 2596 char *svc;
530 uberlord 2547
531 uberlord 2577 /* service may be a provided service, like net */
532     if (! service || ! rc_service_exists (service_to_start))
533     return;
534 uberlord 2547
535 uberlord 2596 svc = rc_xstrdup (service);
536     dir = rc_strcatpaths (RC_SVCDIR, "scheduled", basename (svc),
537 uberlord 2577 (char *) NULL);
538 uberlord 2596 free (svc);
539 uberlord 2577 if (! rc_is_dir (dir))
540     if (mkdir (dir, 0755) != 0) {
541     eerror ("mkdir `%s': %s", dir, strerror (errno));
542     free (dir);
543     return;
544     }
545 uberlord 2547
546 uberlord 2577 init = rc_resolve_service (service_to_start);
547 uberlord 2596 svc = rc_xstrdup (service_to_start);
548     file = rc_strcatpaths (dir, basename (svc), (char *) NULL);
549     free (svc);
550 uberlord 2577 if (! rc_exists (file) && symlink (init, file) != 0)
551     eerror ("symlink `%s' to `%s': %s", init, file, strerror (errno));
552 uberlord 2547
553 uberlord 2577 free (init);
554     free (file);
555     free (dir);
556 uberlord 2547 }
557 vapier 2597 librc_hidden_def(rc_schedule_start_service)
558 uberlord 2547
559     void rc_schedule_clear (const char *service)
560     {
561 uberlord 2596 char *svc = rc_xstrdup (service);
562     char *dir = rc_strcatpaths (RC_SVCDIR, "scheduled", basename (svc),
563 uberlord 2577 (char *) NULL);
564 uberlord 2547
565 uberlord 2596 free (svc);
566 uberlord 2577 if (rc_is_dir (dir))
567     rc_rm_dir (dir, true);
568     free (dir);
569 uberlord 2547 }
570 vapier 2597 librc_hidden_def(rc_schedule_clear)
571 uberlord 2547
572     bool rc_wait_service (const char *service)
573     {
574 uberlord 2596 char *svc = rc_xstrdup (service);
575     char *fifo = rc_strcatpaths (RC_SVCDIR, "exclusive", basename (svc),
576 uberlord 2577 (char *) NULL);
577     struct timeval tv;
578     struct timeval stopat;
579     struct timeval now;
580     bool retval = false;
581 uberlord 2547
582 uberlord 2596 free (svc);
583 uberlord 2577 if (gettimeofday (&stopat, NULL) != 0) {
584     eerror ("gettimeofday: %s", strerror (errno));
585     return (false);
586     }
587     stopat.tv_sec += WAIT_MAX;
588 uberlord 2547
589 uberlord 2577 while (true) {
590     if (! rc_exists (fifo)) {
591     retval = true;
592     break;
593     }
594 uberlord 2547
595 uberlord 2577 tv.tv_sec = 0;
596     tv.tv_usec = WAIT_INTERVAL;
597     if (select (0, 0, 0, 0, &tv) < 0) {
598     if (errno != EINTR)
599     eerror ("select: %s",strerror (errno));
600     break;
601     }
602 uberlord 2547
603 uberlord 2577 /* Don't hang around forever */
604     if (gettimeofday (&now, NULL) != 0) {
605     eerror ("gettimeofday: %s", strerror (errno));
606     break;
607     }
608 uberlord 2547
609 uberlord 2577 if (timercmp (&now, &stopat, >))
610     break;
611     }
612    
613     free (fifo);
614     return (retval);
615 uberlord 2547 }
616 vapier 2597 librc_hidden_def(rc_wait_service)
617 uberlord 2547
618     char **rc_services_in_runlevel (const char *runlevel)
619     {
620 uberlord 2577 char *dir;
621     char **list = NULL;
622 uberlord 2547
623 uberlord 2577 if (! runlevel)
624     return (rc_ls_dir (NULL, RC_INITDIR, RC_LS_INITD));
625 uberlord 2547
626 uberlord 2577 /* These special levels never contain any services */
627     if (strcmp (runlevel, RC_LEVEL_SYSINIT) == 0 ||
628     strcmp (runlevel, RC_LEVEL_SINGLE) == 0)
629     return (NULL);
630 uberlord 2547
631 uberlord 2577 dir = rc_strcatpaths (RC_RUNLEVELDIR, runlevel, (char *) NULL);
632     if (! rc_is_dir (dir))
633     eerror ("runlevel `%s' does not exist", runlevel);
634     else
635     list = rc_ls_dir (list, dir, RC_LS_INITD);
636 uberlord 2547
637 uberlord 2577 free (dir);
638     return (list);
639 uberlord 2547 }
640 vapier 2597 librc_hidden_def(rc_services_in_runlevel)
641 uberlord 2547
642     char **rc_services_in_state (rc_service_state_t state)
643     {
644 uberlord 2577 char *dir = rc_strcatpaths (RC_SVCDIR, rc_service_state_names[state],
645     (char *) NULL);
646     char **list = NULL;
647 uberlord 2547
648 uberlord 2577 if (state == rc_service_scheduled) {
649     char **dirs = rc_ls_dir (NULL, dir, 0);
650     char *d;
651     int i;
652 uberlord 2547
653 uberlord 2577 STRLIST_FOREACH (dirs, d, i) {
654     char *p = rc_strcatpaths (dir, d, (char *) NULL);
655     char **entries = rc_ls_dir (NULL, p, RC_LS_INITD);
656     char *e;
657     int j;
658 uberlord 2573
659 uberlord 2577 STRLIST_FOREACH (entries, e, j)
660     list = rc_strlist_addsortu (list, e);
661 uberlord 2573
662 uberlord 2577 if (entries)
663     free (entries);
664     }
665 uberlord 2573
666 uberlord 2577 if (dirs)
667     free (dirs);
668     } else {
669     if (rc_is_dir (dir))
670     list = rc_ls_dir (list, dir, RC_LS_INITD);
671     }
672 uberlord 2573
673 uberlord 2577 free (dir);
674     return (list);
675 uberlord 2547 }
676 vapier 2597 librc_hidden_def(rc_services_in_state)
677 uberlord 2547
678     bool rc_service_add (const char *runlevel, const char *service)
679     {
680 uberlord 2577 bool retval;
681     char *init;
682     char *file;
683 uberlord 2596 char *svc;
684 uberlord 2547
685 uberlord 2577 if (! rc_runlevel_exists (runlevel)) {
686     errno = ENOENT;
687     return (false);
688     }
689 uberlord 2569
690 uberlord 2577 if (rc_service_in_runlevel (service, runlevel)) {
691     errno = EEXIST;
692     return (false);
693     }
694 uberlord 2547
695 uberlord 2577 init = rc_resolve_service (service);
696 uberlord 2596 svc = rc_xstrdup (service);
697     file = rc_strcatpaths (RC_RUNLEVELDIR, runlevel, basename (svc),
698 uberlord 2577 (char *) NULL);
699 uberlord 2596 free (svc);
700 uberlord 2577 retval = (symlink (init, file) == 0);
701     free (init);
702     free (file);
703     return (retval);
704 uberlord 2547 }
705 vapier 2597 librc_hidden_def(rc_service_add)
706 uberlord 2547
707     bool rc_service_delete (const char *runlevel, const char *service)
708     {
709 uberlord 2577 char *file;
710 uberlord 2596 char *svc;
711 uberlord 2577 bool retval = false;
712 uberlord 2547
713 uberlord 2577 if (! runlevel || ! service)
714     return (false);
715 uberlord 2569
716 uberlord 2596 svc = rc_xstrdup (service);
717     file = rc_strcatpaths (RC_RUNLEVELDIR, runlevel, basename (svc),
718 uberlord 2577 (char *) NULL);
719 uberlord 2596 free (svc);
720 uberlord 2577 if (unlink (file) == 0)
721     retval = true;
722 uberlord 2569
723 uberlord 2577 free (file);
724     return (retval);
725 uberlord 2547 }
726 vapier 2597 librc_hidden_def(rc_service_delete)
727 uberlord 2547
728     char **rc_services_scheduled_by (const char *service)
729     {
730 uberlord 2577 char **dirs = rc_ls_dir (NULL, RC_SVCDIR "scheduled", 0);
731     char **list = NULL;
732     char *dir;
733     int i;
734 uberlord 2547
735 uberlord 2577 STRLIST_FOREACH (dirs, dir, i) {
736     char *file = rc_strcatpaths (RC_SVCDIR "scheduled", dir, service,
737     (char *) NULL);
738     if (rc_exists (file))
739     list = rc_strlist_add (list, file);
740     free (file);
741     }
742     rc_strlist_free (dirs);
743 uberlord 2569
744 uberlord 2577 return (list);
745 uberlord 2547 }
746 vapier 2597 librc_hidden_def(rc_services_scheduled_by)
747 uberlord 2547
748     char **rc_services_scheduled (const char *service)
749     {
750 uberlord 2596 char *svc = rc_xstrdup (service);
751     char *dir = rc_strcatpaths (RC_SVCDIR, "scheduled", basename (svc),
752 uberlord 2577 (char *) NULL);
753     char **list = NULL;
754 uberlord 2547
755 uberlord 2577 if (rc_is_dir (dir))
756     list = rc_ls_dir (list, dir, RC_LS_INITD);
757 uberlord 2547
758 uberlord 2596 free (svc);
759 uberlord 2577 free (dir);
760     return (list);
761 uberlord 2547 }
762 vapier 2597 librc_hidden_def(rc_services_scheduled)
763 uberlord 2547
764     bool rc_allow_plug (char *service)
765     {
766 uberlord 2577 char *list;
767     char *p;
768     char *star;
769     char *token;
770     bool allow = true;
771     char *match = getenv ("RC_PLUG_SERVICES");
772     if (! match)
773     return true;
774 uberlord 2547
775 uberlord 2596 list = rc_xstrdup (match);
776 uberlord 2577 p = list;
777     while ((token = strsep (&p, " "))) {
778     bool truefalse = true;
779     if (token[0] == '!') {
780     truefalse = false;
781     token++;
782     }
783 uberlord 2547
784 uberlord 2577 star = strchr (token, '*');
785     if (star) {
786     if (strncmp (service, token, star - token) == 0) {
787     allow = truefalse;
788     break;
789     }
790     } else {
791     if (strcmp (service, token) == 0) {
792     allow = truefalse;
793     break;
794     }
795     }
796     }
797 uberlord 2547
798 uberlord 2577 free (list);
799     return (allow);
800 uberlord 2547 }
801 vapier 2597 librc_hidden_def(rc_allow_plug)

  ViewVC Help
Powered by ViewVC 1.1.20