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

Contents of /trunk/src/librc.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2634 - (hide annotations) (download) (as text)
Thu Apr 19 14:54:35 2007 UTC (7 years, 3 months ago) by uberlord
File MIME type: text/x-csrc
File size: 17694 byte(s)
strdup -> rc_xstrdup
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     static const char *rc_service_state_names[] = {
19 uberlord 2577 "started",
20     "stopped",
21     "starting",
22     "stopping",
23     "inactive",
24     "wasinactive",
25     "coldplugged",
26     "failed",
27     "scheduled",
28     NULL
29 uberlord 2547 };
30    
31     bool rc_runlevel_starting (void)
32     {
33 uberlord 2577 return (rc_is_dir (RC_SVCDIR "softscripts.old"));
34 uberlord 2547 }
35 vapier 2597 librc_hidden_def(rc_runlevel_starting)
36 uberlord 2547
37     bool rc_runlevel_stopping (void)
38     {
39 uberlord 2577 return (rc_is_dir (RC_SVCDIR "softscripts.new"));
40 uberlord 2547 }
41 vapier 2597 librc_hidden_def(rc_runlevel_stopping)
42 uberlord 2547
43     char **rc_get_runlevels (void)
44     {
45 uberlord 2577 char **dirs = rc_ls_dir (NULL, RC_RUNLEVELDIR, 0);
46     char **runlevels = NULL;
47     int i;
48     char *dir;
49 uberlord 2547
50 uberlord 2577 STRLIST_FOREACH (dirs, dir, i) {
51     char *path = rc_strcatpaths (RC_RUNLEVELDIR, dir, (char *) NULL);
52     if (rc_is_dir (path))
53     runlevels = rc_strlist_addsort (runlevels, dir);
54     free (path);
55     }
56     rc_strlist_free (dirs);
57 uberlord 2547
58 uberlord 2577 return (runlevels);
59 uberlord 2547 }
60 vapier 2597 librc_hidden_def(rc_get_runlevels)
61 uberlord 2547
62     char *rc_get_runlevel (void)
63     {
64 uberlord 2577 FILE *fp;
65     static char buffer [PATH_MAX];
66 uberlord 2547
67 uberlord 2577 if (! (fp = fopen (SOFTLEVEL, "r"))) {
68     snprintf (buffer, sizeof (buffer), "sysinit");
69     return (buffer);
70     }
71 uberlord 2547
72 uberlord 2577 if (fgets (buffer, PATH_MAX, fp)) {
73     int i = strlen (buffer) - 1;
74     if (buffer[i] == '\n')
75     buffer[i] = 0;
76     fclose (fp);
77     return (buffer);
78     }
79 uberlord 2547
80 uberlord 2577 fclose (fp);
81     snprintf (buffer, sizeof (buffer), "sysinit");
82     return (buffer);
83 uberlord 2547 }
84 vapier 2597 librc_hidden_def(rc_get_runlevel)
85 uberlord 2547
86     void rc_set_runlevel (const char *runlevel)
87     {
88 uberlord 2577 FILE *fp = fopen (SOFTLEVEL, "w");
89     if (! fp)
90     eerrorx ("failed to open `" SOFTLEVEL "': %s", strerror (errno));
91     fprintf (fp, "%s", runlevel);
92     fclose (fp);
93 uberlord 2547 }
94 vapier 2597 librc_hidden_def(rc_set_runlevel)
95 uberlord 2547
96     bool rc_runlevel_exists (const char *runlevel)
97     {
98 uberlord 2577 char *path;
99     bool retval;
100 uberlord 2547
101 uberlord 2577 if (! runlevel)
102     return (false);
103 uberlord 2547
104 uberlord 2577 path = rc_strcatpaths (RC_RUNLEVELDIR, runlevel, (char *) NULL);
105     retval = rc_is_dir (path);
106     free (path);
107     return (retval);
108 uberlord 2547 }
109 vapier 2597 librc_hidden_def(rc_runlevel_exists)
110 uberlord 2547
111     /* Resolve a service name to it's full path */
112     char *rc_resolve_service (const char *service)
113     {
114 uberlord 2577 char buffer[PATH_MAX];
115     char *file;
116     int r = 0;
117 uberlord 2547
118 uberlord 2577 if (! service)
119     return (NULL);
120 uberlord 2547
121 uberlord 2577 if (service[0] == '/')
122     return (strdup (service));
123 uberlord 2547
124 uberlord 2577 file = rc_strcatpaths (RC_SVCDIR, "started", service, (char *) NULL);
125     if (! rc_is_link (file)) {
126     free (file);
127     file = rc_strcatpaths (RC_SVCDIR, "inactive", service, (char *) NULL);
128     if (! rc_is_link (file)) {
129     free (file);
130     file = NULL;
131     }
132     }
133 uberlord 2547
134 uberlord 2577 memset (buffer, 0, sizeof (buffer));
135     if (file) {
136     r = readlink (file, buffer, sizeof (buffer));
137     free (file);
138     if (r > 0)
139 uberlord 2634 return (rc_xstrdup (buffer));
140 uberlord 2577 }
141 uberlord 2547
142 uberlord 2577 snprintf (buffer, sizeof (buffer), RC_INITDIR "%s", service);
143     return (strdup (buffer));
144 uberlord 2547 }
145 vapier 2597 librc_hidden_def(rc_resolve_service)
146 uberlord 2547
147     bool rc_service_exists (const char *service)
148     {
149 uberlord 2577 char *file;
150     bool retval = false;
151     int len;
152 uberlord 2547
153 uberlord 2577 if (! service)
154     return (false);
155 uberlord 2547
156 uberlord 2577 len = strlen (service);
157 uberlord 2547
158 uberlord 2577 /* .sh files are not init scripts */
159     if (len > 2 && service[len - 3] == '.' &&
160     service[len - 2] == 's' &&
161     service[len - 1] == 'h')
162     return (false);
163 uberlord 2547
164 uberlord 2577 file = rc_resolve_service (service);
165     if (rc_exists (file))
166     retval = rc_is_exec (file);
167     free (file);
168     return (retval);
169 uberlord 2547 }
170 vapier 2597 librc_hidden_def(rc_service_exists)
171 uberlord 2547
172     bool rc_service_in_runlevel (const char *service, const char *runlevel)
173     {
174 uberlord 2577 char *file;
175     bool retval;
176 uberlord 2596 char *svc;
177 uberlord 2547
178 uberlord 2577 if (! runlevel || ! service)
179     return (false);
180 uberlord 2547
181 uberlord 2577 if (! rc_service_exists (service))
182     return (false);
183 uberlord 2547
184 uberlord 2596 svc = rc_xstrdup (service);
185     file = rc_strcatpaths (RC_RUNLEVELDIR, runlevel, basename (svc),
186 uberlord 2577 (char *) NULL);
187 uberlord 2596 free (svc);
188 uberlord 2577 retval = rc_exists (file);
189     free (file);
190 uberlord 2547
191 uberlord 2577 return (retval);
192 uberlord 2547 }
193 vapier 2597 librc_hidden_def(rc_service_in_runlevel)
194 uberlord 2547
195     bool rc_mark_service (const char *service, const rc_service_state_t state)
196     {
197 uberlord 2577 char *file;
198     int i = 0;
199     int skip_state = -1;
200     char *base;
201 uberlord 2596 char *svc;
202 uberlord 2577 char *init = rc_resolve_service (service);
203     bool skip_wasinactive = false;
204 uberlord 2547
205 uberlord 2577 if (! service)
206     return (false);
207 uberlord 2547
208 uberlord 2596 svc = rc_xstrdup (service);
209     base = basename (svc);
210 uberlord 2547
211 uberlord 2577 if (state != rc_service_stopped) {
212     if (! rc_is_file(init)) {
213     free (init);
214 uberlord 2596 free (svc);
215 uberlord 2577 return (false);
216     }
217 uberlord 2547
218 uberlord 2577 file = rc_strcatpaths (RC_SVCDIR, rc_service_state_names[state], base,
219     (char *) NULL);
220     if (rc_exists (file))
221     unlink (file);
222     i = symlink (init, file);
223     if (i != 0) {
224     free (file);
225     free (init);
226 uberlord 2596 free (svc);
227 uberlord 2577 einfo ("%d %s %s", state, rc_service_state_names[state], base);
228     eerror ("symlink `%s' to `%s': %s", init, file, strerror (errno));
229     return (false);
230     }
231 uberlord 2547
232 uberlord 2577 free (file);
233     skip_state = state;
234     }
235 uberlord 2547
236 uberlord 2577 if (state == rc_service_coldplugged) {
237     free (init);
238 uberlord 2596 free (svc);
239 uberlord 2577 return (true);
240     }
241 uberlord 2547
242 uberlord 2577 /* Remove any old states now */
243     i = 0;
244     while (rc_service_state_names[i]) {
245     if ((i != skip_state &&
246     i != rc_service_stopped &&
247     i != rc_service_coldplugged &&
248     i != rc_service_scheduled &&
249     i != rc_service_crashed) &&
250     (! skip_wasinactive || i != rc_service_wasinactive))
251     {
252     file = rc_strcatpaths (RC_SVCDIR, rc_service_state_names[i], base,
253     (char *) NULL);
254     if (rc_exists (file)) {
255     if ((state == rc_service_starting ||
256     state == rc_service_stopping) &&
257     i == rc_service_inactive)
258     {
259     char *wasfile = rc_strcatpaths (RC_SVCDIR,
260     rc_service_state_names[rc_service_wasinactive],
261     base, (char *) NULL);
262 uberlord 2547
263 uberlord 2577 if (symlink (init, wasfile) != 0)
264     eerror ("symlink `%s' to `%s': %s", init, wasfile,
265     strerror (errno));
266 uberlord 2547
267 uberlord 2577 skip_wasinactive = true;
268     free (wasfile);
269     }
270 uberlord 2547
271 uberlord 2577 errno = 0;
272     if (unlink (file) != 0 && errno != ENOENT)
273     eerror ("failed to delete `%s': %s", file,
274     strerror (errno));
275     }
276     free (file);
277     }
278     i++;
279     }
280 uberlord 2547
281 uberlord 2577 /* Remove the exclusive state if we're inactive */
282     if (state == rc_service_started ||
283     state == rc_service_stopped ||
284     state == rc_service_inactive)
285     {
286     file = rc_strcatpaths (RC_SVCDIR, "exclusive", base, (char *) NULL);
287     if (rc_exists (file))
288     if (unlink (file) != 0)
289     eerror ("unlink `%s': %s", file, strerror (errno));
290     free (file);
291     }
292 uberlord 2547
293 uberlord 2577 /* Remove any options and daemons the service may have stored */
294     if (state == rc_service_stopped) {
295     char *dir = rc_strcatpaths (RC_SVCDIR, "options", base, (char *) NULL);
296 uberlord 2547
297 uberlord 2577 if (rc_is_dir (dir))
298     rc_rm_dir (dir, true);
299     free (dir);
300 uberlord 2547
301 uberlord 2577 dir = rc_strcatpaths (RC_SVCDIR, "daemons", base, (char *) NULL);
302     if (rc_is_dir (dir))
303     rc_rm_dir (dir, true);
304     free (dir);
305 uberlord 2569
306 uberlord 2577 rc_schedule_clear (service);
307     }
308 uberlord 2547
309 uberlord 2577 /* These are final states, so remove us from scheduled */
310     if (state == rc_service_started || state == rc_service_stopped) {
311     char *sdir = rc_strcatpaths (RC_SVCDIR, "scheduled", (char *) NULL);
312     char **dirs = rc_ls_dir (NULL, sdir, 0);
313     char *dir;
314     int serrno;
315 uberlord 2547
316 uberlord 2577 STRLIST_FOREACH (dirs, dir, i) {
317     char *bdir = rc_strcatpaths (sdir, dir, (char *) NULL);
318     file = rc_strcatpaths (bdir, base, (char *) NULL);
319     if (rc_exists (file))
320     if (unlink (file) != 0)
321     eerror ("unlink `%s': %s", file, strerror (errno));
322     free (file);
323 uberlord 2547
324 uberlord 2577 /* Try and remove the dir - we don't care about errors */
325     serrno = errno;
326     rmdir (bdir);
327     errno = serrno;
328     free (bdir);
329     }
330     rc_strlist_free (dirs);
331     free (sdir);
332     }
333 uberlord 2547
334 uberlord 2596 free (svc);
335 uberlord 2577 free (init);
336     return (true);
337 uberlord 2547 }
338 vapier 2597 librc_hidden_def(rc_mark_service)
339 uberlord 2547
340     bool rc_service_state (const char *service, const rc_service_state_t state)
341     {
342 uberlord 2577 char *file;
343     bool retval;
344 uberlord 2596 char *svc;
345 uberlord 2547
346 uberlord 2577 /* If the init script does not exist then we are stopped */
347     if (! rc_service_exists (service))
348     return (state == rc_service_stopped ? true : false);
349 uberlord 2547
350 uberlord 2577 /* We check stopped state by not being in any of the others */
351     if (state == rc_service_stopped)
352     return ( ! (rc_service_state (service, rc_service_started) ||
353     rc_service_state (service, rc_service_starting) ||
354     rc_service_state (service, rc_service_stopping) ||
355     rc_service_state (service, rc_service_inactive)));
356 uberlord 2547
357 uberlord 2577 /* The crashed state and scheduled states are virtual */
358     if (state == rc_service_crashed)
359     return (rc_service_daemons_crashed (service));
360     else if (state == rc_service_scheduled) {
361     char **services = rc_services_scheduled_by (service);
362     retval = (services);
363     if (services)
364     free (services);
365     return (retval);
366     }
367 uberlord 2547
368 uberlord 2577 /* Now we just check if a file by the service name rc_exists
369     in the state dir */
370 uberlord 2596 svc = rc_xstrdup (service);
371 uberlord 2577 file = rc_strcatpaths (RC_SVCDIR, rc_service_state_names[state],
372 uberlord 2596 basename (svc), (char*) NULL);
373     free (svc);
374 uberlord 2577 retval = rc_exists (file);
375     free (file);
376     return (retval);
377 uberlord 2547 }
378 vapier 2597 librc_hidden_def(rc_service_state)
379 uberlord 2547
380     bool rc_get_service_option (const char *service, const char *option,
381 uberlord 2577 char *value)
382 uberlord 2547 {
383 uberlord 2577 FILE *fp;
384     char buffer[RC_LINEBUFFER];
385     char *file = rc_strcatpaths (RC_SVCDIR, "options", service, option,
386     (char *) NULL);
387     bool retval = false;
388 uberlord 2547
389 uberlord 2577 if (rc_exists (file)) {
390     if ((fp = fopen (file, "r")) == NULL)
391     eerror ("fopen `%s': %s", file, strerror (errno));
392     else {
393     memset (buffer, 0, sizeof (buffer));
394     while (fgets (buffer, RC_LINEBUFFER, fp)) {
395     memcpy (value, buffer, strlen (buffer));
396     value += strlen (buffer);
397     }
398     fclose (fp);
399     retval = true;
400     }
401     }
402 uberlord 2547
403 uberlord 2577 free (file);
404     return (retval);
405 uberlord 2547 }
406 vapier 2597 librc_hidden_def(rc_get_service_option)
407 uberlord 2547
408     bool rc_set_service_option (const char *service, const char *option,
409 uberlord 2577 const char *value)
410 uberlord 2547 {
411 uberlord 2577 FILE *fp;
412     char *path = rc_strcatpaths (RC_SVCDIR, "options", service, (char *) NULL);
413     char *file = rc_strcatpaths (path, option, (char *) NULL);
414     bool retval = false;
415 uberlord 2547
416 uberlord 2577 if (! rc_is_dir (path)) {
417     if (mkdir (path, 0755) != 0) {
418     eerror ("mkdir `%s': %s", path, strerror (errno));
419     free (path);
420     free (file);
421     return (false);
422     }
423     }
424 uberlord 2547
425 uberlord 2577 if ((fp = fopen (file, "w")) == NULL)
426     eerror ("fopen `%s': %s", file, strerror (errno));
427     else {
428     if (value)
429     fprintf (fp, "%s", value);
430     fclose (fp);
431     retval = true;
432     }
433 uberlord 2547
434 uberlord 2577 free (path);
435     free (file);
436     return (retval);
437 uberlord 2547 }
438 vapier 2597 librc_hidden_def(rc_set_service_option)
439 uberlord 2547
440     static pid_t _exec_service (const char *service, const char *arg)
441     {
442 uberlord 2577 char *file;
443     char *fifo;
444     pid_t pid = -1;
445     pid_t savedpid;
446     int status;
447 uberlord 2596 char *svc;
448 uberlord 2547
449 uberlord 2577 file = rc_resolve_service (service);
450     if (! rc_is_file (file)) {
451     rc_mark_service (service, rc_service_stopped);
452     free (file);
453     return (0);
454     }
455 uberlord 2547
456 uberlord 2577 /* We create a fifo so that other services can wait until we complete */
457 uberlord 2596 svc = rc_xstrdup (service);
458     fifo = rc_strcatpaths (RC_SVCDIR, "exclusive", basename (svc),
459 uberlord 2577 (char *) NULL);
460 uberlord 2596 free (svc);
461 uberlord 2547
462 uberlord 2577 if (mkfifo (fifo, 0600) != 0 && errno != EEXIST) {
463     eerror ("unable to create fifo `%s': %s", fifo, strerror (errno));
464     free (fifo);
465     free (file);
466     return (-1);
467     }
468 uberlord 2547
469 uberlord 2577 if ((pid = fork ()) == 0) {
470 uberlord 2634 char *myarg = rc_xstrdup (arg);
471 uberlord 2577 int e = 0;
472     execl (file, file, myarg, (char *) NULL);
473     e = errno;
474     free (myarg);
475     unlink (fifo);
476     free (fifo);
477     eerrorx ("unable to exec `%s': %s", file, strerror (errno));
478     }
479 uberlord 2547
480 uberlord 2577 free (fifo);
481     free (file);
482 uberlord 2547
483 uberlord 2577 if (pid == -1) {
484     eerror ("unable to fork: %s", strerror (errno));
485     return (pid);
486     }
487 uberlord 2547
488 uberlord 2577 if (rc_is_env ("RC_PARALLEL_STARTUP", "yes"))
489     return (pid);
490 uberlord 2547
491 uberlord 2577 savedpid = pid;
492     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 2547
502 uberlord 2577 return (0);
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