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

Diff of /trunk/src/rc.c

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

Revision 2978 Revision 3036
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"
108 rc_deptree_free (deptree); 110 rc_deptree_free (deptree);
109 rc_strlist_free (types); 111 rc_strlist_free (types);
110 112
111 /* Clean runlevel start, stop markers */ 113 /* Clean runlevel start, stop markers */
112 if (! rc_in_plugin) { 114 if (! rc_in_plugin) {
113 if (rc_is_dir (RC_STARTING))
114 rc_rm_dir (RC_STARTING, true); 115 rmdir (RC_STARTING);
115 if (rc_is_dir (RC_STOPPING))
116 rc_rm_dir (RC_STOPPING, true); 116 rmdir (RC_STOPPING);
117 } 117 }
118 118
119 free (runlevel); 119 free (runlevel);
120 } 120 }
121 121
191 191
192 if (argc > 0) { 192 if (argc > 0) {
193 for (i = 0; i < argc; i++) 193 for (i = 0; i < argc; i++)
194 l += strlen (argv[i]) + 1; 194 l += strlen (argv[i]) + 1;
195 195
196 message = rc_xmalloc (l); 196 message = xmalloc (l);
197 p = message; 197 p = message;
198 198
199 for (i = 0; i < argc; i++) { 199 for (i = 0; i < argc; i++) {
200 if (i > 0) 200 if (i > 0)
201 *p++ = ' '; 201 *p++ = ' ';
204 } 204 }
205 *p = 0; 205 *p = 0;
206 } 206 }
207 207
208 if (message) 208 if (message)
209 fmt = rc_xstrdup ("%s"); 209 fmt = xstrdup ("%s");
210 210
211 if (strcmp (applet, "einfo") == 0) 211 if (strcmp (applet, "einfo") == 0)
212 einfo (fmt, message); 212 einfo (fmt, message);
213 else if (strcmp (applet, "einfon") == 0) 213 else if (strcmp (applet, "einfon") == 0)
214 einfon (fmt, message); 214 einfon (fmt, message);
315 ok = rc_service_mark (argv[0], RC_SERVICE_STOPPING); 315 ok = rc_service_mark (argv[0], RC_SERVICE_STOPPING);
316 else if (strcmp (applet, "mark_service_stopping") == 0) 316 else if (strcmp (applet, "mark_service_stopping") == 0)
317 ok = rc_service_mark (argv[0], RC_SERVICE_STOPPING); 317 ok = rc_service_mark (argv[0], RC_SERVICE_STOPPING);
318 else if (strcmp (applet, "mark_service_coldplugged") == 0) 318 else if (strcmp (applet, "mark_service_coldplugged") == 0)
319 ok = rc_service_mark (argv[0], RC_SERVICE_COLDPLUGGED); 319 ok = rc_service_mark (argv[0], RC_SERVICE_COLDPLUGGED);
320 else if (strcmp (applet, "mark_service_failed") == 0)
321 ok = rc_service_mark (argv[0], RC_SERVICE_FAILED);
320 else 322 else
321 eerrorx ("%s: unknown applet", applet); 323 eerrorx ("%s: unknown applet", applet);
322 324
323 /* If we're marking ourselves then we need to inform our parent runscript 325 /* If we're marking ourselves then we need to inform our parent runscript
324 process so they do not mark us based on our exit code */ 326 process so they do not mark us based on our exit code */
331 if (runscript_pid && sscanf (runscript_pid, "%d", &pid) == 1) 333 if (runscript_pid && sscanf (runscript_pid, "%d", &pid) == 1)
332 if (kill (pid, SIGHUP) != 0) 334 if (kill (pid, SIGHUP) != 0)
333 eerror ("%s: failed to signal parent %d: %s", 335 eerror ("%s: failed to signal parent %d: %s",
334 applet, pid, strerror (errno)); 336 applet, pid, strerror (errno));
335 337
336 /* Remove the exclsive time test. This ensures that it's not 338 /* Remove the exclusive time test. This ensures that it's not
337 in control as well */ 339 in control as well */
338 l = strlen (RC_SVCDIR "exclusive") + 340 l = strlen (RC_SVCDIR "exclusive") +
339 strlen (svcname) + 341 strlen (svcname) +
340 strlen (runscript_pid) + 342 strlen (runscript_pid) +
341 4; 343 4;
342 mtime = rc_xmalloc (l); 344 mtime = xmalloc (l);
343 snprintf (mtime, l, RC_SVCDIR "exclusive/%s.%s", 345 snprintf (mtime, l, RC_SVCDIR "exclusive/%s.%s",
344 svcname, runscript_pid); 346 svcname, runscript_pid);
345 if (rc_exists (mtime) && unlink (mtime) != 0) 347 if (exists (mtime) && unlink (mtime) != 0)
346 eerror ("%s: unlink: %s", applet, strerror (errno)); 348 eerror ("%s: unlink: %s", applet, strerror (errno));
347 free (mtime); 349 free (mtime);
348 } 350 }
349 351
350 return (ok ? EXIT_SUCCESS : EXIT_FAILURE); 352 return (ok ? EXIT_SUCCESS : EXIT_FAILURE);
378 380
379#ifdef __linux__ 381#ifdef __linux__
380static char *proc_getent (const char *ent) 382static char *proc_getent (const char *ent)
381{ 383{
382 FILE *fp; 384 FILE *fp;
383 char buffer[RC_LINEBUFFER]; 385 char *buffer;
384 char *p; 386 char *p;
385 char *value = NULL; 387 char *value = NULL;
386 int i; 388 int i;
387 389
388 if (! rc_exists ("/proc/cmdline")) 390 if (! exists ("/proc/cmdline"))
389 return (NULL); 391 return (NULL);
390 392
391 if (! (fp = fopen ("/proc/cmdline", "r"))) { 393 if (! (fp = fopen ("/proc/cmdline", "r"))) {
392 eerror ("failed to open `/proc/cmdline': %s", strerror (errno)); 394 eerror ("failed to open `/proc/cmdline': %s", strerror (errno));
393 return (NULL); 395 return (NULL);
394 } 396 }
395 397
396 memset (buffer, 0, sizeof (buffer)); 398 buffer = xmalloc (sizeof (char) * RC_LINEBUFFER);
399 memset (buffer, 0, RC_LINEBUFFER);
397 if (fgets (buffer, RC_LINEBUFFER, fp) && 400 if (fgets (buffer, RC_LINEBUFFER, fp) &&
398 (p = strstr (buffer, ent))) 401 (p = strstr (buffer, ent)))
399 { 402 {
400 i = p - buffer; 403 i = p - buffer;
401 if (i == '\0' || buffer[i - 1] == ' ') { 404 if (i == '\0' || buffer[i - 1] == ' ') {
405 buffer[i] = 0; 408 buffer[i] = 0;
406 409
407 p += strlen (ent); 410 p += strlen (ent);
408 if (*p == '=') 411 if (*p == '=')
409 p++; 412 p++;
410 value = strdup (strsep (&p, " ")); 413 value = xstrdup (strsep (&p, " "));
411 } 414 }
412 } else 415 } else
413 errno = ENOENT; 416 errno = ENOENT;
417 free (buffer);
414 fclose (fp); 418 fclose (fp);
415 419
416 return (value); 420 return (value);
417} 421}
418#endif 422#endif
420static char read_key (bool block) 424static char read_key (bool block)
421{ 425{
422 struct termios termios; 426 struct termios termios;
423 char c = 0; 427 char c = 0;
424 int fd = fileno (stdin); 428 int fd = fileno (stdin);
425 429
426 if (! isatty (fd)) 430 if (! isatty (fd))
427 return (false); 431 return (false);
428 432
429 /* Now save our terminal settings. We need to restore them at exit as we 433 /* Now save our terminal settings. We need to restore them at exit as we
430 will be changing it for non-blocking reads for Interactive */ 434 will be changing it for non-blocking reads for Interactive */
431 if (! termios_orig) { 435 if (! termios_orig) {
432 termios_orig = rc_xmalloc (sizeof (struct termios)); 436 termios_orig = xmalloc (sizeof (struct termios));
433 tcgetattr (fd, termios_orig); 437 tcgetattr (fd, termios_orig);
434 } 438 }
435 439
436 tcgetattr (fd, &termios); 440 tcgetattr (fd, &termios);
437 termios.c_lflag &= ~(ICANON | ECHO); 441 termios.c_lflag &= ~(ICANON | ECHO);
484 execl ("/sbin/halt", "/sbin/halt", "-f", (char *) NULL); 488 execl ("/sbin/halt", "/sbin/halt", "-f", (char *) NULL);
485 eerrorx ("%s: unable to exec `/sbin/halt': %s", applet, strerror (errno)); 489 eerrorx ("%s: unable to exec `/sbin/halt': %s", applet, strerror (errno));
486 } 490 }
487#endif 491#endif
488 492
489 newenv = rc_filter_env (); 493 newenv = env_filter ();
490 494
491 if (cont) { 495 if (cont) {
492 int status = 0; 496 int status = 0;
493#ifdef __linux__ 497#ifdef __linux__
494 char *tty = ttyname (fileno (stdout)); 498 char *tty = ttyname (fileno (stdout));
546 if (! level || 550 if (! level ||
547 strcmp (level, getenv ("RC_BOOTLEVEL")) == 0 || 551 strcmp (level, getenv ("RC_BOOTLEVEL")) == 0 ||
548 strcmp (level, RC_LEVEL_SINGLE) == 0 || 552 strcmp (level, RC_LEVEL_SINGLE) == 0 ||
549 strcmp (level, RC_LEVEL_SYSINIT) == 0) 553 strcmp (level, RC_LEVEL_SYSINIT) == 0)
550 { 554 {
551 if (rc_exists (RC_KSOFTLEVEL) && 555 if (exists (RC_KSOFTLEVEL) &&
552 unlink (RC_KSOFTLEVEL) != 0) 556 unlink (RC_KSOFTLEVEL) != 0)
553 eerror ("unlink `%s': %s", RC_KSOFTLEVEL, strerror (errno)); 557 eerror ("unlink `%s': %s", RC_KSOFTLEVEL, strerror (errno));
554 return; 558 return;
555 } 559 }
556 560
566static int get_ksoftlevel (char *buffer, int buffer_len) 570static int get_ksoftlevel (char *buffer, int buffer_len)
567{ 571{
568 FILE *fp; 572 FILE *fp;
569 int i = 0; 573 int i = 0;
570 574
571 if (! rc_exists (RC_KSOFTLEVEL)) 575 if (! exists (RC_KSOFTLEVEL))
572 return (0); 576 return (0);
573 577
574 if (! (fp = fopen (RC_KSOFTLEVEL, "r"))) { 578 if (! (fp = fopen (RC_KSOFTLEVEL, "r"))) {
575 eerror ("fopen `%s': %s", RC_KSOFTLEVEL, strerror (errno)); 579 eerror ("fopen `%s': %s", RC_KSOFTLEVEL, strerror (errno));
576 return (-1); 580 return (-1);
596{ 600{
597 pidlist_t *sp = service_pids; 601 pidlist_t *sp = service_pids;
598 if (sp) { 602 if (sp) {
599 while (sp->next) 603 while (sp->next)
600 sp = sp->next; 604 sp = sp->next;
601 sp->next = rc_xmalloc (sizeof (pidlist_t)); 605 sp->next = xmalloc (sizeof (pidlist_t));
602 sp = sp->next; 606 sp = sp->next;
603 } else 607 } else
604 sp = service_pids = rc_xmalloc (sizeof (pidlist_t)); 608 sp = service_pids = xmalloc (sizeof (pidlist_t));
605 memset (sp, 0, sizeof (pidlist_t)); 609 memset (sp, 0, sizeof (pidlist_t));
606 sp->pid = pid; 610 sp->pid = pid;
607} 611}
608 612
609static void remove_pid (pid_t pid) 613static void remove_pid (pid_t pid)
620 free (pl); 624 free (pl);
621 break; 625 break;
622 } 626 }
623 last = pl; 627 last = pl;
624 } 628 }
629}
630
631static int wait_pid (pid_t pid)
632{
633 int status = 0;
634 pid_t savedpid = pid;
635 int retval = -1;
636
637 errno = 0;
638 while ((pid = waitpid (savedpid, &status, 0)) > 0) {
639 if (pid == savedpid)
640 retval = WIFEXITED (status) ? WEXITSTATUS (status) : EXIT_FAILURE;
641 }
642
643 return (retval);
625} 644}
626 645
627static void handle_signal (int sig) 646static void handle_signal (int sig)
628{ 647{
629 int serrno = errno; 648 int serrno = errno;
714 733
715#include "_usage.h" 734#include "_usage.h"
716#define getoptstring getoptstring_COMMON 735#define getoptstring getoptstring_COMMON
717static struct option longopts[] = { 736static struct option longopts[] = {
718 longopts_COMMON 737 longopts_COMMON
719 { NULL, 0, NULL, 0}
720}; 738};
721static const char * const longopts_help[] = { 739static const char * const longopts_help[] = {
722 longopts_help_COMMON 740 longopts_help_COMMON
723}; 741};
724#include "_usage.c" 742#include "_usage.c"
736 bool interactive = false; 754 bool interactive = false;
737 int depoptions = RC_DEP_STRICT | RC_DEP_TRACE; 755 int depoptions = RC_DEP_STRICT | RC_DEP_TRACE;
738 char ksoftbuffer [PATH_MAX]; 756 char ksoftbuffer [PATH_MAX];
739 char pidstr[6]; 757 char pidstr[6];
740 int opt; 758 int opt;
759 DIR *dp;
760 struct dirent *d;
741 761
742 atexit (cleanup); 762 atexit (cleanup);
743 if (argv[0]) 763 if (argv[0])
744 applet = rc_xstrdup (basename (argv[0])); 764 applet = xstrdup (basename (argv[0]));
745 765
746 if (! applet) 766 if (! applet)
747 eerrorx ("arguments required"); 767 eerrorx ("arguments required");
748 768
749 /* These used to be programs in their own right, so we shouldn't 769 /* These used to be programs in their own right, so we shouldn't
821 signal (SIGTERM, handle_signal); 841 signal (SIGTERM, handle_signal);
822 signal (SIGUSR1, handle_signal); 842 signal (SIGUSR1, handle_signal);
823 843
824 /* Ensure our environment is pure 844 /* Ensure our environment is pure
825 Also, add our configuration to it */ 845 Also, add our configuration to it */
826 env = rc_filter_env (); 846 env = env_filter ();
827 tmplist = rc_make_env (); 847 tmplist = env_config ();
828 rc_strlist_join (&env, tmplist); 848 rc_strlist_join (&env, tmplist);
829 rc_strlist_free (tmplist); 849 rc_strlist_free (tmplist);
830 850
831 if (env) { 851 if (env) {
832 char *p; 852 char *p;
840 /* No clearenv present here then. 860 /* No clearenv present here then.
841 We could manipulate environ directly ourselves, but it seems that 861 We could manipulate environ directly ourselves, but it seems that
842 some kernels bitch about this according to the environ man pages 862 some kernels bitch about this according to the environ man pages
843 so we walk though environ and call unsetenv for each value. */ 863 so we walk though environ and call unsetenv for each value. */
844 while (environ[0]) { 864 while (environ[0]) {
845 tmp = rc_xstrdup (environ[0]); 865 tmp = xstrdup (environ[0]);
846 p = tmp; 866 p = tmp;
847 var = strsep (&p, "="); 867 var = strsep (&p, "=");
848 unsetenv (var); 868 unsetenv (var);
849 free (tmp); 869 free (tmp);
850 } 870 }
880 900
881 /* Export our PID */ 901 /* Export our PID */
882 snprintf (pidstr, sizeof (pidstr), "%d", getpid ()); 902 snprintf (pidstr, sizeof (pidstr), "%d", getpid ());
883 setenv ("RC_PID", pidstr, 1); 903 setenv ("RC_PID", pidstr, 1);
884 904
885 interactive = rc_exists (INTERACTIVE); 905 interactive = exists (INTERACTIVE);
886 rc_plugin_load (); 906 rc_plugin_load ();
887 907
888 /* Load current softlevel */ 908 /* Load current softlevel */
889 bootlevel = getenv ("RC_BOOTLEVEL"); 909 bootlevel = getenv ("RC_BOOTLEVEL");
890 runlevel = rc_runlevel_get (); 910 runlevel = rc_runlevel_get ();
907#endif 927#endif
908 928
909 /* exec init-early.sh if it exists 929 /* exec init-early.sh if it exists
910 * This should just setup the console to use the correct 930 * This should just setup the console to use the correct
911 * font. Maybe it should setup the keyboard too? */ 931 * font. Maybe it should setup the keyboard too? */
912 if (rc_exists (INITEARLYSH)) 932 if (exists (INITEARLYSH))
913 run_script (INITEARLYSH); 933 run_script (INITEARLYSH);
914 934
915 uname (&uts); 935 uname (&uts);
916 936
917 printf ("\n"); 937 printf ("\n");
1014 rc_plugin_run (RC_HOOK_RUNLEVEL_STOP_IN, runlevel); 1034 rc_plugin_run (RC_HOOK_RUNLEVEL_STOP_IN, runlevel);
1015 } 1035 }
1016 1036
1017 /* Check if runlevel is valid if we're changing */ 1037 /* Check if runlevel is valid if we're changing */
1018 if (newlevel && strcmp (runlevel, newlevel) != 0 && ! going_down) { 1038 if (newlevel && strcmp (runlevel, newlevel) != 0 && ! going_down) {
1019 tmp = rc_strcatpaths (RC_RUNLEVELDIR, newlevel, (char *) NULL); 1039 if (! rc_runlevel_exists (newlevel))
1020 if (! rc_is_dir (tmp))
1021 eerrorx ("%s: is not a valid runlevel", newlevel); 1040 eerrorx ("%s: is not a valid runlevel", newlevel);
1022 CHAR_FREE (tmp);
1023 } 1041 }
1024 1042
1025 /* Load our deptree now */ 1043 /* Load our deptree now */
1026 if ((deptree = _rc_deptree_load ()) == NULL) 1044 if ((deptree = _rc_deptree_load ()) == NULL)
1027 eerrorx ("failed to load deptree"); 1045 eerrorx ("failed to load deptree");
1028 1046
1029 /* Clean the failed services state dir now */ 1047 /* Clean the failed services state dir now */
1030 if (rc_is_dir (RC_SVCDIR "/failed")) 1048 if ((dp = opendir (RC_SVCDIR "/failed"))) {
1031 rc_rm_dir (RC_SVCDIR "/failed", false); 1049 while ((d = readdir (dp))) {
1050 if (d->d_name[0] == '.' &&
1051 (d->d_name[1] == '\0' ||
1052 (d->d_name[1] == '.' && d->d_name[2] == '\0')))
1053 continue;
1054
1055 asprintf (&tmp, RC_SVCDIR "/failed/%s", d->d_name);
1056 if (tmp) {
1057 if (unlink (tmp))
1058 eerror ("%s: unlink `%s': %s", applet, tmp,
1059 strerror (errno));
1060 free (tmp);
1061 }
1062 }
1063 closedir (dp);
1064 }
1032 1065
1033 mkdir (RC_STOPPING, 0755); 1066 mkdir (RC_STOPPING, 0755);
1034 1067
1035#ifdef __linux__ 1068#ifdef __linux__
1036 /* udev likes to start services before we're ready when it does 1069 /* udev likes to start services before we're ready when it does
1037 its coldplugging thing. runscript knows when we're not ready so it 1070 its coldplugging thing. runscript knows when we're not ready so it
1038 stores a list of coldplugged services in DEVBOOT for us to pick up 1071 stores a list of coldplugged services in DEVBOOT for us to pick up
1039 here when we are ready for them */ 1072 here when we are ready for them */
1040 if (rc_is_dir (DEVBOOT)) { 1073 if ((dp = opendir (DEVBOOT))) {
1041 start_services = rc_ls_dir (DEVBOOT, RC_LS_INITD); 1074 while ((d = readdir (dp))) {
1042 rc_rm_dir (DEVBOOT, true); 1075 if (d->d_name[0] == '.' &&
1076 (d->d_name[1] == '\0' ||
1077 (d->d_name[1] == '.' && d->d_name[2] == '\0')))
1078 continue;
1043 1079
1044 STRLIST_FOREACH (start_services, service, i) 1080 if (rc_service_exists (d->d_name) &&
1045 if (rc_service_plugable (service)) 1081 rc_service_plugable (d->d_name))
1046 rc_service_mark (service, RC_SERVICE_COLDPLUGGED); 1082 rc_service_mark (d->d_name, RC_SERVICE_COLDPLUGGED);
1047 /* We need to dump this list now. 1083
1048 This may seem redunant, but only Linux needs this and saves on 1084 asprintf (&tmp, DEVBOOT "/%s", d->d_name);
1049 code bloat. */ 1085 if (tmp) {
1050 rc_strlist_free (start_services); 1086 if (unlink (tmp))
1051 start_services = NULL; 1087 eerror ("%s: unlink `%s': %s", applet, tmp,
1088 strerror (errno));
1089 free (tmp);
1090 }
1091 }
1092 closedir (dp);
1093 rmdir (DEVBOOT);
1052 } 1094 }
1053#else 1095#else
1054 /* BSD's on the other hand populate /dev automagically and use devd. 1096 /* BSD's on the other hand populate /dev automagically and use devd.
1055 The only downside of this approach and ours is that we have to hard code 1097 The only downside of this approach and ours is that we have to hard code
1056 the device node to the init script to simulate the coldplug into 1098 the device node to the init script to simulate the coldplug into
1060 strcmp (runlevel, RC_LEVEL_SYSINIT) == 0) && 1102 strcmp (runlevel, RC_LEVEL_SYSINIT) == 0) &&
1061 rc_env_bool ("RC_COLDPLUG")) 1103 rc_env_bool ("RC_COLDPLUG"))
1062 { 1104 {
1063#if defined(__DragonFly__) || defined(__FreeBSD__) 1105#if defined(__DragonFly__) || defined(__FreeBSD__)
1064 /* The net interfaces are easy - they're all in net /dev/net :) */ 1106 /* The net interfaces are easy - they're all in net /dev/net :) */
1065 start_services = rc_ls_dir ("/dev/net", 0); 1107 if ((dp = opendir ("/dev/net"))) {
1066 STRLIST_FOREACH (start_services, service, i) { 1108 while ((d = readdir (dp))) {
1067 j = (strlen ("net.") + strlen (service) + 1); 1109 i = (strlen ("net.") + strlen (d->d_name) + 1);
1068 tmp = rc_xmalloc (sizeof (char *) * j); 1110 tmp = xmalloc (sizeof (char) * i);
1069 snprintf (tmp, j, "net.%s", service); 1111 snprintf (tmp, i, "net.%s", d->d_name);
1070 if (rc_service_exists (tmp) && rc_service_plugable (tmp)) 1112 if (rc_service_exists (tmp) &&
1113 rc_service_plugable (tmp))
1071 rc_service_mark (tmp, RC_SERVICE_COLDPLUGGED); 1114 rc_service_mark (tmp, RC_SERVICE_COLDPLUGGED);
1072 CHAR_FREE (tmp); 1115 CHAR_FREE (tmp);
1073 } 1116 }
1074 rc_strlist_free (start_services); 1117 closedir (dp);
1118 }
1075#endif 1119#endif
1076 1120
1077 /* The mice are a little more tricky. 1121 /* The mice are a little more tricky.
1078 If we coldplug anything else, we'll probably do it here. */ 1122 If we coldplug anything else, we'll probably do it here. */
1079 start_services = rc_ls_dir ("/dev", 0); 1123 if ((dp == opendir ("/dev"))) {
1080 STRLIST_FOREACH (start_services, service, i) { 1124 while ((d = readdir (dp))) {
1081 if (strncmp (service, "psm", 3) == 0 || 1125 if (strncmp (d->d_name, "psm", 3) == 0 ||
1082 strncmp (service, "ums", 3) == 0) 1126 strncmp (d->d_name, "ums", 3) == 0)
1083 { 1127 {
1084 char *p = service + 3; 1128 char *p = d->d_name + 3;
1085 if (p && isdigit (*p)) { 1129 if (p && isdigit (*p)) {
1086 j = (strlen ("moused.") + strlen (service) + 1); 1130 i = (strlen ("moused.") + strlen (d->d_name) + 1);
1087 tmp = rc_xmalloc (sizeof (char *) * j); 1131 tmp = xmalloc (sizeof (char) * i);
1088 snprintf (tmp, j, "moused.%s", service); 1132 snprintf (tmp, i, "moused.%s", d->d_name);
1089 if (rc_service_exists (tmp) && rc_service_plugable (tmp)) 1133 if (rc_service_exists (tmp) && rc_service_plugable (tmp))
1090 rc_service_mark (tmp, RC_SERVICE_COLDPLUGGED); 1134 rc_service_mark (tmp, RC_SERVICE_COLDPLUGGED);
1091 CHAR_FREE (tmp); 1135 CHAR_FREE (tmp);
1136 }
1092 } 1137 }
1093 } 1138 }
1139 closedir (dp);
1094 } 1140 }
1095 rc_strlist_free (start_services);
1096 start_services = NULL;
1097 } 1141 }
1098#endif 1142#endif
1099 1143
1100 /* Build a list of all services to stop and then work out the 1144 /* Build a list of all services to stop and then work out the
1101 correct order for stopping them */ 1145 correct order for stopping them */
1102 stop_services = rc_ls_dir (RC_SVCDIR_STARTING, RC_LS_INITD); 1146 stop_services = rc_services_in_state (RC_SERVICE_STARTING);
1103 1147
1104 tmplist = rc_ls_dir (RC_SVCDIR_INACTIVE, RC_LS_INITD); 1148 tmplist = rc_services_in_state (RC_SERVICE_INACTIVE);
1105 rc_strlist_join (&stop_services, tmplist); 1149 rc_strlist_join (&stop_services, tmplist);
1106 rc_strlist_free (tmplist); 1150 rc_strlist_free (tmplist);
1107 1151
1108 tmplist = rc_ls_dir (RC_SVCDIR_STARTED, RC_LS_INITD); 1152 tmplist = rc_services_in_state (RC_SERVICE_STARTED);
1109 rc_strlist_join (&stop_services, tmplist); 1153 rc_strlist_join (&stop_services, tmplist);
1110 rc_strlist_free (tmplist); 1154 rc_strlist_free (tmplist);
1111 1155
1112 types = NULL; 1156 types = NULL;
1113 rc_strlist_add (&types, "ineed"); 1157 rc_strlist_add (&types, "ineed");
1114 rc_strlist_add (&types, "iuse"); 1158 rc_strlist_add (&types, "iuse");
1115 rc_strlist_add (&types, "iafter"); 1159 rc_strlist_add (&types, "iafter");
1116 1160
1117 deporder = rc_deptree_depends (deptree, types, stop_services, 1161 deporder = rc_deptree_depends (deptree, types, stop_services,
1118 runlevel, depoptions | RC_DEP_STOP); 1162 runlevel, depoptions | RC_DEP_STOP);
1119 1163
1120 rc_strlist_free (stop_services); 1164 rc_strlist_free (stop_services);
1121 rc_strlist_free (types); 1165 rc_strlist_free (types);
1122 types = NULL; 1166 types = NULL;
1123 stop_services = deporder; 1167 stop_services = deporder;
1124 deporder = NULL; 1168 deporder = NULL;
1125 rc_strlist_reverse (stop_services); 1169 rc_strlist_reverse (stop_services);
1126 1170
1127 /* Load our list of coldplugged services */ 1171 /* Load our list of coldplugged services */
1128 coldplugged_services = rc_ls_dir (RC_SVCDIR_COLDPLUGGED, RC_LS_INITD); 1172 coldplugged_services = rc_services_in_state (RC_SERVICE_COLDPLUGGED);
1129 1173
1130 /* Load our start services now. 1174 /* Load our start services now.
1131 We have different rules dependent on runlevel. */ 1175 We have different rules dependent on runlevel. */
1132 if (newlevel && strcmp (newlevel, bootlevel) == 0) { 1176 if (newlevel && strcmp (newlevel, bootlevel) == 0) {
1133 if (coldplugged_services) { 1177 if (coldplugged_services) {
1136 printf (" %s", service); 1180 printf (" %s", service);
1137 rc_strlist_add (&start_services, service); 1181 rc_strlist_add (&start_services, service);
1138 } 1182 }
1139 printf ("\n"); 1183 printf ("\n");
1140 } 1184 }
1141 tmp = rc_strcatpaths (RC_RUNLEVELDIR, newlevel ? newlevel : runlevel, 1185 tmplist = rc_services_in_runlevel (newlevel ? newlevel : runlevel);
1142 (char *) NULL);
1143 tmplist = rc_ls_dir (tmp, RC_LS_INITD);
1144 rc_strlist_join (&start_services, tmplist); 1186 rc_strlist_join (&start_services, tmplist);
1145 rc_strlist_free (tmplist); 1187 rc_strlist_free (tmplist);
1146 CHAR_FREE (tmp);
1147 } else { 1188 } else {
1148 /* Store our list of coldplugged services */ 1189 /* Store our list of coldplugged services */
1149 tmplist = rc_ls_dir (RC_SVCDIR_COLDPLUGGED, RC_LS_INITD); 1190 tmplist = rc_services_in_state (RC_SERVICE_COLDPLUGGED);
1150 rc_strlist_join (&coldplugged_services, tmplist); 1191 rc_strlist_join (&coldplugged_services, tmplist);
1151 rc_strlist_free (tmplist); 1192 rc_strlist_free (tmplist);
1152 if (strcmp (newlevel ? newlevel : runlevel, RC_LEVEL_SINGLE) != 0 && 1193 if (strcmp (newlevel ? newlevel : runlevel, RC_LEVEL_SINGLE) != 0 &&
1153 strcmp (newlevel ? newlevel : runlevel, RC_LEVEL_SHUTDOWN) != 0 && 1194 strcmp (newlevel ? newlevel : runlevel, RC_LEVEL_SHUTDOWN) != 0 &&
1154 strcmp (newlevel ? newlevel : runlevel, RC_LEVEL_REBOOT) != 0) 1195 strcmp (newlevel ? newlevel : runlevel, RC_LEVEL_REBOOT) != 0)
1158 rc_strlist_join (&start_services, tmplist); 1199 rc_strlist_join (&start_services, tmplist);
1159 rc_strlist_free (tmplist); 1200 rc_strlist_free (tmplist);
1160 tmplist = rc_services_in_runlevel (newlevel ? newlevel : runlevel); 1201 tmplist = rc_services_in_runlevel (newlevel ? newlevel : runlevel);
1161 rc_strlist_join (&start_services, tmplist); 1202 rc_strlist_join (&start_services, tmplist);
1162 rc_strlist_free (tmplist); 1203 rc_strlist_free (tmplist);
1163 1204
1164 STRLIST_FOREACH (coldplugged_services, service, i) 1205 STRLIST_FOREACH (coldplugged_services, service, i)
1165 rc_strlist_add (&start_services, service); 1206 rc_strlist_add (&start_services, service);
1166 1207
1167 } 1208 }
1168 } 1209 }
1187 1228
1188 /* We always stop the service when in these runlevels */ 1229 /* We always stop the service when in these runlevels */
1189 if (going_down) { 1230 if (going_down) {
1190 pid_t pid = rc_service_stop (service); 1231 pid_t pid = rc_service_stop (service);
1191 if (pid > 0 && ! rc_env_bool ("RC_PARALLEL")) 1232 if (pid > 0 && ! rc_env_bool ("RC_PARALLEL"))
1192 rc_waitpid (pid); 1233 wait_pid (pid);
1193 continue; 1234 continue;
1194 } 1235 }
1195 1236
1196 /* If we're in the start list then don't bother stopping us */ 1237 /* If we're in the start list then don't bother stopping us */
1197 STRLIST_FOREACH (start_services, svc1, j) 1238 STRLIST_FOREACH (start_services, svc1, j)
1205 int len; 1246 int len;
1206 if (! newlevel) 1247 if (! newlevel)
1207 continue; 1248 continue;
1208 1249
1209 len = strlen (service) + strlen (runlevel) + 2; 1250 len = strlen (service) + strlen (runlevel) + 2;
1210 tmp = rc_xmalloc (sizeof (char *) * len); 1251 tmp = xmalloc (sizeof (char) * len);
1211 snprintf (tmp, len, "%s.%s", service, runlevel); 1252 snprintf (tmp, len, "%s.%s", service, runlevel);
1212 conf = rc_strcatpaths (RC_CONFDIR, tmp, (char *) NULL); 1253 conf = rc_strcatpaths (RC_CONFDIR, tmp, (char *) NULL);
1213 found = rc_exists (conf); 1254 found = exists (conf);
1214 CHAR_FREE (conf); 1255 CHAR_FREE (conf);
1215 CHAR_FREE (tmp); 1256 CHAR_FREE (tmp);
1216 if (! found) { 1257 if (! found) {
1217 len = strlen (service) + strlen (newlevel) + 2; 1258 len = strlen (service) + strlen (newlevel) + 2;
1218 tmp = rc_xmalloc (sizeof (char *) * len); 1259 tmp = xmalloc (sizeof (char) * len);
1219 snprintf (tmp, len, "%s.%s", service, newlevel); 1260 snprintf (tmp, len, "%s.%s", service, newlevel);
1220 conf = rc_strcatpaths (RC_CONFDIR, tmp, (char *) NULL); 1261 conf = rc_strcatpaths (RC_CONFDIR, tmp, (char *) NULL);
1221 found = rc_exists (conf); 1262 found = exists (conf);
1222 CHAR_FREE (conf); 1263 CHAR_FREE (conf);
1223 CHAR_FREE (tmp); 1264 CHAR_FREE (tmp);
1224 if (!found) 1265 if (!found)
1225 continue; 1266 continue;
1226 } 1267 }
1232 1273
1233 /* We got this far! Or last check is to see if any any service that 1274 /* We got this far! Or last check is to see if any any service that
1234 going to be started depends on us */ 1275 going to be started depends on us */
1235 rc_strlist_add (&stopdeps, service); 1276 rc_strlist_add (&stopdeps, service);
1236 deporder = rc_deptree_depends (deptree, types, stopdeps, 1277 deporder = rc_deptree_depends (deptree, types, stopdeps,
1237 runlevel, RC_DEP_STRICT); 1278 runlevel, RC_DEP_STRICT);
1238 rc_strlist_free (stopdeps); 1279 rc_strlist_free (stopdeps);
1239 stopdeps = NULL; 1280 stopdeps = NULL;
1240 found = false; 1281 found = false;
1241 STRLIST_FOREACH (deporder, svc1, j) { 1282 STRLIST_FOREACH (deporder, svc1, j) {
1242 STRLIST_FOREACH (start_services, svc2, k) 1283 STRLIST_FOREACH (start_services, svc2, k)
1252 1293
1253 /* After all that we can finally stop the blighter! */ 1294 /* After all that we can finally stop the blighter! */
1254 if (! found) { 1295 if (! found) {
1255 pid_t pid = rc_service_stop (service); 1296 pid_t pid = rc_service_stop (service);
1256 if (pid > 0 && ! rc_env_bool ("RC_PARALLEL")) 1297 if (pid > 0 && ! rc_env_bool ("RC_PARALLEL"))
1257 rc_waitpid (pid); 1298 wait_pid (pid);
1258 } 1299 }
1259 } 1300 }
1260 rc_strlist_free (types); 1301 rc_strlist_free (types);
1261 types = NULL; 1302 types = NULL;
1262 1303
1270 1311
1271 /* Store the new runlevel */ 1312 /* Store the new runlevel */
1272 if (newlevel) { 1313 if (newlevel) {
1273 rc_runlevel_set (newlevel); 1314 rc_runlevel_set (newlevel);
1274 free (runlevel); 1315 free (runlevel);
1275 runlevel = rc_xstrdup (newlevel); 1316 runlevel = xstrdup (newlevel);
1276 setenv ("RC_SOFTLEVEL", runlevel, 1); 1317 setenv ("RC_SOFTLEVEL", runlevel, 1);
1277 } 1318 }
1278 1319
1279 /* Run the halt script if needed */ 1320 /* Run the halt script if needed */
1280 if (strcmp (runlevel, RC_LEVEL_SHUTDOWN) == 0 || 1321 if (strcmp (runlevel, RC_LEVEL_SHUTDOWN) == 0 ||
1285 applet, HALTSH, strerror (errno)); 1326 applet, HALTSH, strerror (errno));
1286 } 1327 }
1287 1328
1288 /* Single user is done now */ 1329 /* Single user is done now */
1289 if (strcmp (runlevel, RC_LEVEL_SINGLE) == 0) { 1330 if (strcmp (runlevel, RC_LEVEL_SINGLE) == 0) {
1290 if (rc_exists (INTERACTIVE)) 1331 if (exists (INTERACTIVE))
1291 unlink (INTERACTIVE); 1332 unlink (INTERACTIVE);
1292 sulogin (false); 1333 sulogin (false);
1293 } 1334 }
1294 1335
1295 mkdir (RC_STARTING, 0755); 1336 mkdir (RC_STARTING, 0755);
1302 /* Order the services to start */ 1343 /* Order the services to start */
1303 rc_strlist_add (&types, "ineed"); 1344 rc_strlist_add (&types, "ineed");
1304 rc_strlist_add (&types, "iuse"); 1345 rc_strlist_add (&types, "iuse");
1305 rc_strlist_add (&types, "iafter"); 1346 rc_strlist_add (&types, "iafter");
1306 deporder = rc_deptree_depends (deptree, types, start_services, 1347 deporder = rc_deptree_depends (deptree, types, start_services,
1307 runlevel, depoptions | RC_DEP_START); 1348 runlevel, depoptions | RC_DEP_START);
1308 rc_strlist_free (types); 1349 rc_strlist_free (types);
1309 types = NULL; 1350 types = NULL;
1310 rc_strlist_free (start_services); 1351 rc_strlist_free (start_services);
1311 start_services = deporder; 1352 start_services = deporder;
1312 deporder = NULL; 1353 deporder = NULL;
1354 /* Remember the pid if we're running in parallel */ 1395 /* Remember the pid if we're running in parallel */
1355 if ((pid = rc_service_start (service))) 1396 if ((pid = rc_service_start (service)))
1356 add_pid (pid); 1397 add_pid (pid);
1357 1398
1358 if (! rc_env_bool ("RC_PARALLEL")) { 1399 if (! rc_env_bool ("RC_PARALLEL")) {
1359 rc_waitpid (pid); 1400 wait_pid (pid);
1360 remove_pid (pid); 1401 remove_pid (pid);
1361 } 1402 }
1362 } 1403 }
1363 } 1404 }
1364 1405
1383 1424
1384 /* Store our interactive status for boot */ 1425 /* Store our interactive status for boot */
1385 if (interactive && strcmp (runlevel, bootlevel) == 0) 1426 if (interactive && strcmp (runlevel, bootlevel) == 0)
1386 mark_interactive (); 1427 mark_interactive ();
1387 else { 1428 else {
1388 if (rc_exists (INTERACTIVE)) 1429 if (exists (INTERACTIVE))
1389 unlink (INTERACTIVE); 1430 unlink (INTERACTIVE);
1390 } 1431 }
1391 1432
1392 return (EXIT_SUCCESS); 1433 return (EXIT_SUCCESS);
1393} 1434}

Legend:
Removed from v.2978  
changed lines
  Added in v.3036

  ViewVC Help
Powered by ViewVC 1.1.20