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

Diff of /trunk/src/rc.c

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

Revision 2999 Revision 3040
28#include <stdbool.h> 28#include <stdbool.h>
29#include <stdio.h> 29#include <stdio.h>
30#include <stdlib.h> 30#include <stdlib.h>
31#include <signal.h> 31#include <signal.h>
32#include <string.h> 32#include <string.h>
33#include <strings.h>
33#include <syslog.h> 34#include <syslog.h>
34#include <termios.h> 35#include <termios.h>
35#include <unistd.h> 36#include <unistd.h>
36 37
37#include "builtins.h" 38#include "builtins.h"
69static char **newenv = NULL; 70static char **newenv = NULL;
70static char **coldplugged_services = NULL; 71static char **coldplugged_services = NULL;
71static char **stop_services = NULL; 72static char **stop_services = NULL;
72static char **start_services = NULL; 73static char **start_services = NULL;
73static rc_depinfo_t *deptree = NULL; 74static rc_depinfo_t *deptree = NULL;
74static char **types = NULL;
75static char *tmp = NULL; 75static char *tmp = NULL;
76 76
77struct termios *termios_orig = NULL; 77struct termios *termios_orig = NULL;
78 78
79typedef struct pidlist 79typedef struct pidlist
80{ 80{
81 pid_t pid; 81 pid_t pid;
82 struct pidlist *next; 82 struct pidlist *next;
83} pidlist_t; 83} pidlist_t;
84static 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 };
85 88
86static void cleanup (void) 89static void cleanup (void)
87{ 90{
88 if (applet && strcmp (applet, "rc") == 0) { 91 if (applet && strcmp (applet, "rc") == 0) {
89 pidlist_t *pl = service_pids; 92 pidlist_t *pl = service_pids;
105 rc_strlist_free (newenv); 108 rc_strlist_free (newenv);
106 rc_strlist_free (coldplugged_services); 109 rc_strlist_free (coldplugged_services);
107 rc_strlist_free (stop_services); 110 rc_strlist_free (stop_services);
108 rc_strlist_free (start_services); 111 rc_strlist_free (start_services);
109 rc_deptree_free (deptree); 112 rc_deptree_free (deptree);
110 rc_strlist_free (types);
111 113
112 /* Clean runlevel start, stop markers */ 114 /* Clean runlevel start, stop markers */
113 if (! rc_in_plugin) { 115 if (! rc_in_plugin) {
114 rmdir (RC_STARTING); 116 rmdir (RC_STARTING);
115 rmdir (RC_STOPPING); 117 rmdir (RC_STOPPING);
190 192
191 if (argc > 0) { 193 if (argc > 0) {
192 for (i = 0; i < argc; i++) 194 for (i = 0; i < argc; i++)
193 l += strlen (argv[i]) + 1; 195 l += strlen (argv[i]) + 1;
194 196
195 message = rc_xmalloc (l); 197 message = xmalloc (l);
196 p = message; 198 p = message;
197 199
198 for (i = 0; i < argc; i++) { 200 for (i = 0; i < argc; i++) {
199 if (i > 0) 201 if (i > 0)
200 *p++ = ' '; 202 *p++ = ' ';
203 } 205 }
204 *p = 0; 206 *p = 0;
205 } 207 }
206 208
207 if (message) 209 if (message)
208 fmt = rc_xstrdup ("%s"); 210 fmt = xstrdup ("%s");
209 211
210 if (strcmp (applet, "einfo") == 0) 212 if (strcmp (applet, "einfo") == 0)
211 einfo (fmt, message); 213 einfo (fmt, message);
212 else if (strcmp (applet, "einfon") == 0) 214 else if (strcmp (applet, "einfon") == 0)
213 einfon (fmt, message); 215 einfon (fmt, message);
314 ok = rc_service_mark (argv[0], RC_SERVICE_STOPPING); 316 ok = rc_service_mark (argv[0], RC_SERVICE_STOPPING);
315 else if (strcmp (applet, "mark_service_stopping") == 0) 317 else if (strcmp (applet, "mark_service_stopping") == 0)
316 ok = rc_service_mark (argv[0], RC_SERVICE_STOPPING); 318 ok = rc_service_mark (argv[0], RC_SERVICE_STOPPING);
317 else if (strcmp (applet, "mark_service_coldplugged") == 0) 319 else if (strcmp (applet, "mark_service_coldplugged") == 0)
318 ok = rc_service_mark (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);
319 else 323 else
320 eerrorx ("%s: unknown applet", applet); 324 eerrorx ("%s: unknown applet", applet);
321 325
322 /* 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
323 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 */
336 in control as well */ 340 in control as well */
337 l = strlen (RC_SVCDIR "exclusive") + 341 l = strlen (RC_SVCDIR "exclusive") +
338 strlen (svcname) + 342 strlen (svcname) +
339 strlen (runscript_pid) + 343 strlen (runscript_pid) +
340 4; 344 4;
341 mtime = rc_xmalloc (l); 345 mtime = xmalloc (l);
342 snprintf (mtime, l, RC_SVCDIR "exclusive/%s.%s", 346 snprintf (mtime, l, RC_SVCDIR "exclusive/%s.%s",
343 svcname, runscript_pid); 347 svcname, runscript_pid);
344 if (rc_exists (mtime) && unlink (mtime) != 0) 348 if (exists (mtime) && unlink (mtime) != 0)
345 eerror ("%s: unlink: %s", applet, strerror (errno)); 349 eerror ("%s: unlink: %s", applet, strerror (errno));
346 free (mtime); 350 free (mtime);
347 } 351 }
348 352
349 return (ok ? EXIT_SUCCESS : EXIT_FAILURE); 353 return (ok ? EXIT_SUCCESS : EXIT_FAILURE);
377 381
378#ifdef __linux__ 382#ifdef __linux__
379static char *proc_getent (const char *ent) 383static char *proc_getent (const char *ent)
380{ 384{
381 FILE *fp; 385 FILE *fp;
382 char buffer[RC_LINEBUFFER]; 386 char *buffer;
383 char *p; 387 char *p;
384 char *value = NULL; 388 char *value = NULL;
385 int i; 389 int i;
386 390
387 if (! rc_exists ("/proc/cmdline")) 391 if (! exists ("/proc/cmdline"))
388 return (NULL); 392 return (NULL);
389 393
390 if (! (fp = fopen ("/proc/cmdline", "r"))) { 394 if (! (fp = fopen ("/proc/cmdline", "r"))) {
391 eerror ("failed to open `/proc/cmdline': %s", strerror (errno)); 395 eerror ("failed to open `/proc/cmdline': %s", strerror (errno));
392 return (NULL); 396 return (NULL);
393 } 397 }
394 398
395 memset (buffer, 0, sizeof (buffer)); 399 buffer = xmalloc (sizeof (char) * RC_LINEBUFFER);
400 memset (buffer, 0, RC_LINEBUFFER);
396 if (fgets (buffer, RC_LINEBUFFER, fp) && 401 if (fgets (buffer, RC_LINEBUFFER, fp) &&
397 (p = strstr (buffer, ent))) 402 (p = strstr (buffer, ent)))
398 { 403 {
399 i = p - buffer; 404 i = p - buffer;
400 if (i == '\0' || buffer[i - 1] == ' ') { 405 if (i == '\0' || buffer[i - 1] == ' ') {
404 buffer[i] = 0; 409 buffer[i] = 0;
405 410
406 p += strlen (ent); 411 p += strlen (ent);
407 if (*p == '=') 412 if (*p == '=')
408 p++; 413 p++;
409 value = strdup (strsep (&p, " ")); 414 value = xstrdup (strsep (&p, " "));
410 } 415 }
411 } else 416 } else
412 errno = ENOENT; 417 errno = ENOENT;
418 free (buffer);
413 fclose (fp); 419 fclose (fp);
414 420
415 return (value); 421 return (value);
416} 422}
417#endif 423#endif
426 return (false); 432 return (false);
427 433
428 /* 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
429 will be changing it for non-blocking reads for Interactive */ 435 will be changing it for non-blocking reads for Interactive */
430 if (! termios_orig) { 436 if (! termios_orig) {
431 termios_orig = rc_xmalloc (sizeof (struct termios)); 437 termios_orig = xmalloc (sizeof (struct termios));
432 tcgetattr (fd, termios_orig); 438 tcgetattr (fd, termios_orig);
433 } 439 }
434 440
435 tcgetattr (fd, &termios); 441 tcgetattr (fd, &termios);
436 termios.c_lflag &= ~(ICANON | ECHO); 442 termios.c_lflag &= ~(ICANON | ECHO);
483 execl ("/sbin/halt", "/sbin/halt", "-f", (char *) NULL); 489 execl ("/sbin/halt", "/sbin/halt", "-f", (char *) NULL);
484 eerrorx ("%s: unable to exec `/sbin/halt': %s", applet, strerror (errno)); 490 eerrorx ("%s: unable to exec `/sbin/halt': %s", applet, strerror (errno));
485 } 491 }
486#endif 492#endif
487 493
488 newenv = rc_env_filter (); 494 newenv = env_filter ();
489 495
490 if (cont) { 496 if (cont) {
491 int status = 0; 497 int status = 0;
492#ifdef __linux__ 498#ifdef __linux__
493 char *tty = ttyname (fileno (stdout)); 499 char *tty = ttyname (fileno (stdout));
545 if (! level || 551 if (! level ||
546 strcmp (level, getenv ("RC_BOOTLEVEL")) == 0 || 552 strcmp (level, getenv ("RC_BOOTLEVEL")) == 0 ||
547 strcmp (level, RC_LEVEL_SINGLE) == 0 || 553 strcmp (level, RC_LEVEL_SINGLE) == 0 ||
548 strcmp (level, RC_LEVEL_SYSINIT) == 0) 554 strcmp (level, RC_LEVEL_SYSINIT) == 0)
549 { 555 {
550 if (rc_exists (RC_KSOFTLEVEL) && 556 if (exists (RC_KSOFTLEVEL) &&
551 unlink (RC_KSOFTLEVEL) != 0) 557 unlink (RC_KSOFTLEVEL) != 0)
552 eerror ("unlink `%s': %s", RC_KSOFTLEVEL, strerror (errno)); 558 eerror ("unlink `%s': %s", RC_KSOFTLEVEL, strerror (errno));
553 return; 559 return;
554 } 560 }
555 561
565static int get_ksoftlevel (char *buffer, int buffer_len) 571static int get_ksoftlevel (char *buffer, int buffer_len)
566{ 572{
567 FILE *fp; 573 FILE *fp;
568 int i = 0; 574 int i = 0;
569 575
570 if (! rc_exists (RC_KSOFTLEVEL)) 576 if (! exists (RC_KSOFTLEVEL))
571 return (0); 577 return (0);
572 578
573 if (! (fp = fopen (RC_KSOFTLEVEL, "r"))) { 579 if (! (fp = fopen (RC_KSOFTLEVEL, "r"))) {
574 eerror ("fopen `%s': %s", RC_KSOFTLEVEL, strerror (errno)); 580 eerror ("fopen `%s': %s", RC_KSOFTLEVEL, strerror (errno));
575 return (-1); 581 return (-1);
595{ 601{
596 pidlist_t *sp = service_pids; 602 pidlist_t *sp = service_pids;
597 if (sp) { 603 if (sp) {
598 while (sp->next) 604 while (sp->next)
599 sp = sp->next; 605 sp = sp->next;
600 sp->next = rc_xmalloc (sizeof (pidlist_t)); 606 sp->next = xmalloc (sizeof (pidlist_t));
601 sp = sp->next; 607 sp = sp->next;
602 } else 608 } else
603 sp = service_pids = rc_xmalloc (sizeof (pidlist_t)); 609 sp = service_pids = xmalloc (sizeof (pidlist_t));
604 memset (sp, 0, sizeof (pidlist_t)); 610 memset (sp, 0, sizeof (pidlist_t));
605 sp->pid = pid; 611 sp->pid = pid;
606} 612}
607 613
608static void remove_pid (pid_t pid) 614static void remove_pid (pid_t pid)
619 free (pl); 625 free (pl);
620 break; 626 break;
621 } 627 }
622 last = pl; 628 last = pl;
623 } 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);
624} 645}
625 646
626static void handle_signal (int sig) 647static void handle_signal (int sig)
627{ 648{
628 int serrno = errno; 649 int serrno = errno;
713 734
714#include "_usage.h" 735#include "_usage.h"
715#define getoptstring getoptstring_COMMON 736#define getoptstring getoptstring_COMMON
716static struct option longopts[] = { 737static struct option longopts[] = {
717 longopts_COMMON 738 longopts_COMMON
718 { NULL, 0, NULL, 0}
719}; 739};
720static const char * const longopts_help[] = { 740static const char * const longopts_help[] = {
721 longopts_help_COMMON 741 longopts_help_COMMON
722}; 742};
723#include "_usage.c" 743#include "_usage.c"
740 DIR *dp; 760 DIR *dp;
741 struct dirent *d; 761 struct dirent *d;
742 762
743 atexit (cleanup); 763 atexit (cleanup);
744 if (argv[0]) 764 if (argv[0])
745 applet = rc_xstrdup (basename (argv[0])); 765 applet = xstrdup (basename (argv[0]));
746 766
747 if (! applet) 767 if (! applet)
748 eerrorx ("arguments required"); 768 eerrorx ("arguments required");
749 769
750 /* 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
822 signal (SIGTERM, handle_signal); 842 signal (SIGTERM, handle_signal);
823 signal (SIGUSR1, handle_signal); 843 signal (SIGUSR1, handle_signal);
824 844
825 /* Ensure our environment is pure 845 /* Ensure our environment is pure
826 Also, add our configuration to it */ 846 Also, add our configuration to it */
827 env = rc_env_filter (); 847 env = env_filter ();
828 tmplist = rc_env_config (); 848 tmplist = env_config ();
829 rc_strlist_join (&env, tmplist); 849 rc_strlist_join (&env, tmplist);
830 rc_strlist_free (tmplist); 850 rc_strlist_free (tmplist);
831 851
832 if (env) { 852 if (env) {
833 char *p; 853 char *p;
841 /* No clearenv present here then. 861 /* No clearenv present here then.
842 We could manipulate environ directly ourselves, but it seems that 862 We could manipulate environ directly ourselves, but it seems that
843 some kernels bitch about this according to the environ man pages 863 some kernels bitch about this according to the environ man pages
844 so we walk though environ and call unsetenv for each value. */ 864 so we walk though environ and call unsetenv for each value. */
845 while (environ[0]) { 865 while (environ[0]) {
846 tmp = rc_xstrdup (environ[0]); 866 tmp = xstrdup (environ[0]);
847 p = tmp; 867 p = tmp;
848 var = strsep (&p, "="); 868 var = strsep (&p, "=");
849 unsetenv (var); 869 unsetenv (var);
850 free (tmp); 870 free (tmp);
851 } 871 }
881 901
882 /* Export our PID */ 902 /* Export our PID */
883 snprintf (pidstr, sizeof (pidstr), "%d", getpid ()); 903 snprintf (pidstr, sizeof (pidstr), "%d", getpid ());
884 setenv ("RC_PID", pidstr, 1); 904 setenv ("RC_PID", pidstr, 1);
885 905
886 interactive = rc_exists (INTERACTIVE); 906 interactive = exists (INTERACTIVE);
887 rc_plugin_load (); 907 rc_plugin_load ();
888 908
889 /* Load current softlevel */ 909 /* Load current softlevel */
890 bootlevel = getenv ("RC_BOOTLEVEL"); 910 bootlevel = getenv ("RC_BOOTLEVEL");
891 runlevel = rc_runlevel_get (); 911 runlevel = rc_runlevel_get ();
908#endif 928#endif
909 929
910 /* exec init-early.sh if it exists 930 /* exec init-early.sh if it exists
911 * This should just setup the console to use the correct 931 * This should just setup the console to use the correct
912 * font. Maybe it should setup the keyboard too? */ 932 * font. Maybe it should setup the keyboard too? */
913 if (rc_exists (INITEARLYSH)) 933 if (exists (INITEARLYSH))
914 run_script (INITEARLYSH); 934 run_script (INITEARLYSH);
915 935
916 uname (&uts); 936 uname (&uts);
917 937
918 printf ("\n"); 938 printf ("\n");
1024 /* Load our deptree now */ 1044 /* Load our deptree now */
1025 if ((deptree = _rc_deptree_load ()) == NULL) 1045 if ((deptree = _rc_deptree_load ()) == NULL)
1026 eerrorx ("failed to load deptree"); 1046 eerrorx ("failed to load deptree");
1027 1047
1028 /* Clean the failed services state dir now */ 1048 /* Clean the failed services state dir now */
1029 rc_rm_dir (RC_SVCDIR "/failed", false); 1049 if ((dp = opendir (RC_SVCDIR "/failed"))) {
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 ((dp = opendir (DEVBOOT))) { 1074 if ((dp = opendir (DEVBOOT))) {
1039 while ((d = readdir (dp))) { 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
1040 if (rc_service_exists (d->d_name) && 1081 if (rc_service_exists (d->d_name) &&
1041 rc_service_plugable (d->d_name)) 1082 rc_service_plugable (d->d_name))
1042 rc_service_mark (d->d_name, RC_SERVICE_COLDPLUGGED); 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 }
1043 } 1092 }
1044 closedir (dp); 1093 closedir (dp);
1045 rc_rm_dir (DEVBOOT, true); 1094 rmdir (DEVBOOT);
1046 } 1095 }
1047#else 1096#else
1048 /* 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.
1049 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
1050 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
1057#if defined(__DragonFly__) || defined(__FreeBSD__) 1106#if defined(__DragonFly__) || defined(__FreeBSD__)
1058 /* 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 :) */
1059 if ((dp = opendir ("/dev/net"))) { 1108 if ((dp = opendir ("/dev/net"))) {
1060 while ((d = readdir (dp))) { 1109 while ((d = readdir (dp))) {
1061 i = (strlen ("net.") + strlen (d->d_name) + 1); 1110 i = (strlen ("net.") + strlen (d->d_name) + 1);
1062 tmp = rc_xmalloc (sizeof (char *) * i); 1111 tmp = xmalloc (sizeof (char) * i);
1063 snprintf (tmp, i, "net.%s", d->d_name); 1112 snprintf (tmp, i, "net.%s", d->d_name);
1064 if (rc_service_exists (d->d_name) && 1113 if (rc_service_exists (tmp) &&
1065 rc_service_plugable (d->d_name)) 1114 rc_service_plugable (tmp))
1066 rc_service_mark (d->d_name, RC_SERVICE_COLDPLUGGED); 1115 rc_service_mark (tmp, RC_SERVICE_COLDPLUGGED);
1067 CHAR_FREE (tmp); 1116 CHAR_FREE (tmp);
1068 } 1117 }
1069 closedir (dp); 1118 closedir (dp);
1070 } 1119 }
1071#endif 1120#endif
1078 strncmp (d->d_name, "ums", 3) == 0) 1127 strncmp (d->d_name, "ums", 3) == 0)
1079 { 1128 {
1080 char *p = d->d_name + 3; 1129 char *p = d->d_name + 3;
1081 if (p && isdigit (*p)) { 1130 if (p && isdigit (*p)) {
1082 i = (strlen ("moused.") + strlen (d->d_name) + 1); 1131 i = (strlen ("moused.") + strlen (d->d_name) + 1);
1083 tmp = rc_xmalloc (sizeof (char *) * i); 1132 tmp = xmalloc (sizeof (char) * i);
1084 snprintf (tmp, i, "moused.%s", d->d_name); 1133 snprintf (tmp, i, "moused.%s", d->d_name);
1085 if (rc_service_exists (tmp) && rc_service_plugable (tmp)) 1134 if (rc_service_exists (tmp) && rc_service_plugable (tmp))
1086 rc_service_mark (tmp, RC_SERVICE_COLDPLUGGED); 1135 rc_service_mark (tmp, RC_SERVICE_COLDPLUGGED);
1087 CHAR_FREE (tmp); 1136 CHAR_FREE (tmp);
1088 } 1137 }
1103 1152
1104 tmplist = rc_services_in_state (RC_SERVICE_STARTED); 1153 tmplist = rc_services_in_state (RC_SERVICE_STARTED);
1105 rc_strlist_join (&stop_services, tmplist); 1154 rc_strlist_join (&stop_services, tmplist);
1106 rc_strlist_free (tmplist); 1155 rc_strlist_free (tmplist);
1107 1156
1108 types = NULL;
1109 rc_strlist_add (&types, "ineed");
1110 rc_strlist_add (&types, "iuse");
1111 rc_strlist_add (&types, "iafter");
1112
1113 deporder = rc_deptree_depends (deptree, types, stop_services, 1157 deporder = rc_deptree_depends (deptree, types_nua,
1158 (const char **) stop_services,
1114 runlevel, depoptions | RC_DEP_STOP); 1159 runlevel, depoptions | RC_DEP_STOP);
1115 1160
1116 rc_strlist_free (stop_services); 1161 rc_strlist_free (stop_services);
1117 rc_strlist_free (types);
1118 types = NULL;
1119 stop_services = deporder; 1162 stop_services = deporder;
1120 deporder = NULL; 1163 deporder = NULL;
1121 rc_strlist_reverse (stop_services); 1164 rc_strlist_reverse (stop_services);
1122 1165
1123 /* Load our list of coldplugged services */ 1166 /* Load our list of coldplugged services */
1162 1205
1163 /* Save out softlevel now */ 1206 /* Save out softlevel now */
1164 if (going_down) 1207 if (going_down)
1165 rc_runlevel_set (newlevel); 1208 rc_runlevel_set (newlevel);
1166 1209
1167 types = NULL;
1168 rc_strlist_add (&types, "needsme");
1169 /* Now stop the services that shouldn't be running */ 1210 /* Now stop the services that shouldn't be running */
1170 STRLIST_FOREACH (stop_services, service, i) { 1211 STRLIST_FOREACH (stop_services, service, i) {
1171 bool found = false; 1212 bool found = false;
1172 char *conf = NULL; 1213 char *conf = NULL;
1173 char **stopdeps = NULL; 1214 char **stopdeps = NULL;
1180 1221
1181 /* We always stop the service when in these runlevels */ 1222 /* We always stop the service when in these runlevels */
1182 if (going_down) { 1223 if (going_down) {
1183 pid_t pid = rc_service_stop (service); 1224 pid_t pid = rc_service_stop (service);
1184 if (pid > 0 && ! rc_env_bool ("RC_PARALLEL")) 1225 if (pid > 0 && ! rc_env_bool ("RC_PARALLEL"))
1185 rc_waitpid (pid); 1226 wait_pid (pid);
1186 continue; 1227 continue;
1187 } 1228 }
1188 1229
1189 /* 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 */
1190 STRLIST_FOREACH (start_services, svc1, j) 1231 STRLIST_FOREACH (start_services, svc1, j)
1198 int len; 1239 int len;
1199 if (! newlevel) 1240 if (! newlevel)
1200 continue; 1241 continue;
1201 1242
1202 len = strlen (service) + strlen (runlevel) + 2; 1243 len = strlen (service) + strlen (runlevel) + 2;
1203 tmp = rc_xmalloc (sizeof (char *) * len); 1244 tmp = xmalloc (sizeof (char) * len);
1204 snprintf (tmp, len, "%s.%s", service, runlevel); 1245 snprintf (tmp, len, "%s.%s", service, runlevel);
1205 conf = rc_strcatpaths (RC_CONFDIR, tmp, (char *) NULL); 1246 conf = rc_strcatpaths (RC_CONFDIR, tmp, (char *) NULL);
1206 found = rc_exists (conf); 1247 found = exists (conf);
1207 CHAR_FREE (conf); 1248 CHAR_FREE (conf);
1208 CHAR_FREE (tmp); 1249 CHAR_FREE (tmp);
1209 if (! found) { 1250 if (! found) {
1210 len = strlen (service) + strlen (newlevel) + 2; 1251 len = strlen (service) + strlen (newlevel) + 2;
1211 tmp = rc_xmalloc (sizeof (char *) * len); 1252 tmp = xmalloc (sizeof (char) * len);
1212 snprintf (tmp, len, "%s.%s", service, newlevel); 1253 snprintf (tmp, len, "%s.%s", service, newlevel);
1213 conf = rc_strcatpaths (RC_CONFDIR, tmp, (char *) NULL); 1254 conf = rc_strcatpaths (RC_CONFDIR, tmp, (char *) NULL);
1214 found = rc_exists (conf); 1255 found = exists (conf);
1215 CHAR_FREE (conf); 1256 CHAR_FREE (conf);
1216 CHAR_FREE (tmp); 1257 CHAR_FREE (tmp);
1217 if (!found) 1258 if (!found)
1218 continue; 1259 continue;
1219 } 1260 }
1224 } 1265 }
1225 1266
1226 /* 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
1227 going to be started depends on us */ 1268 going to be started depends on us */
1228 rc_strlist_add (&stopdeps, service); 1269 rc_strlist_add (&stopdeps, service);
1229 deporder = rc_deptree_depends (deptree, types, stopdeps, 1270 deporder = rc_deptree_depends (deptree, types_n,
1271 (const char **) stopdeps,
1230 runlevel, RC_DEP_STRICT); 1272 runlevel, RC_DEP_STRICT);
1231 rc_strlist_free (stopdeps); 1273 rc_strlist_free (stopdeps);
1232 stopdeps = NULL; 1274 stopdeps = NULL;
1233 found = false; 1275 found = false;
1234 STRLIST_FOREACH (deporder, svc1, j) { 1276 STRLIST_FOREACH (deporder, svc1, j) {
1245 1287
1246 /* After all that we can finally stop the blighter! */ 1288 /* After all that we can finally stop the blighter! */
1247 if (! found) { 1289 if (! found) {
1248 pid_t pid = rc_service_stop (service); 1290 pid_t pid = rc_service_stop (service);
1249 if (pid > 0 && ! rc_env_bool ("RC_PARALLEL")) 1291 if (pid > 0 && ! rc_env_bool ("RC_PARALLEL"))
1250 rc_waitpid (pid); 1292 wait_pid (pid);
1251 }
1252 } 1293 }
1253 rc_strlist_free (types); 1294 }
1254 types = NULL;
1255 1295
1256 /* Wait for our services to finish */ 1296 /* Wait for our services to finish */
1257 wait_for_services (); 1297 wait_for_services ();
1258 1298
1259 /* Notify the plugins we have finished */ 1299 /* Notify the plugins we have finished */
1263 1303
1264 /* Store the new runlevel */ 1304 /* Store the new runlevel */
1265 if (newlevel) { 1305 if (newlevel) {
1266 rc_runlevel_set (newlevel); 1306 rc_runlevel_set (newlevel);
1267 free (runlevel); 1307 free (runlevel);
1268 runlevel = rc_xstrdup (newlevel); 1308 runlevel = xstrdup (newlevel);
1269 setenv ("RC_SOFTLEVEL", runlevel, 1); 1309 setenv ("RC_SOFTLEVEL", runlevel, 1);
1270 } 1310 }
1271 1311
1272 /* Run the halt script if needed */ 1312 /* Run the halt script if needed */
1273 if (strcmp (runlevel, RC_LEVEL_SHUTDOWN) == 0 || 1313 if (strcmp (runlevel, RC_LEVEL_SHUTDOWN) == 0 ||
1278 applet, HALTSH, strerror (errno)); 1318 applet, HALTSH, strerror (errno));
1279 } 1319 }
1280 1320
1281 /* Single user is done now */ 1321 /* Single user is done now */
1282 if (strcmp (runlevel, RC_LEVEL_SINGLE) == 0) { 1322 if (strcmp (runlevel, RC_LEVEL_SINGLE) == 0) {
1283 if (rc_exists (INTERACTIVE)) 1323 if (exists (INTERACTIVE))
1284 unlink (INTERACTIVE); 1324 unlink (INTERACTIVE);
1285 sulogin (false); 1325 sulogin (false);
1286 } 1326 }
1287 1327
1288 mkdir (RC_STARTING, 0755); 1328 mkdir (RC_STARTING, 0755);
1291 /* Re-add our coldplugged services if they stopped */ 1331 /* Re-add our coldplugged services if they stopped */
1292 STRLIST_FOREACH (coldplugged_services, service, i) 1332 STRLIST_FOREACH (coldplugged_services, service, i)
1293 rc_service_mark (service, RC_SERVICE_COLDPLUGGED); 1333 rc_service_mark (service, RC_SERVICE_COLDPLUGGED);
1294 1334
1295 /* Order the services to start */ 1335 /* Order the services to start */
1296 rc_strlist_add (&types, "ineed");
1297 rc_strlist_add (&types, "iuse");
1298 rc_strlist_add (&types, "iafter");
1299 deporder = rc_deptree_depends (deptree, types, start_services, 1336 deporder = rc_deptree_depends (deptree, types_nua,
1337 (const char **) start_services,
1300 runlevel, depoptions | RC_DEP_START); 1338 runlevel, depoptions | RC_DEP_START);
1301 rc_strlist_free (types);
1302 types = NULL;
1303 rc_strlist_free (start_services); 1339 rc_strlist_free (start_services);
1304 start_services = deporder; 1340 start_services = deporder;
1305 deporder = NULL; 1341 deporder = NULL;
1306 1342
1307#ifdef __linux__ 1343#ifdef __linux__
1347 /* Remember the pid if we're running in parallel */ 1383 /* Remember the pid if we're running in parallel */
1348 if ((pid = rc_service_start (service))) 1384 if ((pid = rc_service_start (service)))
1349 add_pid (pid); 1385 add_pid (pid);
1350 1386
1351 if (! rc_env_bool ("RC_PARALLEL")) { 1387 if (! rc_env_bool ("RC_PARALLEL")) {
1352 rc_waitpid (pid); 1388 wait_pid (pid);
1353 remove_pid (pid); 1389 remove_pid (pid);
1354 } 1390 }
1355 } 1391 }
1356 } 1392 }
1357 1393
1376 1412
1377 /* Store our interactive status for boot */ 1413 /* Store our interactive status for boot */
1378 if (interactive && strcmp (runlevel, bootlevel) == 0) 1414 if (interactive && strcmp (runlevel, bootlevel) == 0)
1379 mark_interactive (); 1415 mark_interactive ();
1380 else { 1416 else {
1381 if (rc_exists (INTERACTIVE)) 1417 if (exists (INTERACTIVE))
1382 unlink (INTERACTIVE); 1418 unlink (INTERACTIVE);
1383 } 1419 }
1384 1420
1385 return (EXIT_SUCCESS); 1421 return (EXIT_SUCCESS);
1386} 1422}

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

  ViewVC Help
Powered by ViewVC 1.1.20