int main(int argc, char **argv) { bool ok = false; char *service; char *exec; int idx = 0; RC_SERVICE state, bit; applet = basename_c(argv[0]); if (argc > 1) service = argv[1]; else service = getenv("RC_SVCNAME"); if (service == NULL || *service == '\0') eerrorx("%s: no service specified", applet); state = rc_service_state(service); bit = lookup_service_state(applet); if (bit) { ok = (state & bit); } else if (strcmp(applet, "service_started_daemon") == 0) { service = getenv("RC_SVCNAME"); exec = argv[1]; if (argc > 3) { service = argv[1]; exec = argv[2]; sscanf(argv[3], "%d", &idx); } else if (argc == 3) { if (sscanf(argv[2], "%d", &idx) != 1) { service = argv[1]; exec = argv[2]; } } ok = rc_service_started_daemon(service, exec, NULL, idx); } else if (strcmp(applet, "service_crashed") == 0) { ok = (_rc_can_find_pids() && rc_service_daemons_crashed(service) && errno != EACCES); } else eerrorx("%s: unknown applet", applet); return ok ? EXIT_SUCCESS : EXIT_FAILURE; }
Service::ServiceStatus Service::status() const { if (rc_service_daemons_crashed(name_.c_str())) return Service::CRASHED; return static_cast<Service::ServiceStatus>(rc_service_state(name_.c_str())); }
int main(int argc, char **argv) { int opt; char *service; RC_STRINGLIST *list; RC_STRING *s; RC_SERVICE state; bool if_crashed = false; bool if_exists = false; bool if_inactive = false; bool if_notstarted = false; bool if_started = false; bool if_stopped = false; applet = basename_c(argv[0]); /* Ensure that we are only quiet when explicitly told to be */ unsetenv("EINFO_QUIET"); while ((opt = getopt_long(argc, argv, getoptstring, longopts, (int *) 0)) != -1) { switch (opt) { case 'd': setenv("RC_DEBUG", "yes", 1); break; case 'D': setenv("RC_NODEPS", "yes", 1); break; case 'e': service = rc_service_resolve(optarg); opt = service ? EXIT_SUCCESS : EXIT_FAILURE; free(service); return opt; /* NOTREACHED */ case 'c': if_crashed = true; break; case 'i': if_exists = true; break; case 'I': if_inactive = true; break; case 'N': if_notstarted = true; break; case 'l': list = rc_services_in_runlevel(NULL); if (TAILQ_FIRST(list) == NULL) return EXIT_FAILURE; rc_stringlist_sort(&list); TAILQ_FOREACH(s, list, entries) printf("%s\n", s->value); rc_stringlist_free(list); return EXIT_SUCCESS; /* NOTREACHED */ case 'r': service = rc_service_resolve(optarg); if (service == NULL) return EXIT_FAILURE; printf("%s\n", service); free(service); return EXIT_SUCCESS; /* NOTREACHED */ case 's': if_started = true; break; case 'S': if_stopped = true; break; case 'Z': setenv("IN_DRYRUN", "yes", 1); break; case_RC_COMMON_GETOPT } } argc -= optind; argv += optind; if (*argv == NULL) eerrorx("%s: you need to specify a service", applet); if ((service = rc_service_resolve(*argv)) == NULL) { if (if_exists) return 0; eerrorx("%s: service `%s' does not exist", applet, *argv); } state = rc_service_state(*argv); if (if_crashed && ! (rc_service_daemons_crashed(*argv) && errno != EACCES)) return 0; if (if_inactive && ! (state & RC_SERVICE_INACTIVE)) return 0; if (if_notstarted && (state & RC_SERVICE_STARTED)) return 0; if (if_started && ! (state & RC_SERVICE_STARTED)) return 0; if (if_stopped && ! (state & RC_SERVICE_STOPPED)) return 0; *argv = service; execv(*argv, argv); eerrorx("%s: %s", applet, strerror(errno)); /* NOTREACHED */ }
static void do_stop_services(RC_STRINGLIST *types_n, RC_STRINGLIST *start_services, const RC_STRINGLIST *stop_services, const RC_DEPTREE *deptree, const char *newlevel, bool parallel, bool going_down) { pid_t pid; RC_STRING *service, *svc1, *svc2; RC_STRINGLIST *deporder, *tmplist, *kwords; RC_SERVICE state; RC_STRINGLIST *nostop; bool crashed, nstop; if (!types_n) { types_n = rc_stringlist_new(); rc_stringlist_add(types_n, "needsme"); } crashed = rc_conf_yesno("rc_crashed_stop"); nostop = rc_stringlist_split(rc_conf_value("rc_nostop"), " "); TAILQ_FOREACH_REVERSE(service, stop_services, rc_stringlist, entries) { state = rc_service_state(service->value); if (state & RC_SERVICE_STOPPED || state & RC_SERVICE_FAILED) continue; /* Sometimes we don't ever want to stop a service. */ if (rc_stringlist_find(nostop, service->value)) { rc_service_mark(service->value, RC_SERVICE_FAILED); continue; } kwords = rc_deptree_depend(deptree, service->value, "keyword"); if (rc_stringlist_find(kwords, "-stop") || rc_stringlist_find(kwords, "nostop") || (going_down && (rc_stringlist_find(kwords, "-shutdown") || rc_stringlist_find(kwords, "noshutdown")))) nstop = true; else nstop = false; rc_stringlist_free(kwords); if (nstop) { rc_service_mark(service->value, RC_SERVICE_FAILED); continue; } /* If the service has crashed, skip futher checks and just stop it */ if (crashed && rc_service_daemons_crashed(service->value)) goto stop; /* If we're in the start list then don't bother stopping us */ svc1 = rc_stringlist_find(start_services, service->value); if (svc1) { if (newlevel && strcmp(runlevel, newlevel) != 0) { /* So we're in the start list. But we should * be stopped if we have a runlevel * configuration file for either the current * or next so we use the correct one. */ if (!runlevel_config(service->value,runlevel) && !runlevel_config(service->value,newlevel)) continue; } else continue; } /* We got this far. Last check is to see if any any service * that going to be started depends on us */ if (!svc1) { tmplist = rc_stringlist_new(); rc_stringlist_add(tmplist, service->value); deporder = rc_deptree_depends(deptree, types_n, tmplist, newlevel ? newlevel : runlevel, RC_DEP_STRICT | RC_DEP_TRACE); rc_stringlist_free(tmplist); svc2 = NULL; TAILQ_FOREACH(svc1, deporder, entries) { svc2 = rc_stringlist_find(start_services, svc1->value); if (svc2) break; }