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

Diff of /trunk/src/rc.c

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

Revision 2993 Revision 2999
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>
329 if (runscript_pid && sscanf (runscript_pid, "%d", &pid) == 1) 330 if (runscript_pid && sscanf (runscript_pid, "%d", &pid) == 1)
330 if (kill (pid, SIGHUP) != 0) 331 if (kill (pid, SIGHUP) != 0)
331 eerror ("%s: failed to signal parent %d: %s", 332 eerror ("%s: failed to signal parent %d: %s",
332 applet, pid, strerror (errno)); 333 applet, pid, strerror (errno));
333 334
334 /* Remove the exclsive time test. This ensures that it's not 335 /* Remove the exclusive time test. This ensures that it's not
335 in control as well */ 336 in control as well */
336 l = strlen (RC_SVCDIR "exclusive") + 337 l = strlen (RC_SVCDIR "exclusive") +
337 strlen (svcname) + 338 strlen (svcname) +
338 strlen (runscript_pid) + 339 strlen (runscript_pid) +
339 4; 340 4;
418static char read_key (bool block) 419static char read_key (bool block)
419{ 420{
420 struct termios termios; 421 struct termios termios;
421 char c = 0; 422 char c = 0;
422 int fd = fileno (stdin); 423 int fd = fileno (stdin);
423 424
424 if (! isatty (fd)) 425 if (! isatty (fd))
425 return (false); 426 return (false);
426 427
427 /* Now save our terminal settings. We need to restore them at exit as we 428 /* Now save our terminal settings. We need to restore them at exit as we
428 will be changing it for non-blocking reads for Interactive */ 429 will be changing it for non-blocking reads for Interactive */
734 bool interactive = false; 735 bool interactive = false;
735 int depoptions = RC_DEP_STRICT | RC_DEP_TRACE; 736 int depoptions = RC_DEP_STRICT | RC_DEP_TRACE;
736 char ksoftbuffer [PATH_MAX]; 737 char ksoftbuffer [PATH_MAX];
737 char pidstr[6]; 738 char pidstr[6];
738 int opt; 739 int opt;
740 DIR *dp;
741 struct dirent *d;
739 742
740 atexit (cleanup); 743 atexit (cleanup);
741 if (argv[0]) 744 if (argv[0])
742 applet = rc_xstrdup (basename (argv[0])); 745 applet = rc_xstrdup (basename (argv[0]));
743 746
1030#ifdef __linux__ 1033#ifdef __linux__
1031 /* udev likes to start services before we're ready when it does 1034 /* udev likes to start services before we're ready when it does
1032 its coldplugging thing. runscript knows when we're not ready so it 1035 its coldplugging thing. runscript knows when we're not ready so it
1033 stores a list of coldplugged services in DEVBOOT for us to pick up 1036 stores a list of coldplugged services in DEVBOOT for us to pick up
1034 here when we are ready for them */ 1037 here when we are ready for them */
1035 start_services = rc_ls_dir (DEVBOOT, RC_LS_INITD); 1038 if ((dp = opendir (DEVBOOT))) {
1036 if (start_services) { 1039 while ((d = readdir (dp))) {
1040 if (rc_service_exists (d->d_name) &&
1041 rc_service_plugable (d->d_name))
1042 rc_service_mark (d->d_name, RC_SERVICE_COLDPLUGGED);
1043 }
1044 closedir (dp);
1037 rc_rm_dir (DEVBOOT, true); 1045 rc_rm_dir (DEVBOOT, true);
1038
1039 STRLIST_FOREACH (start_services, service, i)
1040 if (rc_service_plugable (service))
1041 rc_service_mark (service, RC_SERVICE_COLDPLUGGED);
1042 /* We need to dump this list now.
1043 This may seem redunant, but only Linux needs this and saves on
1044 code bloat. */
1045 rc_strlist_free (start_services);
1046 start_services = NULL;
1047 } 1046 }
1048#else 1047#else
1049 /* BSD's on the other hand populate /dev automagically and use devd. 1048 /* BSD's on the other hand populate /dev automagically and use devd.
1050 The only downside of this approach and ours is that we have to hard code 1049 The only downside of this approach and ours is that we have to hard code
1051 the device node to the init script to simulate the coldplug into 1050 the device node to the init script to simulate the coldplug into
1055 strcmp (runlevel, RC_LEVEL_SYSINIT) == 0) && 1054 strcmp (runlevel, RC_LEVEL_SYSINIT) == 0) &&
1056 rc_env_bool ("RC_COLDPLUG")) 1055 rc_env_bool ("RC_COLDPLUG"))
1057 { 1056 {
1058#if defined(__DragonFly__) || defined(__FreeBSD__) 1057#if defined(__DragonFly__) || defined(__FreeBSD__)
1059 /* The net interfaces are easy - they're all in net /dev/net :) */ 1058 /* The net interfaces are easy - they're all in net /dev/net :) */
1060 start_services = rc_ls_dir ("/dev/net", 0); 1059 if ((dp = opendir ("/dev/net"))) {
1061 STRLIST_FOREACH (start_services, service, i) { 1060 while ((d = readdir (dp))) {
1062 j = (strlen ("net.") + strlen (service) + 1); 1061 i = (strlen ("net.") + strlen (d->d_name) + 1);
1063 tmp = rc_xmalloc (sizeof (char *) * j); 1062 tmp = rc_xmalloc (sizeof (char *) * i);
1064 snprintf (tmp, j, "net.%s", service); 1063 snprintf (tmp, i, "net.%s", d->d_name);
1065 if (rc_service_exists (tmp) && rc_service_plugable (tmp)) 1064 if (rc_service_exists (d->d_name) &&
1065 rc_service_plugable (d->d_name))
1066 rc_service_mark (tmp, RC_SERVICE_COLDPLUGGED); 1066 rc_service_mark (d->d_name, RC_SERVICE_COLDPLUGGED);
1067 CHAR_FREE (tmp); 1067 CHAR_FREE (tmp);
1068 } 1068 }
1069 rc_strlist_free (start_services); 1069 closedir (dp);
1070 }
1070#endif 1071#endif
1071 1072
1072 /* The mice are a little more tricky. 1073 /* The mice are a little more tricky.
1073 If we coldplug anything else, we'll probably do it here. */ 1074 If we coldplug anything else, we'll probably do it here. */
1074 start_services = rc_ls_dir ("/dev", 0); 1075 if ((dp == opendir ("/dev"))) {
1075 STRLIST_FOREACH (start_services, service, i) { 1076 while ((d = readdir (dp))) {
1076 if (strncmp (service, "psm", 3) == 0 || 1077 if (strncmp (d->d_name, "psm", 3) == 0 ||
1077 strncmp (service, "ums", 3) == 0) 1078 strncmp (d->d_name, "ums", 3) == 0)
1078 { 1079 {
1079 char *p = service + 3; 1080 char *p = d->d_name + 3;
1080 if (p && isdigit (*p)) { 1081 if (p && isdigit (*p)) {
1081 j = (strlen ("moused.") + strlen (service) + 1); 1082 i = (strlen ("moused.") + strlen (d->d_name) + 1);
1082 tmp = rc_xmalloc (sizeof (char *) * j); 1083 tmp = rc_xmalloc (sizeof (char *) * i);
1083 snprintf (tmp, j, "moused.%s", service); 1084 snprintf (tmp, i, "moused.%s", d->d_name);
1084 if (rc_service_exists (tmp) && rc_service_plugable (tmp)) 1085 if (rc_service_exists (tmp) && rc_service_plugable (tmp))
1085 rc_service_mark (tmp, RC_SERVICE_COLDPLUGGED); 1086 rc_service_mark (tmp, RC_SERVICE_COLDPLUGGED);
1086 CHAR_FREE (tmp); 1087 CHAR_FREE (tmp);
1088 }
1087 } 1089 }
1088 } 1090 }
1091 closedir (dp);
1089 } 1092 }
1090 rc_strlist_free (start_services);
1091 start_services = NULL;
1092 } 1093 }
1093#endif 1094#endif
1094 1095
1095 /* Build a list of all services to stop and then work out the 1096 /* Build a list of all services to stop and then work out the
1096 correct order for stopping them */ 1097 correct order for stopping them */
1097 stop_services = rc_ls_dir (RC_SVCDIR_STARTING, RC_LS_INITD); 1098 stop_services = rc_services_in_state (RC_SERVICE_STARTING);
1098 1099
1099 tmplist = rc_ls_dir (RC_SVCDIR_INACTIVE, RC_LS_INITD); 1100 tmplist = rc_services_in_state (RC_SERVICE_INACTIVE);
1100 rc_strlist_join (&stop_services, tmplist); 1101 rc_strlist_join (&stop_services, tmplist);
1101 rc_strlist_free (tmplist); 1102 rc_strlist_free (tmplist);
1102 1103
1103 tmplist = rc_ls_dir (RC_SVCDIR_STARTED, RC_LS_INITD); 1104 tmplist = rc_services_in_state (RC_SERVICE_STARTED);
1104 rc_strlist_join (&stop_services, tmplist); 1105 rc_strlist_join (&stop_services, tmplist);
1105 rc_strlist_free (tmplist); 1106 rc_strlist_free (tmplist);
1106 1107
1107 types = NULL; 1108 types = NULL;
1108 rc_strlist_add (&types, "ineed"); 1109 rc_strlist_add (&types, "ineed");
1109 rc_strlist_add (&types, "iuse"); 1110 rc_strlist_add (&types, "iuse");
1110 rc_strlist_add (&types, "iafter"); 1111 rc_strlist_add (&types, "iafter");
1111 1112
1112 deporder = rc_deptree_depends (deptree, types, stop_services, 1113 deporder = rc_deptree_depends (deptree, types, stop_services,
1113 runlevel, depoptions | RC_DEP_STOP); 1114 runlevel, depoptions | RC_DEP_STOP);
1114 1115
1115 rc_strlist_free (stop_services); 1116 rc_strlist_free (stop_services);
1116 rc_strlist_free (types); 1117 rc_strlist_free (types);
1117 types = NULL; 1118 types = NULL;
1118 stop_services = deporder; 1119 stop_services = deporder;
1119 deporder = NULL; 1120 deporder = NULL;
1120 rc_strlist_reverse (stop_services); 1121 rc_strlist_reverse (stop_services);
1121 1122
1122 /* Load our list of coldplugged services */ 1123 /* Load our list of coldplugged services */
1123 coldplugged_services = rc_ls_dir (RC_SVCDIR_COLDPLUGGED, RC_LS_INITD); 1124 coldplugged_services = rc_services_in_state (RC_SERVICE_COLDPLUGGED);
1124 1125
1125 /* Load our start services now. 1126 /* Load our start services now.
1126 We have different rules dependent on runlevel. */ 1127 We have different rules dependent on runlevel. */
1127 if (newlevel && strcmp (newlevel, bootlevel) == 0) { 1128 if (newlevel && strcmp (newlevel, bootlevel) == 0) {
1128 if (coldplugged_services) { 1129 if (coldplugged_services) {
1131 printf (" %s", service); 1132 printf (" %s", service);
1132 rc_strlist_add (&start_services, service); 1133 rc_strlist_add (&start_services, service);
1133 } 1134 }
1134 printf ("\n"); 1135 printf ("\n");
1135 } 1136 }
1136 tmp = rc_strcatpaths (RC_RUNLEVELDIR, newlevel ? newlevel : runlevel, 1137 tmplist = rc_services_in_runlevel (newlevel ? newlevel : runlevel);
1137 (char *) NULL);
1138 tmplist = rc_ls_dir (tmp, RC_LS_INITD);
1139 rc_strlist_join (&start_services, tmplist); 1138 rc_strlist_join (&start_services, tmplist);
1140 rc_strlist_free (tmplist); 1139 rc_strlist_free (tmplist);
1141 CHAR_FREE (tmp);
1142 } else { 1140 } else {
1143 /* Store our list of coldplugged services */ 1141 /* Store our list of coldplugged services */
1144 tmplist = rc_ls_dir (RC_SVCDIR_COLDPLUGGED, RC_LS_INITD); 1142 tmplist = rc_services_in_state (RC_SERVICE_COLDPLUGGED);
1145 rc_strlist_join (&coldplugged_services, tmplist); 1143 rc_strlist_join (&coldplugged_services, tmplist);
1146 rc_strlist_free (tmplist); 1144 rc_strlist_free (tmplist);
1147 if (strcmp (newlevel ? newlevel : runlevel, RC_LEVEL_SINGLE) != 0 && 1145 if (strcmp (newlevel ? newlevel : runlevel, RC_LEVEL_SINGLE) != 0 &&
1148 strcmp (newlevel ? newlevel : runlevel, RC_LEVEL_SHUTDOWN) != 0 && 1146 strcmp (newlevel ? newlevel : runlevel, RC_LEVEL_SHUTDOWN) != 0 &&
1149 strcmp (newlevel ? newlevel : runlevel, RC_LEVEL_REBOOT) != 0) 1147 strcmp (newlevel ? newlevel : runlevel, RC_LEVEL_REBOOT) != 0)
1153 rc_strlist_join (&start_services, tmplist); 1151 rc_strlist_join (&start_services, tmplist);
1154 rc_strlist_free (tmplist); 1152 rc_strlist_free (tmplist);
1155 tmplist = rc_services_in_runlevel (newlevel ? newlevel : runlevel); 1153 tmplist = rc_services_in_runlevel (newlevel ? newlevel : runlevel);
1156 rc_strlist_join (&start_services, tmplist); 1154 rc_strlist_join (&start_services, tmplist);
1157 rc_strlist_free (tmplist); 1155 rc_strlist_free (tmplist);
1158 1156
1159 STRLIST_FOREACH (coldplugged_services, service, i) 1157 STRLIST_FOREACH (coldplugged_services, service, i)
1160 rc_strlist_add (&start_services, service); 1158 rc_strlist_add (&start_services, service);
1161 1159
1162 } 1160 }
1163 } 1161 }
1227 1225
1228 /* We got this far! Or last check is to see if any any service that 1226 /* We got this far! Or last check is to see if any any service that
1229 going to be started depends on us */ 1227 going to be started depends on us */
1230 rc_strlist_add (&stopdeps, service); 1228 rc_strlist_add (&stopdeps, service);
1231 deporder = rc_deptree_depends (deptree, types, stopdeps, 1229 deporder = rc_deptree_depends (deptree, types, stopdeps,
1232 runlevel, RC_DEP_STRICT); 1230 runlevel, RC_DEP_STRICT);
1233 rc_strlist_free (stopdeps); 1231 rc_strlist_free (stopdeps);
1234 stopdeps = NULL; 1232 stopdeps = NULL;
1235 found = false; 1233 found = false;
1236 STRLIST_FOREACH (deporder, svc1, j) { 1234 STRLIST_FOREACH (deporder, svc1, j) {
1237 STRLIST_FOREACH (start_services, svc2, k) 1235 STRLIST_FOREACH (start_services, svc2, k)
1297 /* Order the services to start */ 1295 /* Order the services to start */
1298 rc_strlist_add (&types, "ineed"); 1296 rc_strlist_add (&types, "ineed");
1299 rc_strlist_add (&types, "iuse"); 1297 rc_strlist_add (&types, "iuse");
1300 rc_strlist_add (&types, "iafter"); 1298 rc_strlist_add (&types, "iafter");
1301 deporder = rc_deptree_depends (deptree, types, start_services, 1299 deporder = rc_deptree_depends (deptree, types, start_services,
1302 runlevel, depoptions | RC_DEP_START); 1300 runlevel, depoptions | RC_DEP_START);
1303 rc_strlist_free (types); 1301 rc_strlist_free (types);
1304 types = NULL; 1302 types = NULL;
1305 rc_strlist_free (start_services); 1303 rc_strlist_free (start_services);
1306 start_services = deporder; 1304 start_services = deporder;
1307 deporder = NULL; 1305 deporder = NULL;

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

  ViewVC Help
Powered by ViewVC 1.1.20