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

Contents of /trunk/src/librc.c

Parent Directory Parent Directory | Revision Log Revision Log


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

  ViewVC Help
Powered by ViewVC 1.1.20