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

Contents of /trunk/src/librc.c

Parent Directory Parent Directory | Revision Log Revision Log


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

  ViewVC Help
Powered by ViewVC 1.1.20