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

Diff of /trunk/src/runscript.c

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

Revision 2666 Revision 2669
34#define SELINUX_LIB RC_LIBDIR "/runscript_selinux.so" 34#define SELINUX_LIB RC_LIBDIR "/runscript_selinux.so"
35 35
36#define PREFIX_LOCK RC_SVCDIR "/prefix.lock" 36#define PREFIX_LOCK RC_SVCDIR "/prefix.lock"
37 37
38static char *applet = NULL; 38static char *applet = NULL;
39static char *service = NULL;
39static char *exclusive = NULL; 40static char *exclusive = NULL;
40static char *mtime_test = NULL; 41static char *mtime_test = NULL;
41static rc_depinfo_t *deptree = NULL; 42static rc_depinfo_t *deptree = NULL;
42static char **services = NULL; 43static char **services = NULL;
43static char **svclist = NULL; 44static char **svclist = NULL;
191 } 192 }
192 193
193 return (true); 194 return (true);
194} 195}
195 196
196static void uncoldplug (char *service) 197static void uncoldplug ()
197{ 198{
198 char *cold = rc_strcatpaths (RC_SVCDIR "coldplugged", basename (service), 199 char *cold = rc_strcatpaths (RC_SVCDIR "coldplugged", applet, (char *) NULL);
199 (char *) NULL);
200 if (rc_exists (cold) && unlink (cold) != 0) 200 if (rc_exists (cold) && unlink (cold) != 0)
201 eerror ("%s: unlink `%s': %s", applet, cold, strerror (errno)); 201 eerror ("%s: unlink `%s': %s", applet, cold, strerror (errno));
202 free (cold); 202 free (cold);
203} 203}
204 204
205static void start_services (char **list) {
206 bool inactive;
207 char *svc;
208 int i;
209
210 if (! list)
211 return;
212
213 inactive = rc_service_state (service, rc_service_inactive);
214 if (! inactive)
215 inactive = rc_service_state (service, rc_service_wasinactive);
216
217 if (inactive ||
218 rc_service_state (service, rc_service_starting) ||
219 rc_service_state (service, rc_service_started))
220 {
221 STRLIST_FOREACH (list, svc, i) {
222 if (rc_service_state (svc, rc_service_stopped)) {
223 if (inactive) {
224 rc_schedule_start_service (service, svc);
225 ewarn ("WARNING: %s is scheduled to started when %s has started",
226 svc, applet);
227 } else
228 rc_start_service (svc);
229 }
230 }
231 }
232}
233
205static void cleanup (void) 234static void cleanup (void)
206{ 235{
207 if (prefix_locked) 236 if (prefix_locked)
208 unlink (PREFIX_LOCK); 237 unlink (PREFIX_LOCK);
209 238
211 eclose (); 240 eclose ();
212 241
213 if (hook_out) 242 if (hook_out)
214 rc_plugin_run (hook_out, applet); 243 rc_plugin_run (hook_out, applet);
215 rc_plugin_unload (); 244 rc_plugin_unload ();
245
246 if (restart_services ) {
247 start_services (restart_services);
248 rc_strlist_free (restart_services);
249 }
216 250
217 rc_free_deptree (deptree); 251 rc_free_deptree (deptree);
218 rc_strlist_free (services); 252 rc_strlist_free (services);
219 rc_strlist_free (types); 253 rc_strlist_free (types);
220 rc_strlist_free (svclist); 254 rc_strlist_free (svclist);
221 rc_strlist_free (providelist); 255 rc_strlist_free (providelist);
222 rc_strlist_free (restart_services);
223 rc_strlist_free (need_services); 256 rc_strlist_free (need_services);
224 rc_strlist_free (tmplist); 257 rc_strlist_free (tmplist);
225 free (ibsave); 258 free (ibsave);
226 259
227 if (in_control ()) { 260 if (in_control ()) {
293 } 326 }
294 327
295 return (ret); 328 return (ret);
296} 329}
297 330
298static bool svc_exec (const char *service, const char *arg1, const char *arg2) 331static bool svc_exec (const char *arg1, const char *arg2)
299{ 332{
300 bool execok; 333 bool execok;
301 int stdout_pipes[2]; 334 int stdout_pipes[2];
302 int stderr_pipes[2]; 335 int stderr_pipes[2];
303 336
437 signal (SIGCHLD, handle_signal); 470 signal (SIGCHLD, handle_signal);
438 471
439 return (execok); 472 return (execok);
440} 473}
441 474
442static rc_service_state_t svc_status (const char *service) 475static rc_service_state_t svc_status ()
443{ 476{
444 char status[10]; 477 char status[10];
445 int (*e) (const char *fmt, ...) = &einfo; 478 int (*e) (const char *fmt, ...) = &einfo;
446 479
447 rc_service_state_t retval = rc_service_stopped; 480 rc_service_state_t retval = rc_service_stopped;
470 503
471 e ("status: %s", status); 504 e ("status: %s", status);
472 return (retval); 505 return (retval);
473} 506}
474 507
475static void make_exclusive (const char *service) 508static void make_exclusive ()
476{ 509{
477 char *path; 510 char *path;
478 int i; 511 int i;
479 512
480 /* We create a fifo so that other services can wait until we complete */ 513 /* We create a fifo so that other services can wait until we complete */
516 mtime_test = NULL; 549 mtime_test = NULL;
517} 550}
518 551
519static void get_started_services () 552static void get_started_services ()
520{ 553{
521 char *service; 554 char *svc;
522 int i; 555 int i;
523 556
524 rc_strlist_free (tmplist); 557 rc_strlist_free (tmplist);
525 tmplist = rc_services_in_state (rc_service_inactive); 558 tmplist = rc_services_in_state (rc_service_inactive);
526 559
527 rc_strlist_free (restart_services); 560 rc_strlist_free (restart_services);
528 restart_services = rc_services_in_state (rc_service_started); 561 restart_services = rc_services_in_state (rc_service_started);
529 562
530 STRLIST_FOREACH (tmplist, service, i) 563 STRLIST_FOREACH (tmplist, svc, i)
531 restart_services = rc_strlist_addsort (restart_services, service); 564 restart_services = rc_strlist_addsort (restart_services, svc);
532 565
533 rc_strlist_free (tmplist); 566 rc_strlist_free (tmplist);
534 tmplist = NULL; 567 tmplist = NULL;
535} 568}
536 569
537static void svc_start (const char *service, bool deps) 570static void svc_start (bool deps)
538{ 571{
539 bool started; 572 bool started;
540 bool background = false; 573 bool background = false;
541 char *svc; 574 char *svc;
542 char *svc2; 575 char *svc2;
693 } 726 }
694 727
695 if (ibsave) 728 if (ibsave)
696 setenv ("IN_BACKGROUND", ibsave, 1); 729 setenv ("IN_BACKGROUND", ibsave, 1);
697 rc_plugin_run (rc_hook_service_start_now, applet); 730 rc_plugin_run (rc_hook_service_start_now, applet);
698 started = svc_exec (service, "start", NULL); 731 started = svc_exec ("start", NULL);
699 if (ibsave) 732 if (ibsave)
700 unsetenv ("IN_BACKGROUND"); 733 unsetenv ("IN_BACKGROUND");
701 734
702 if (in_control ()) { 735 if (in_control ()) {
703 if (! started) { 736 if (! started) {
749 782
750 hook_out = 0; 783 hook_out = 0;
751 rc_plugin_run (rc_hook_service_start_out, applet); 784 rc_plugin_run (rc_hook_service_start_out, applet);
752} 785}
753 786
754static void svc_stop (const char *service, bool deps) 787static void svc_stop (bool deps)
755{ 788{
756 bool stopped; 789 bool stopped;
757 790
758 hook_out = rc_hook_service_stop_out; 791 hook_out = rc_hook_service_stop_out;
759 792
855 } 888 }
856 889
857 if (ibsave) 890 if (ibsave)
858 setenv ("IN_BACKGROUND", ibsave, 1); 891 setenv ("IN_BACKGROUND", ibsave, 1);
859 rc_plugin_run (rc_hook_service_stop_now, applet); 892 rc_plugin_run (rc_hook_service_stop_now, applet);
860 stopped = svc_exec (service, "stop", NULL); 893 stopped = svc_exec ("stop", NULL);
861 if (ibsave) 894 if (ibsave)
862 unsetenv ("IN_BACKGROUND"); 895 unsetenv ("IN_BACKGROUND");
863 896
864 if (! in_control ()) { 897 if (! in_control ()) {
865 rc_plugin_run (rc_hook_service_stop_done, applet); 898 rc_plugin_run (rc_hook_service_stop_done, applet);
884 rc_plugin_run (rc_hook_service_stop_done, applet); 917 rc_plugin_run (rc_hook_service_stop_done, applet);
885 hook_out = 0; 918 hook_out = 0;
886 rc_plugin_run (rc_hook_service_stop_out, applet); 919 rc_plugin_run (rc_hook_service_stop_out, applet);
887} 920}
888 921
889static void svc_restart (const char *service, bool deps) 922static void svc_restart (bool deps)
890{ 923{
891 char *svc;
892 int i;
893 bool inactive = false;
894
895 /* This is hairly and a better way needs to be found I think! 924 /* This is hairly and a better way needs to be found I think!
896 The issue is this - openvpn need net and dns. net can restart 925 The issue is this - openvpn need net and dns. net can restart
897 dns via resolvconf, so you could have openvpn trying to restart dnsmasq 926 dns via resolvconf, so you could have openvpn trying to restart dnsmasq
898 which in turn is waiting on net which in turn is waiting on dnsmasq. 927 which in turn is waiting on net which in turn is waiting on dnsmasq.
899 The work around is for resolvconf to restart it's services with --nodeps 928 The work around is for resolvconf to restart it's services with --nodeps
901 our status is invalid. 930 our status is invalid.
902 One workaround would be to introduce a new status, or status locking. */ 931 One workaround would be to introduce a new status, or status locking. */
903 if (! deps) { 932 if (! deps) {
904 if (rc_service_state (service, rc_service_started) || 933 if (rc_service_state (service, rc_service_started) ||
905 rc_service_state (service, rc_service_inactive)) 934 rc_service_state (service, rc_service_inactive))
906 svc_exec (service, "stop", "start"); 935 svc_exec ("stop", "start");
907 else 936 else
908 svc_exec (service, "start", NULL); 937 svc_exec ("start", NULL);
909 return; 938 return;
910 } 939 }
911 940
912 if (! rc_service_state (service, rc_service_stopped)) { 941 if (! rc_service_state (service, rc_service_stopped)) {
913 get_started_services (); 942 get_started_services ();
914 svc_stop (service, deps); 943 svc_stop (deps);
915 944
916 /* Flush our buffered output if any */ 945 /* Flush our buffered output if any */
917 eflush (); 946 eflush ();
918 } 947 }
919 948
920 svc_start (service, deps); 949 svc_start (deps);
921 950 start_services (restart_services);
922 inactive = rc_service_state (service, rc_service_inactive); 951 rc_strlist_free (restart_services);
923 if (! inactive) 952 restart_services = NULL;
924 inactive = rc_service_state (service, rc_service_wasinactive);
925
926 if (inactive ||
927 rc_service_state (service, rc_service_starting) ||
928 rc_service_state (service, rc_service_started))
929 {
930 STRLIST_FOREACH (restart_services, svc, i) {
931 if (rc_service_state (svc, rc_service_stopped)) {
932 if (inactive) {
933 rc_schedule_start_service (service, svc);
934 ewarn ("WARNING: %s is scheduled to started when %s has started",
935 svc, applet);
936 } else
937 rc_start_service (svc);
938 }
939 }
940 }
941} 953}
942 954
943#define getoptstring "dCDNqvh" 955#define getoptstring "dCDNqvh"
944static struct option longopts[] = { 956static struct option longopts[] = {
945 { "debug", 0, NULL, 'd'}, 957 { "debug", 0, NULL, 'd'},
953}; 965};
954// #include "_usage.c" 966// #include "_usage.c"
955 967
956int main (int argc, char **argv) 968int main (int argc, char **argv)
957{ 969{
958 char *service = argv[1];
959 int i; 970 int i;
960 bool deps = true; 971 bool deps = true;
961 bool doneone = false; 972 bool doneone = false;
962 char pid[16]; 973 char pid[16];
963 int retval; 974 int retval;
964 char c; 975 char c;
965 976
977 service = argv[1];
966 /* Show help if insufficient args */ 978 /* Show help if insufficient args */
967 if (argc < 3) { 979 if (argc < 3) {
968 execl (RCSCRIPT_HELP, RCSCRIPT_HELP, service, (char *) NULL); 980 execl (RCSCRIPT_HELP, RCSCRIPT_HELP, service, (char *) NULL);
969 eerrorx ("%s: failed to exec `" RCSCRIPT_HELP "': %s", 981 eerrorx ("%s: failed to exec `" RCSCRIPT_HELP "': %s",
970 applet, strerror (errno)); 982 applet, strerror (errno));
1135 doneone = true; 1147 doneone = true;
1136 if (strcmp (optarg, "conditionalrestart") == 0 || 1148 if (strcmp (optarg, "conditionalrestart") == 0 ||
1137 strcmp (optarg, "condrestart") == 0) 1149 strcmp (optarg, "condrestart") == 0)
1138 { 1150 {
1139 if (rc_service_state (service, rc_service_started)) 1151 if (rc_service_state (service, rc_service_started))
1140 svc_restart (service, deps); 1152 svc_restart (deps);
1141 } 1153 }
1142 else if (strcmp (optarg, "restart") == 0) 1154 else if (strcmp (optarg, "restart") == 0)
1143 svc_restart (service, deps); 1155 svc_restart (deps);
1144 else if (strcmp (optarg, "start") == 0) 1156 else if (strcmp (optarg, "start") == 0)
1145 svc_start (service, deps); 1157 svc_start (deps);
1146 else if (strcmp (optarg, "status") == 0) { 1158 else if (strcmp (optarg, "status") == 0) {
1147 rc_service_state_t r = svc_status (service); 1159 rc_service_state_t r = svc_status (service);
1148 retval = (int) r; 1160 retval = (int) r;
1149 } else if (strcmp (optarg, "stop") == 0) { 1161 } else if (strcmp (optarg, "stop") == 0) {
1150 if (in_background) 1162 if (in_background)
1151 get_started_services (); 1163 get_started_services ();
1152 1164
1153 svc_stop (service, deps); 1165 svc_stop (deps);
1154 1166
1155 if (! in_background && 1167 if (! in_background &&
1156 ! rc_runlevel_stopping () && 1168 ! rc_runlevel_stopping () &&
1157 rc_service_state (service, rc_service_stopped)) 1169 rc_service_state (service, rc_service_stopped))
1158 uncoldplug (applet); 1170 uncoldplug ();
1159 1171
1160 if (in_background && 1172 if (in_background &&
1161 rc_service_state (service, rc_service_inactive)) 1173 rc_service_state (service, rc_service_inactive))
1162 { 1174 {
1163 char *svc; 1175 char *svc;
1167 rc_schedule_start_service (service, svc); 1179 rc_schedule_start_service (service, svc);
1168 } 1180 }
1169 } else if (strcmp (optarg, "zap") == 0) { 1181 } else if (strcmp (optarg, "zap") == 0) {
1170 einfo ("Manually resetting %s to stopped state", applet); 1182 einfo ("Manually resetting %s to stopped state", applet);
1171 rc_mark_service (applet, rc_service_stopped); 1183 rc_mark_service (applet, rc_service_stopped);
1172 uncoldplug (applet); 1184 uncoldplug ();
1173 } else if (strcmp (optarg, "help") == 0) { 1185 } else if (strcmp (optarg, "help") == 0) {
1174 execl (RCSCRIPT_HELP, RCSCRIPT_HELP, service, "help", (char *) NULL); 1186 execl (RCSCRIPT_HELP, RCSCRIPT_HELP, service, "help", (char *) NULL);
1175 eerrorx ("%s: failed to exec `" RCSCRIPT_HELP "': %s", 1187 eerrorx ("%s: failed to exec `" RCSCRIPT_HELP "': %s",
1176 applet, strerror (errno)); 1188 applet, strerror (errno));
1177 }else 1189 }else
1178 svc_exec (service, optarg, NULL); 1190 svc_exec (optarg, NULL);
1179 1191
1180 /* Flush our buffered output if any */ 1192 /* Flush our buffered output if any */
1181 eflush (); 1193 eflush ();
1182 1194
1183 /* We should ensure this list is empty after an action is done */ 1195 /* We should ensure this list is empty after an action is done */

Legend:
Removed from v.2666  
changed lines
  Added in v.2669

  ViewVC Help
Powered by ViewVC 1.1.20