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

Diff of /trunk/src/rc.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

Revision 2957 Revision 3040
18#include <sys/types.h> 18#include <sys/types.h>
19#include <sys/stat.h> 19#include <sys/stat.h>
20#include <sys/utsname.h> 20#include <sys/utsname.h>
21#include <sys/wait.h> 21#include <sys/wait.h>
22#include <errno.h> 22#include <errno.h>
23#include <dirent.h>
23#include <ctype.h> 24#include <ctype.h>
24#include <getopt.h> 25#include <getopt.h>
25#include <libgen.h> 26#include <libgen.h>
26#include <limits.h> 27#include <limits.h>
27#include <stdbool.h> 28#include <stdbool.h>
28#include <stdio.h> 29#include <stdio.h>
29#include <stdlib.h> 30#include <stdlib.h>
30#include <signal.h> 31#include <signal.h>
31#include <string.h> 32#include <string.h>
33#include <strings.h>
32#include <syslog.h> 34#include <syslog.h>
33#include <termios.h> 35#include <termios.h>
34#include <unistd.h> 36#include <unistd.h>
35 37
36#include "builtins.h" 38#include "builtins.h"
61 63
62static char *RUNLEVEL = NULL; 64static char *RUNLEVEL = NULL;
63static char *PREVLEVEL = NULL; 65static char *PREVLEVEL = NULL;
64 66
65static char *applet = NULL; 67static char *applet = NULL;
68static char *runlevel = NULL;
66static char **env = NULL; 69static char **env = NULL;
67static char **newenv = NULL; 70static char **newenv = NULL;
68static char **coldplugged_services = NULL; 71static char **coldplugged_services = NULL;
69static char **stop_services = NULL; 72static char **stop_services = NULL;
70static char **start_services = NULL; 73static char **start_services = NULL;
71static rc_depinfo_t *deptree = NULL; 74static rc_depinfo_t *deptree = NULL;
72static char **types = NULL;
73static char *tmp = NULL; 75static char *tmp = NULL;
74 76
75struct termios *termios_orig = NULL; 77struct termios *termios_orig = NULL;
76 78
77typedef struct pidlist 79typedef struct pidlist
78{ 80{
79 pid_t pid; 81 pid_t pid;
80 struct pidlist *next; 82 struct pidlist *next;
81} pidlist_t; 83} pidlist_t;
82static pidlist_t *service_pids = NULL; 84static pidlist_t *service_pids = NULL;
85
86static const char *types_n[] = { "needsme", NULL };
87static const char *types_nua[] = { "ineed", "iuse", "iafter", NULL };
83 88
84static void cleanup (void) 89static void cleanup (void)
85{ 90{
86 if (applet && strcmp (applet, "rc") == 0) { 91 if (applet && strcmp (applet, "rc") == 0) {
87 pidlist_t *pl = service_pids; 92 pidlist_t *pl = service_pids;
103 rc_strlist_free (newenv); 108 rc_strlist_free (newenv);
104 rc_strlist_free (coldplugged_services); 109 rc_strlist_free (coldplugged_services);
105 rc_strlist_free (stop_services); 110 rc_strlist_free (stop_services);
106 rc_strlist_free (start_services); 111 rc_strlist_free (start_services);
107 rc_deptree_free (deptree); 112 rc_deptree_free (deptree);
108 rc_strlist_free (types);
109 113
110 /* Clean runlevel start, stop markers */ 114 /* Clean runlevel start, stop markers */
111 if (! rc_in_plugin) { 115 if (! rc_in_plugin) {
112 if (rc_is_dir (RC_STARTING))
113 rc_rm_dir (RC_STARTING, true); 116 rmdir (RC_STARTING);
114 if (rc_is_dir (RC_STOPPING))
115 rc_rm_dir (RC_STOPPING, true); 117 rmdir (RC_STOPPING);
116 } 118 }
119
120 free (runlevel);
117 } 121 }
118 122
119 free (applet); 123 free (applet);
120} 124}
121 125
188 192
189 if (argc > 0) { 193 if (argc > 0) {
190 for (i = 0; i < argc; i++) 194 for (i = 0; i < argc; i++)
191 l += strlen (argv[i]) + 1; 195 l += strlen (argv[i]) + 1;
192 196
193 message = rc_xmalloc (l); 197 message = xmalloc (l);
194 p = message; 198 p = message;
195 199
196 for (i = 0; i < argc; i++) { 200 for (i = 0; i < argc; i++) {
197 if (i > 0) 201 if (i > 0)
198 *p++ = ' '; 202 *p++ = ' ';
201 } 205 }
202 *p = 0; 206 *p = 0;
203 } 207 }
204 208
205 if (message) 209 if (message)
206 fmt = rc_xstrdup ("%s"); 210 fmt = xstrdup ("%s");
207 211
208 if (strcmp (applet, "einfo") == 0) 212 if (strcmp (applet, "einfo") == 0)
209 einfo (fmt, message); 213 einfo (fmt, message);
210 else if (strcmp (applet, "einfon") == 0) 214 else if (strcmp (applet, "einfon") == 0)
211 einfon (fmt, message); 215 einfon (fmt, message);
301 305
302 if (argc < 1 || ! argv[0] || strlen (argv[0]) == 0) 306 if (argc < 1 || ! argv[0] || strlen (argv[0]) == 0)
303 eerrorx ("%s: no service specified", applet); 307 eerrorx ("%s: no service specified", applet);
304 308
305 if (strcmp (applet, "mark_service_started") == 0) 309 if (strcmp (applet, "mark_service_started") == 0)
306 ok = rc_mark_service (argv[0], RC_SERVICE_STARTED); 310 ok = rc_service_mark (argv[0], RC_SERVICE_STARTED);
307 else if (strcmp (applet, "mark_service_stopped") == 0) 311 else if (strcmp (applet, "mark_service_stopped") == 0)
308 ok = rc_mark_service (argv[0], RC_SERVICE_STOPPED); 312 ok = rc_service_mark (argv[0], RC_SERVICE_STOPPED);
309 else if (strcmp (applet, "mark_service_inactive") == 0) 313 else if (strcmp (applet, "mark_service_inactive") == 0)
310 ok = rc_mark_service (argv[0], RC_SERVICE_INACTIVE); 314 ok = rc_service_mark (argv[0], RC_SERVICE_INACTIVE);
311 else if (strcmp (applet, "mark_service_starting") == 0) 315 else if (strcmp (applet, "mark_service_starting") == 0)
312 ok = rc_mark_service (argv[0], RC_SERVICE_STOPPING); 316 ok = rc_service_mark (argv[0], RC_SERVICE_STOPPING);
313 else if (strcmp (applet, "mark_service_stopping") == 0) 317 else if (strcmp (applet, "mark_service_stopping") == 0)
314 ok = rc_mark_service (argv[0], RC_SERVICE_STOPPING); 318 ok = rc_service_mark (argv[0], RC_SERVICE_STOPPING);
315 else if (strcmp (applet, "mark_service_coldplugged") == 0) 319 else if (strcmp (applet, "mark_service_coldplugged") == 0)
316 ok = rc_mark_service (argv[0], RC_SERVICE_COLDPLUGGED); 320 ok = rc_service_mark (argv[0], RC_SERVICE_COLDPLUGGED);
321 else if (strcmp (applet, "mark_service_failed") == 0)
322 ok = rc_service_mark (argv[0], RC_SERVICE_FAILED);
317 else 323 else
318 eerrorx ("%s: unknown applet", applet); 324 eerrorx ("%s: unknown applet", applet);
319 325
320 /* If we're marking ourselves then we need to inform our parent runscript 326 /* If we're marking ourselves then we need to inform our parent runscript
321 process so they do not mark us based on our exit code */ 327 process so they do not mark us based on our exit code */
328 if (runscript_pid && sscanf (runscript_pid, "%d", &pid) == 1) 334 if (runscript_pid && sscanf (runscript_pid, "%d", &pid) == 1)
329 if (kill (pid, SIGHUP) != 0) 335 if (kill (pid, SIGHUP) != 0)
330 eerror ("%s: failed to signal parent %d: %s", 336 eerror ("%s: failed to signal parent %d: %s",
331 applet, pid, strerror (errno)); 337 applet, pid, strerror (errno));
332 338
333 /* Remove the exclsive time test. This ensures that it's not 339 /* Remove the exclusive time test. This ensures that it's not
334 in control as well */ 340 in control as well */
335 l = strlen (RC_SVCDIR "exclusive") + 341 l = strlen (RC_SVCDIR "exclusive") +
336 strlen (svcname) + 342 strlen (svcname) +
337 strlen (runscript_pid) + 343 strlen (runscript_pid) +
338 4; 344 4;
339 mtime = rc_xmalloc (l); 345 mtime = xmalloc (l);
340 snprintf (mtime, l, RC_SVCDIR "exclusive/%s.%s", 346 snprintf (mtime, l, RC_SVCDIR "exclusive/%s.%s",
341 svcname, runscript_pid); 347 svcname, runscript_pid);
342 if (rc_exists (mtime) && unlink (mtime) != 0) 348 if (exists (mtime) && unlink (mtime) != 0)
343 eerror ("%s: unlink: %s", applet, strerror (errno)); 349 eerror ("%s: unlink: %s", applet, strerror (errno));
344 free (mtime); 350 free (mtime);
345 } 351 }
346 352
347 return (ok ? EXIT_SUCCESS : EXIT_FAILURE); 353 return (ok ? EXIT_SUCCESS : EXIT_FAILURE);
357 363
358 if (argc < 1 || ! argv[0] || strlen (argv[0]) == 0) 364 if (argc < 1 || ! argv[0] || strlen (argv[0]) == 0)
359 eerrorx ("%s: no option specified", applet); 365 eerrorx ("%s: no option specified", applet);
360 366
361 if (strcmp (applet, "get_options") == 0) { 367 if (strcmp (applet, "get_options") == 0) {
362 char *option = rc_get_service_option (service, argv[0]); 368 char *option = rc_service_value_get (service, argv[0]);
363 if (option) { 369 if (option) {
364 printf ("%s", option); 370 printf ("%s", option);
365 free (option); 371 free (option);
366 ok = true; 372 ok = true;
367 } 373 }
368 } else if (strcmp (applet, "save_options") == 0) 374 } else if (strcmp (applet, "save_options") == 0)
369 ok = rc_set_service_option (service, argv[0], argv[1]); 375 ok = rc_service_value_set (service, argv[0], argv[1]);
370 else 376 else
371 eerrorx ("%s: unknown applet", applet); 377 eerrorx ("%s: unknown applet", applet);
372 378
373 return (ok ? EXIT_SUCCESS : EXIT_FAILURE); 379 return (ok ? EXIT_SUCCESS : EXIT_FAILURE);
374} 380}
375 381
376#ifdef __linux__ 382#ifdef __linux__
377static char *proc_getent (const char *ent) 383static char *proc_getent (const char *ent)
378{ 384{
379 FILE *fp; 385 FILE *fp;
380 char buffer[RC_LINEBUFFER]; 386 char *buffer;
381 char *p; 387 char *p;
382 char *value = NULL; 388 char *value = NULL;
383 int i; 389 int i;
384 390
385 if (! rc_exists ("/proc/cmdline")) 391 if (! exists ("/proc/cmdline"))
386 return (NULL); 392 return (NULL);
387 393
388 if (! (fp = fopen ("/proc/cmdline", "r"))) { 394 if (! (fp = fopen ("/proc/cmdline", "r"))) {
389 eerror ("failed to open `/proc/cmdline': %s", strerror (errno)); 395 eerror ("failed to open `/proc/cmdline': %s", strerror (errno));
390 return (NULL); 396 return (NULL);
391 } 397 }
392 398
393 memset (buffer, 0, sizeof (buffer)); 399 buffer = xmalloc (sizeof (char) * RC_LINEBUFFER);
400 memset (buffer, 0, RC_LINEBUFFER);
394 if (fgets (buffer, RC_LINEBUFFER, fp) && 401 if (fgets (buffer, RC_LINEBUFFER, fp) &&
395 (p = strstr (buffer, ent))) 402 (p = strstr (buffer, ent)))
396 { 403 {
397 i = p - buffer; 404 i = p - buffer;
398 if (i == '\0' || buffer[i - 1] == ' ') { 405 if (i == '\0' || buffer[i - 1] == ' ') {
402 buffer[i] = 0; 409 buffer[i] = 0;
403 410
404 p += strlen (ent); 411 p += strlen (ent);
405 if (*p == '=') 412 if (*p == '=')
406 p++; 413 p++;
407 value = strdup (strsep (&p, " ")); 414 value = xstrdup (strsep (&p, " "));
408 } 415 }
409 } else 416 } else
410 errno = ENOENT; 417 errno = ENOENT;
418 free (buffer);
411 fclose (fp); 419 fclose (fp);
412 420
413 return (value); 421 return (value);
414} 422}
415#endif 423#endif
417static char read_key (bool block) 425static char read_key (bool block)
418{ 426{
419 struct termios termios; 427 struct termios termios;
420 char c = 0; 428 char c = 0;
421 int fd = fileno (stdin); 429 int fd = fileno (stdin);
422 430
423 if (! isatty (fd)) 431 if (! isatty (fd))
424 return (false); 432 return (false);
425 433
426 /* Now save our terminal settings. We need to restore them at exit as we 434 /* Now save our terminal settings. We need to restore them at exit as we
427 will be changing it for non-blocking reads for Interactive */ 435 will be changing it for non-blocking reads for Interactive */
428 if (! termios_orig) { 436 if (! termios_orig) {
429 termios_orig = rc_xmalloc (sizeof (struct termios)); 437 termios_orig = xmalloc (sizeof (struct termios));
430 tcgetattr (fd, termios_orig); 438 tcgetattr (fd, termios_orig);
431 } 439 }
432 440
433 tcgetattr (fd, &termios); 441 tcgetattr (fd, &termios);
434 termios.c_lflag &= ~(ICANON | ECHO); 442 termios.c_lflag &= ~(ICANON | ECHO);
481 execl ("/sbin/halt", "/sbin/halt", "-f", (char *) NULL); 489 execl ("/sbin/halt", "/sbin/halt", "-f", (char *) NULL);
482 eerrorx ("%s: unable to exec `/sbin/halt': %s", applet, strerror (errno)); 490 eerrorx ("%s: unable to exec `/sbin/halt': %s", applet, strerror (errno));
483 } 491 }
484#endif 492#endif
485 493
486 newenv = rc_filter_env (); 494 newenv = env_filter ();
487 495
488 if (cont) { 496 if (cont) {
489 int status = 0; 497 int status = 0;
490#ifdef __linux__ 498#ifdef __linux__
491 char *tty = ttyname (fileno (stdout)); 499 char *tty = ttyname (fileno (stdout));
534 applet, strerror (errno)); 542 applet, strerror (errno));
535 exit (EXIT_SUCCESS); 543 exit (EXIT_SUCCESS);
536#endif 544#endif
537} 545}
538 546
539static void set_ksoftlevel (const char *runlevel) 547static void set_ksoftlevel (const char *level)
540{ 548{
541 FILE *fp; 549 FILE *fp;
542 550
543 if (! runlevel || 551 if (! level ||
544 strcmp (runlevel, getenv ("RC_BOOTLEVEL")) == 0 || 552 strcmp (level, getenv ("RC_BOOTLEVEL")) == 0 ||
545 strcmp (runlevel, RC_LEVEL_SINGLE) == 0 || 553 strcmp (level, RC_LEVEL_SINGLE) == 0 ||
546 strcmp (runlevel, RC_LEVEL_SYSINIT) == 0) 554 strcmp (level, RC_LEVEL_SYSINIT) == 0)
547 { 555 {
548 if (rc_exists (RC_KSOFTLEVEL) && 556 if (exists (RC_KSOFTLEVEL) &&
549 unlink (RC_KSOFTLEVEL) != 0) 557 unlink (RC_KSOFTLEVEL) != 0)
550 eerror ("unlink `%s': %s", RC_KSOFTLEVEL, strerror (errno)); 558 eerror ("unlink `%s': %s", RC_KSOFTLEVEL, strerror (errno));
551 return; 559 return;
552 } 560 }
553 561
554 if (! (fp = fopen (RC_KSOFTLEVEL, "w"))) { 562 if (! (fp = fopen (RC_KSOFTLEVEL, "w"))) {
555 eerror ("fopen `%s': %s", RC_KSOFTLEVEL, strerror (errno)); 563 eerror ("fopen `%s': %s", RC_KSOFTLEVEL, strerror (errno));
556 return; 564 return;
557 } 565 }
558 566
559 fprintf (fp, "%s", runlevel); 567 fprintf (fp, "%s", level);
560 fclose (fp); 568 fclose (fp);
561} 569}
562 570
563static int get_ksoftlevel (char *buffer, int buffer_len) 571static int get_ksoftlevel (char *buffer, int buffer_len)
564{ 572{
565 FILE *fp; 573 FILE *fp;
566 int i = 0; 574 int i = 0;
567 575
568 if (! rc_exists (RC_KSOFTLEVEL)) 576 if (! exists (RC_KSOFTLEVEL))
569 return (0); 577 return (0);
570 578
571 if (! (fp = fopen (RC_KSOFTLEVEL, "r"))) { 579 if (! (fp = fopen (RC_KSOFTLEVEL, "r"))) {
572 eerror ("fopen `%s': %s", RC_KSOFTLEVEL, strerror (errno)); 580 eerror ("fopen `%s': %s", RC_KSOFTLEVEL, strerror (errno));
573 return (-1); 581 return (-1);
593{ 601{
594 pidlist_t *sp = service_pids; 602 pidlist_t *sp = service_pids;
595 if (sp) { 603 if (sp) {
596 while (sp->next) 604 while (sp->next)
597 sp = sp->next; 605 sp = sp->next;
598 sp->next = rc_xmalloc (sizeof (pidlist_t)); 606 sp->next = xmalloc (sizeof (pidlist_t));
599 sp = sp->next; 607 sp = sp->next;
600 } else 608 } else
601 sp = service_pids = rc_xmalloc (sizeof (pidlist_t)); 609 sp = service_pids = xmalloc (sizeof (pidlist_t));
602 memset (sp, 0, sizeof (pidlist_t)); 610 memset (sp, 0, sizeof (pidlist_t));
603 sp->pid = pid; 611 sp->pid = pid;
604} 612}
605 613
606static void remove_pid (pid_t pid) 614static void remove_pid (pid_t pid)
617 free (pl); 625 free (pl);
618 break; 626 break;
619 } 627 }
620 last = pl; 628 last = pl;
621 } 629 }
630}
631
632static int wait_pid (pid_t pid)
633{
634 int status = 0;
635 pid_t savedpid = pid;
636 int retval = -1;
637
638 errno = 0;
639 while ((pid = waitpid (savedpid, &status, 0)) > 0) {
640 if (pid == savedpid)
641 retval = WIFEXITED (status) ? WEXITSTATUS (status) : EXIT_FAILURE;
642 }
643
644 return (retval);
622} 645}
623 646
624static void handle_signal (int sig) 647static void handle_signal (int sig)
625{ 648{
626 int serrno = errno; 649 int serrno = errno;
711 734
712#include "_usage.h" 735#include "_usage.h"
713#define getoptstring getoptstring_COMMON 736#define getoptstring getoptstring_COMMON
714static struct option longopts[] = { 737static struct option longopts[] = {
715 longopts_COMMON 738 longopts_COMMON
716 { NULL, 0, NULL, 0}
717}; 739};
718static const char * const longopts_help[] = { 740static const char * const longopts_help[] = {
719 longopts_help_COMMON 741 longopts_help_COMMON
720}; 742};
721#include "_usage.c" 743#include "_usage.c"
722 744
723int main (int argc, char **argv) 745int main (int argc, char **argv)
724{ 746{
725 char *runlevel = NULL;
726 const char *bootlevel = NULL; 747 const char *bootlevel = NULL;
727 char *newlevel = NULL; 748 char *newlevel = NULL;
728 char *service = NULL; 749 char *service = NULL;
729 char **deporder = NULL; 750 char **deporder = NULL;
730 char **tmplist; 751 char **tmplist;
734 bool interactive = false; 755 bool interactive = false;
735 int depoptions = RC_DEP_STRICT | RC_DEP_TRACE; 756 int depoptions = RC_DEP_STRICT | RC_DEP_TRACE;
736 char ksoftbuffer [PATH_MAX]; 757 char ksoftbuffer [PATH_MAX];
737 char pidstr[6]; 758 char pidstr[6];
738 int opt; 759 int opt;
760 DIR *dp;
761 struct dirent *d;
739 762
740 atexit (cleanup); 763 atexit (cleanup);
741 if (argv[0]) 764 if (argv[0])
742 applet = rc_xstrdup (basename (argv[0])); 765 applet = xstrdup (basename (argv[0]));
743 766
744 if (! applet) 767 if (! applet)
745 eerrorx ("arguments required"); 768 eerrorx ("arguments required");
746 769
747 /* These used to be programs in their own right, so we shouldn't 770 /* These used to be programs in their own right, so we shouldn't
819 signal (SIGTERM, handle_signal); 842 signal (SIGTERM, handle_signal);
820 signal (SIGUSR1, handle_signal); 843 signal (SIGUSR1, handle_signal);
821 844
822 /* Ensure our environment is pure 845 /* Ensure our environment is pure
823 Also, add our configuration to it */ 846 Also, add our configuration to it */
824 env = rc_filter_env (); 847 env = env_filter ();
825 tmplist = rc_make_env (); 848 tmplist = env_config ();
826 rc_strlist_join (&env, tmplist); 849 rc_strlist_join (&env, tmplist);
827 rc_strlist_free (tmplist); 850 rc_strlist_free (tmplist);
828 851
829 if (env) { 852 if (env) {
830 char *p; 853 char *p;
838 /* No clearenv present here then. 861 /* No clearenv present here then.
839 We could manipulate environ directly ourselves, but it seems that 862 We could manipulate environ directly ourselves, but it seems that
840 some kernels bitch about this according to the environ man pages 863 some kernels bitch about this according to the environ man pages
841 so we walk though environ and call unsetenv for each value. */ 864 so we walk though environ and call unsetenv for each value. */
842 while (environ[0]) { 865 while (environ[0]) {
843 tmp = rc_xstrdup (environ[0]); 866 tmp = xstrdup (environ[0]);
844 p = tmp; 867 p = tmp;
845 var = strsep (&p, "="); 868 var = strsep (&p, "=");
846 unsetenv (var); 869 unsetenv (var);
847 free (tmp); 870 free (tmp);
848 } 871 }
878 901
879 /* Export our PID */ 902 /* Export our PID */
880 snprintf (pidstr, sizeof (pidstr), "%d", getpid ()); 903 snprintf (pidstr, sizeof (pidstr), "%d", getpid ());
881 setenv ("RC_PID", pidstr, 1); 904 setenv ("RC_PID", pidstr, 1);
882 905
883 interactive = rc_exists (INTERACTIVE); 906 interactive = exists (INTERACTIVE);
884 rc_plugin_load (); 907 rc_plugin_load ();
885 908
886 /* Load current softlevel */ 909 /* Load current softlevel */
887 bootlevel = getenv ("RC_BOOTLEVEL"); 910 bootlevel = getenv ("RC_BOOTLEVEL");
888 runlevel = rc_get_runlevel (); 911 runlevel = rc_runlevel_get ();
889 912
890 /* Check we're in the runlevel requested, ie from 913 /* Check we're in the runlevel requested, ie from
891 rc single 914 rc single
892 rc shutdown 915 rc shutdown
893 rc reboot 916 rc reboot
905#endif 928#endif
906 929
907 /* exec init-early.sh if it exists 930 /* exec init-early.sh if it exists
908 * This should just setup the console to use the correct 931 * This should just setup the console to use the correct
909 * font. Maybe it should setup the keyboard too? */ 932 * font. Maybe it should setup the keyboard too? */
910 if (rc_exists (INITEARLYSH)) 933 if (exists (INITEARLYSH))
911 run_script (INITEARLYSH); 934 run_script (INITEARLYSH);
912 935
913 uname (&uts); 936 uname (&uts);
914 937
915 printf ("\n"); 938 printf ("\n");
1003 (strcmp (newlevel, RC_LEVEL_REBOOT) == 0 || 1026 (strcmp (newlevel, RC_LEVEL_REBOOT) == 0 ||
1004 strcmp (newlevel, RC_LEVEL_SHUTDOWN) == 0 || 1027 strcmp (newlevel, RC_LEVEL_SHUTDOWN) == 0 ||
1005 strcmp (newlevel, RC_LEVEL_SINGLE) == 0)) 1028 strcmp (newlevel, RC_LEVEL_SINGLE) == 0))
1006 { 1029 {
1007 going_down = true; 1030 going_down = true;
1008 rc_set_runlevel (newlevel); 1031 rc_runlevel_set (newlevel);
1009 setenv ("RC_SOFTLEVEL", newlevel, 1); 1032 setenv ("RC_SOFTLEVEL", newlevel, 1);
1010 rc_plugin_run (RC_HOOK_RUNLEVEL_STOP_IN, newlevel); 1033 rc_plugin_run (RC_HOOK_RUNLEVEL_STOP_IN, newlevel);
1011 } else { 1034 } else {
1012 rc_plugin_run (RC_HOOK_RUNLEVEL_STOP_IN, runlevel); 1035 rc_plugin_run (RC_HOOK_RUNLEVEL_STOP_IN, runlevel);
1013 } 1036 }
1014 1037
1015 /* Check if runlevel is valid if we're changing */ 1038 /* Check if runlevel is valid if we're changing */
1016 if (newlevel && strcmp (runlevel, newlevel) != 0 && ! going_down) { 1039 if (newlevel && strcmp (runlevel, newlevel) != 0 && ! going_down) {
1017 tmp = rc_strcatpaths (RC_RUNLEVELDIR, newlevel, (char *) NULL); 1040 if (! rc_runlevel_exists (newlevel))
1018 if (! rc_is_dir (tmp))
1019 eerrorx ("%s: is not a valid runlevel", newlevel); 1041 eerrorx ("%s: is not a valid runlevel", newlevel);
1020 CHAR_FREE (tmp);
1021 } 1042 }
1022 1043
1023 /* Load our deptree now */ 1044 /* Load our deptree now */
1024 if ((deptree = _rc_deptree_load ()) == NULL) 1045 if ((deptree = _rc_deptree_load ()) == NULL)
1025 eerrorx ("failed to load deptree"); 1046 eerrorx ("failed to load deptree");
1026 1047
1027 /* Clean the failed services state dir now */ 1048 /* Clean the failed services state dir now */
1028 if (rc_is_dir (RC_SVCDIR "/failed")) 1049 if ((dp = opendir (RC_SVCDIR "/failed"))) {
1029 rc_rm_dir (RC_SVCDIR "/failed", false); 1050 while ((d = readdir (dp))) {
1051 if (d->d_name[0] == '.' &&
1052 (d->d_name[1] == '\0' ||
1053 (d->d_name[1] == '.' && d->d_name[2] == '\0')))
1054 continue;
1055
1056 asprintf (&tmp, RC_SVCDIR "/failed/%s", d->d_name);
1057 if (tmp) {
1058 if (unlink (tmp))
1059 eerror ("%s: unlink `%s': %s", applet, tmp,
1060 strerror (errno));
1061 free (tmp);
1062 }
1063 }
1064 closedir (dp);
1065 }
1030 1066
1031 mkdir (RC_STOPPING, 0755); 1067 mkdir (RC_STOPPING, 0755);
1032 1068
1033#ifdef __linux__ 1069#ifdef __linux__
1034 /* udev likes to start services before we're ready when it does 1070 /* udev likes to start services before we're ready when it does
1035 its coldplugging thing. runscript knows when we're not ready so it 1071 its coldplugging thing. runscript knows when we're not ready so it
1036 stores a list of coldplugged services in DEVBOOT for us to pick up 1072 stores a list of coldplugged services in DEVBOOT for us to pick up
1037 here when we are ready for them */ 1073 here when we are ready for them */
1038 if (rc_is_dir (DEVBOOT)) { 1074 if ((dp = opendir (DEVBOOT))) {
1039 start_services = rc_ls_dir (DEVBOOT, RC_LS_INITD); 1075 while ((d = readdir (dp))) {
1076 if (d->d_name[0] == '.' &&
1077 (d->d_name[1] == '\0' ||
1078 (d->d_name[1] == '.' && d->d_name[2] == '\0')))
1079 continue;
1080
1081 if (rc_service_exists (d->d_name) &&
1082 rc_service_plugable (d->d_name))
1083 rc_service_mark (d->d_name, RC_SERVICE_COLDPLUGGED);
1084
1085 asprintf (&tmp, DEVBOOT "/%s", d->d_name);
1086 if (tmp) {
1087 if (unlink (tmp))
1088 eerror ("%s: unlink `%s': %s", applet, tmp,
1089 strerror (errno));
1090 free (tmp);
1091 }
1092 }
1093 closedir (dp);
1040 rc_rm_dir (DEVBOOT, true); 1094 rmdir (DEVBOOT);
1041
1042 STRLIST_FOREACH (start_services, service, i)
1043 if (rc_allow_plug (service))
1044 rc_mark_service (service, RC_SERVICE_COLDPLUGGED);
1045 /* We need to dump this list now.
1046 This may seem redunant, but only Linux needs this and saves on
1047 code bloat. */
1048 rc_strlist_free (start_services);
1049 start_services = NULL;
1050 } 1095 }
1051#else 1096#else
1052 /* BSD's on the other hand populate /dev automagically and use devd. 1097 /* BSD's on the other hand populate /dev automagically and use devd.
1053 The only downside of this approach and ours is that we have to hard code 1098 The only downside of this approach and ours is that we have to hard code
1054 the device node to the init script to simulate the coldplug into 1099 the device node to the init script to simulate the coldplug into
1058 strcmp (runlevel, RC_LEVEL_SYSINIT) == 0) && 1103 strcmp (runlevel, RC_LEVEL_SYSINIT) == 0) &&
1059 rc_env_bool ("RC_COLDPLUG")) 1104 rc_env_bool ("RC_COLDPLUG"))
1060 { 1105 {
1061#if defined(__DragonFly__) || defined(__FreeBSD__) 1106#if defined(__DragonFly__) || defined(__FreeBSD__)
1062 /* The net interfaces are easy - they're all in net /dev/net :) */ 1107 /* The net interfaces are easy - they're all in net /dev/net :) */
1063 start_services = rc_ls_dir ("/dev/net", 0); 1108 if ((dp = opendir ("/dev/net"))) {
1064 STRLIST_FOREACH (start_services, service, i) { 1109 while ((d = readdir (dp))) {
1065 j = (strlen ("net.") + strlen (service) + 1); 1110 i = (strlen ("net.") + strlen (d->d_name) + 1);
1066 tmp = rc_xmalloc (sizeof (char *) * j); 1111 tmp = xmalloc (sizeof (char) * i);
1067 snprintf (tmp, j, "net.%s", service); 1112 snprintf (tmp, i, "net.%s", d->d_name);
1068 if (rc_service_exists (tmp) && rc_allow_plug (tmp)) 1113 if (rc_service_exists (tmp) &&
1114 rc_service_plugable (tmp))
1069 rc_mark_service (tmp, RC_SERVICE_COLDPLUGGED); 1115 rc_service_mark (tmp, RC_SERVICE_COLDPLUGGED);
1070 CHAR_FREE (tmp); 1116 CHAR_FREE (tmp);
1071 } 1117 }
1072 rc_strlist_free (start_services); 1118 closedir (dp);
1119 }
1073#endif 1120#endif
1074 1121
1075 /* The mice are a little more tricky. 1122 /* The mice are a little more tricky.
1076 If we coldplug anything else, we'll probably do it here. */ 1123 If we coldplug anything else, we'll probably do it here. */
1077 start_services = rc_ls_dir ("/dev", 0); 1124 if ((dp == opendir ("/dev"))) {
1078 STRLIST_FOREACH (start_services, service, i) { 1125 while ((d = readdir (dp))) {
1079 if (strncmp (service, "psm", 3) == 0 || 1126 if (strncmp (d->d_name, "psm", 3) == 0 ||
1080 strncmp (service, "ums", 3) == 0) 1127 strncmp (d->d_name, "ums", 3) == 0)
1081 { 1128 {
1082 char *p = service + 3; 1129 char *p = d->d_name + 3;
1083 if (p && isdigit (*p)) { 1130 if (p && isdigit (*p)) {
1084 j = (strlen ("moused.") + strlen (service) + 1); 1131 i = (strlen ("moused.") + strlen (d->d_name) + 1);
1085 tmp = rc_xmalloc (sizeof (char *) * j); 1132 tmp = xmalloc (sizeof (char) * i);
1086 snprintf (tmp, j, "moused.%s", service); 1133 snprintf (tmp, i, "moused.%s", d->d_name);
1087 if (rc_service_exists (tmp) && rc_allow_plug (tmp)) 1134 if (rc_service_exists (tmp) && rc_service_plugable (tmp))
1088 rc_mark_service (tmp, RC_SERVICE_COLDPLUGGED); 1135 rc_service_mark (tmp, RC_SERVICE_COLDPLUGGED);
1089 CHAR_FREE (tmp); 1136 CHAR_FREE (tmp);
1137 }
1090 } 1138 }
1091 } 1139 }
1140 closedir (dp);
1092 } 1141 }
1093 rc_strlist_free (start_services);
1094 start_services = NULL;
1095 } 1142 }
1096#endif 1143#endif
1097 1144
1098 /* Build a list of all services to stop and then work out the 1145 /* Build a list of all services to stop and then work out the
1099 correct order for stopping them */ 1146 correct order for stopping them */
1100 stop_services = rc_ls_dir (RC_SVCDIR_STARTING, RC_LS_INITD); 1147 stop_services = rc_services_in_state (RC_SERVICE_STARTING);
1101 1148
1102 tmplist = rc_ls_dir (RC_SVCDIR_INACTIVE, RC_LS_INITD); 1149 tmplist = rc_services_in_state (RC_SERVICE_INACTIVE);
1103 rc_strlist_join (&stop_services, tmplist); 1150 rc_strlist_join (&stop_services, tmplist);
1104 rc_strlist_free (tmplist); 1151 rc_strlist_free (tmplist);
1105 1152
1106 tmplist = rc_ls_dir (RC_SVCDIR_STARTED, RC_LS_INITD); 1153 tmplist = rc_services_in_state (RC_SERVICE_STARTED);
1107 rc_strlist_join (&stop_services, tmplist); 1154 rc_strlist_join (&stop_services, tmplist);
1108 rc_strlist_free (tmplist); 1155 rc_strlist_free (tmplist);
1109 1156
1110 types = NULL;
1111 rc_strlist_add (&types, "ineed");
1112 rc_strlist_add (&types, "iuse");
1113 rc_strlist_add (&types, "iafter");
1114
1115 deporder = rc_deptree_depends (deptree, types, stop_services, 1157 deporder = rc_deptree_depends (deptree, types_nua,
1158 (const char **) stop_services,
1116 runlevel, depoptions | RC_DEP_STOP); 1159 runlevel, depoptions | RC_DEP_STOP);
1117 1160
1118 rc_strlist_free (stop_services); 1161 rc_strlist_free (stop_services);
1119 rc_strlist_free (types);
1120 types = NULL;
1121 stop_services = deporder; 1162 stop_services = deporder;
1122 deporder = NULL; 1163 deporder = NULL;
1123 rc_strlist_reverse (stop_services); 1164 rc_strlist_reverse (stop_services);
1124 1165
1125 /* Load our list of coldplugged services */ 1166 /* Load our list of coldplugged services */
1126 coldplugged_services = rc_ls_dir (RC_SVCDIR_COLDPLUGGED, RC_LS_INITD); 1167 coldplugged_services = rc_services_in_state (RC_SERVICE_COLDPLUGGED);
1127 1168
1128 /* Load our start services now. 1169 /* Load our start services now.
1129 We have different rules dependent on runlevel. */ 1170 We have different rules dependent on runlevel. */
1130 if (newlevel && strcmp (newlevel, bootlevel) == 0) { 1171 if (newlevel && strcmp (newlevel, bootlevel) == 0) {
1131 if (coldplugged_services) { 1172 if (coldplugged_services) {
1134 printf (" %s", service); 1175 printf (" %s", service);
1135 rc_strlist_add (&start_services, service); 1176 rc_strlist_add (&start_services, service);
1136 } 1177 }
1137 printf ("\n"); 1178 printf ("\n");
1138 } 1179 }
1139 tmp = rc_strcatpaths (RC_RUNLEVELDIR, newlevel ? newlevel : runlevel, 1180 tmplist = rc_services_in_runlevel (newlevel ? newlevel : runlevel);
1140 (char *) NULL);
1141 tmplist = rc_ls_dir (tmp, RC_LS_INITD);
1142 rc_strlist_join (&start_services, tmplist); 1181 rc_strlist_join (&start_services, tmplist);
1143 rc_strlist_free (tmplist); 1182 rc_strlist_free (tmplist);
1144 CHAR_FREE (tmp);
1145 } else { 1183 } else {
1146 /* Store our list of coldplugged services */ 1184 /* Store our list of coldplugged services */
1147 tmplist = rc_ls_dir (RC_SVCDIR_COLDPLUGGED, RC_LS_INITD); 1185 tmplist = rc_services_in_state (RC_SERVICE_COLDPLUGGED);
1148 rc_strlist_join (&coldplugged_services, tmplist); 1186 rc_strlist_join (&coldplugged_services, tmplist);
1149 rc_strlist_free (tmplist); 1187 rc_strlist_free (tmplist);
1150 if (strcmp (newlevel ? newlevel : runlevel, RC_LEVEL_SINGLE) != 0 && 1188 if (strcmp (newlevel ? newlevel : runlevel, RC_LEVEL_SINGLE) != 0 &&
1151 strcmp (newlevel ? newlevel : runlevel, RC_LEVEL_SHUTDOWN) != 0 && 1189 strcmp (newlevel ? newlevel : runlevel, RC_LEVEL_SHUTDOWN) != 0 &&
1152 strcmp (newlevel ? newlevel : runlevel, RC_LEVEL_REBOOT) != 0) 1190 strcmp (newlevel ? newlevel : runlevel, RC_LEVEL_REBOOT) != 0)
1156 rc_strlist_join (&start_services, tmplist); 1194 rc_strlist_join (&start_services, tmplist);
1157 rc_strlist_free (tmplist); 1195 rc_strlist_free (tmplist);
1158 tmplist = rc_services_in_runlevel (newlevel ? newlevel : runlevel); 1196 tmplist = rc_services_in_runlevel (newlevel ? newlevel : runlevel);
1159 rc_strlist_join (&start_services, tmplist); 1197 rc_strlist_join (&start_services, tmplist);
1160 rc_strlist_free (tmplist); 1198 rc_strlist_free (tmplist);
1161 1199
1162 STRLIST_FOREACH (coldplugged_services, service, i) 1200 STRLIST_FOREACH (coldplugged_services, service, i)
1163 rc_strlist_add (&start_services, service); 1201 rc_strlist_add (&start_services, service);
1164 1202
1165 } 1203 }
1166 } 1204 }
1167 1205
1168 /* Save out softlevel now */ 1206 /* Save out softlevel now */
1169 if (going_down) 1207 if (going_down)
1170 rc_set_runlevel (newlevel); 1208 rc_runlevel_set (newlevel);
1171 1209
1172 types = NULL;
1173 rc_strlist_add (&types, "needsme");
1174 /* Now stop the services that shouldn't be running */ 1210 /* Now stop the services that shouldn't be running */
1175 STRLIST_FOREACH (stop_services, service, i) { 1211 STRLIST_FOREACH (stop_services, service, i) {
1176 bool found = false; 1212 bool found = false;
1177 char *conf = NULL; 1213 char *conf = NULL;
1178 char **stopdeps = NULL; 1214 char **stopdeps = NULL;
1183 if (rc_service_state (service) & RC_SERVICE_STOPPED) 1219 if (rc_service_state (service) & RC_SERVICE_STOPPED)
1184 continue; 1220 continue;
1185 1221
1186 /* We always stop the service when in these runlevels */ 1222 /* We always stop the service when in these runlevels */
1187 if (going_down) { 1223 if (going_down) {
1188 pid_t pid = rc_stop_service (service); 1224 pid_t pid = rc_service_stop (service);
1189 if (pid > 0 && ! rc_env_bool ("RC_PARALLEL")) 1225 if (pid > 0 && ! rc_env_bool ("RC_PARALLEL"))
1190 rc_waitpid (pid); 1226 wait_pid (pid);
1191 continue; 1227 continue;
1192 } 1228 }
1193 1229
1194 /* If we're in the start list then don't bother stopping us */ 1230 /* If we're in the start list then don't bother stopping us */
1195 STRLIST_FOREACH (start_services, svc1, j) 1231 STRLIST_FOREACH (start_services, svc1, j)
1203 int len; 1239 int len;
1204 if (! newlevel) 1240 if (! newlevel)
1205 continue; 1241 continue;
1206 1242
1207 len = strlen (service) + strlen (runlevel) + 2; 1243 len = strlen (service) + strlen (runlevel) + 2;
1208 tmp = rc_xmalloc (sizeof (char *) * len); 1244 tmp = xmalloc (sizeof (char) * len);
1209 snprintf (tmp, len, "%s.%s", service, runlevel); 1245 snprintf (tmp, len, "%s.%s", service, runlevel);
1210 conf = rc_strcatpaths (RC_CONFDIR, tmp, (char *) NULL); 1246 conf = rc_strcatpaths (RC_CONFDIR, tmp, (char *) NULL);
1211 found = rc_exists (conf); 1247 found = exists (conf);
1212 CHAR_FREE (conf); 1248 CHAR_FREE (conf);
1213 CHAR_FREE (tmp); 1249 CHAR_FREE (tmp);
1214 if (! found) { 1250 if (! found) {
1215 len = strlen (service) + strlen (newlevel) + 2; 1251 len = strlen (service) + strlen (newlevel) + 2;
1216 tmp = rc_xmalloc (sizeof (char *) * len); 1252 tmp = xmalloc (sizeof (char) * len);
1217 snprintf (tmp, len, "%s.%s", service, newlevel); 1253 snprintf (tmp, len, "%s.%s", service, newlevel);
1218 conf = rc_strcatpaths (RC_CONFDIR, tmp, (char *) NULL); 1254 conf = rc_strcatpaths (RC_CONFDIR, tmp, (char *) NULL);
1219 found = rc_exists (conf); 1255 found = exists (conf);
1220 CHAR_FREE (conf); 1256 CHAR_FREE (conf);
1221 CHAR_FREE (tmp); 1257 CHAR_FREE (tmp);
1222 if (!found) 1258 if (!found)
1223 continue; 1259 continue;
1224 } 1260 }
1229 } 1265 }
1230 1266
1231 /* We got this far! Or last check is to see if any any service that 1267 /* We got this far! Or last check is to see if any any service that
1232 going to be started depends on us */ 1268 going to be started depends on us */
1233 rc_strlist_add (&stopdeps, service); 1269 rc_strlist_add (&stopdeps, service);
1234 deporder = rc_deptree_depends (deptree, types, stopdeps, 1270 deporder = rc_deptree_depends (deptree, types_n,
1271 (const char **) stopdeps,
1235 runlevel, RC_DEP_STRICT); 1272 runlevel, RC_DEP_STRICT);
1236 rc_strlist_free (stopdeps); 1273 rc_strlist_free (stopdeps);
1237 stopdeps = NULL; 1274 stopdeps = NULL;
1238 found = false; 1275 found = false;
1239 STRLIST_FOREACH (deporder, svc1, j) { 1276 STRLIST_FOREACH (deporder, svc1, j) {
1240 STRLIST_FOREACH (start_services, svc2, k) 1277 STRLIST_FOREACH (start_services, svc2, k)
1248 rc_strlist_free (deporder); 1285 rc_strlist_free (deporder);
1249 deporder = NULL; 1286 deporder = NULL;
1250 1287
1251 /* After all that we can finally stop the blighter! */ 1288 /* After all that we can finally stop the blighter! */
1252 if (! found) { 1289 if (! found) {
1253 pid_t pid = rc_stop_service (service); 1290 pid_t pid = rc_service_stop (service);
1254 if (pid > 0 && ! rc_env_bool ("RC_PARALLEL")) 1291 if (pid > 0 && ! rc_env_bool ("RC_PARALLEL"))
1255 rc_waitpid (pid); 1292 wait_pid (pid);
1256 }
1257 } 1293 }
1258 rc_strlist_free (types); 1294 }
1259 types = NULL;
1260 1295
1261 /* Wait for our services to finish */ 1296 /* Wait for our services to finish */
1262 wait_for_services (); 1297 wait_for_services ();
1263 1298
1264 /* Notify the plugins we have finished */ 1299 /* Notify the plugins we have finished */
1266 1301
1267 rmdir (RC_STOPPING); 1302 rmdir (RC_STOPPING);
1268 1303
1269 /* Store the new runlevel */ 1304 /* Store the new runlevel */
1270 if (newlevel) { 1305 if (newlevel) {
1271 rc_set_runlevel (newlevel); 1306 rc_runlevel_set (newlevel);
1307 free (runlevel);
1272 runlevel = newlevel; 1308 runlevel = xstrdup (newlevel);
1273 setenv ("RC_SOFTLEVEL", runlevel, 1); 1309 setenv ("RC_SOFTLEVEL", runlevel, 1);
1274 } 1310 }
1275 1311
1276 /* Run the halt script if needed */ 1312 /* Run the halt script if needed */
1277 if (strcmp (runlevel, RC_LEVEL_SHUTDOWN) == 0 || 1313 if (strcmp (runlevel, RC_LEVEL_SHUTDOWN) == 0 ||
1282 applet, HALTSH, strerror (errno)); 1318 applet, HALTSH, strerror (errno));
1283 } 1319 }
1284 1320
1285 /* Single user is done now */ 1321 /* Single user is done now */
1286 if (strcmp (runlevel, RC_LEVEL_SINGLE) == 0) { 1322 if (strcmp (runlevel, RC_LEVEL_SINGLE) == 0) {
1287 if (rc_exists (INTERACTIVE)) 1323 if (exists (INTERACTIVE))
1288 unlink (INTERACTIVE); 1324 unlink (INTERACTIVE);
1289 sulogin (false); 1325 sulogin (false);
1290 } 1326 }
1291 1327
1292 mkdir (RC_STARTING, 0755); 1328 mkdir (RC_STARTING, 0755);
1293 rc_plugin_run (RC_HOOK_RUNLEVEL_START_IN, runlevel); 1329 rc_plugin_run (RC_HOOK_RUNLEVEL_START_IN, runlevel);
1294 1330
1295 /* Re-add our coldplugged services if they stopped */ 1331 /* Re-add our coldplugged services if they stopped */
1296 STRLIST_FOREACH (coldplugged_services, service, i) 1332 STRLIST_FOREACH (coldplugged_services, service, i)
1297 rc_mark_service (service, RC_SERVICE_COLDPLUGGED); 1333 rc_service_mark (service, RC_SERVICE_COLDPLUGGED);
1298 1334
1299 /* Order the services to start */ 1335 /* Order the services to start */
1300 rc_strlist_add (&types, "ineed");
1301 rc_strlist_add (&types, "iuse");
1302 rc_strlist_add (&types, "iafter");
1303 deporder = rc_deptree_depends (deptree, types, start_services, 1336 deporder = rc_deptree_depends (deptree, types_nua,
1337 (const char **) start_services,
1304 runlevel, depoptions | RC_DEP_START); 1338 runlevel, depoptions | RC_DEP_START);
1305 rc_strlist_free (types);
1306 types = NULL;
1307 rc_strlist_free (start_services); 1339 rc_strlist_free (start_services);
1308 start_services = deporder; 1340 start_services = deporder;
1309 deporder = NULL; 1341 deporder = NULL;
1310 1342
1311#ifdef __linux__ 1343#ifdef __linux__
1314 if ((service = proc_getent ("noinitd"))) { 1346 if ((service = proc_getent ("noinitd"))) {
1315 char *p = service; 1347 char *p = service;
1316 char *token; 1348 char *token;
1317 1349
1318 while ((token = strsep (&p, ","))) 1350 while ((token = strsep (&p, ",")))
1319 rc_mark_service (token, RC_SERVICE_STARTED); 1351 rc_service_mark (token, RC_SERVICE_STARTED);
1320 free (service); 1352 free (service);
1321 } 1353 }
1322 } 1354 }
1323#endif 1355#endif
1324 1356
1347 default: goto interactive_option; 1379 default: goto interactive_option;
1348 } 1380 }
1349 } 1381 }
1350 1382
1351 /* Remember the pid if we're running in parallel */ 1383 /* Remember the pid if we're running in parallel */
1352 if ((pid = rc_start_service (service))) 1384 if ((pid = rc_service_start (service)))
1353 add_pid (pid); 1385 add_pid (pid);
1354 1386
1355 if (! rc_env_bool ("RC_PARALLEL")) { 1387 if (! rc_env_bool ("RC_PARALLEL")) {
1356 rc_waitpid (pid); 1388 wait_pid (pid);
1357 remove_pid (pid); 1389 remove_pid (pid);
1358 } 1390 }
1359 } 1391 }
1360 } 1392 }
1361 1393
1370 if ((service = proc_getent ("noinitd"))) { 1402 if ((service = proc_getent ("noinitd"))) {
1371 char *p = service; 1403 char *p = service;
1372 char *token; 1404 char *token;
1373 1405
1374 while ((token = strsep (&p, ","))) 1406 while ((token = strsep (&p, ",")))
1375 rc_mark_service (token, RC_SERVICE_STOPPED); 1407 rc_service_mark (token, RC_SERVICE_STOPPED);
1376 free (service); 1408 free (service);
1377 } 1409 }
1378 } 1410 }
1379#endif 1411#endif
1380 1412
1381 /* Store our interactive status for boot */ 1413 /* Store our interactive status for boot */
1382 if (interactive && strcmp (runlevel, bootlevel) == 0) 1414 if (interactive && strcmp (runlevel, bootlevel) == 0)
1383 mark_interactive (); 1415 mark_interactive ();
1384 else { 1416 else {
1385 if (rc_exists (INTERACTIVE)) 1417 if (exists (INTERACTIVE))
1386 unlink (INTERACTIVE); 1418 unlink (INTERACTIVE);
1387 } 1419 }
1388 1420
1389 return (EXIT_SUCCESS); 1421 return (EXIT_SUCCESS);
1390} 1422}

Legend:
Removed from v.2957  
changed lines
  Added in v.3040

  ViewVC Help
Powered by ViewVC 1.1.20