rc: collapse the applet if statements into a single array walk
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
This commit is contained in:
parent
0813a80223
commit
2486eb4989
@ -253,13 +253,38 @@ do_e(int argc, char **argv)
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct {
|
||||||
|
const char * const name;
|
||||||
|
RC_SERVICE bit;
|
||||||
|
} service_bits[] = {
|
||||||
|
{ "service_started", RC_SERVICE_STARTED, },
|
||||||
|
{ "service_stopped", RC_SERVICE_STOPPED, },
|
||||||
|
{ "service_inactive", RC_SERVICE_INACTIVE, },
|
||||||
|
{ "service_starting", RC_SERVICE_STARTING, },
|
||||||
|
{ "service_stopping", RC_SERVICE_STOPPING, },
|
||||||
|
{ "service_hotplugged", RC_SERVICE_HOTPLUGGED, },
|
||||||
|
{ "service_wasinactive", RC_SERVICE_WASINACTIVE, },
|
||||||
|
{ "service_failed", RC_SERVICE_FAILED, },
|
||||||
|
};
|
||||||
|
|
||||||
|
static RC_SERVICE
|
||||||
|
lookup_service_state(const char *service)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
for (i = 0; i < ARRAY_SIZE(service_bits); ++i)
|
||||||
|
if (!strcmp(service, service_bits[i].name))
|
||||||
|
return service_bits[i].bit;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
do_service(int argc, char **argv)
|
do_service(int argc, char **argv)
|
||||||
{
|
{
|
||||||
bool ok = false;
|
bool ok = false;
|
||||||
char *service;
|
char *service;
|
||||||
char *exec;
|
char *exec;
|
||||||
int idx = 0;
|
int idx;
|
||||||
|
RC_SERVICE state, bit;
|
||||||
|
|
||||||
if (argc > 1)
|
if (argc > 1)
|
||||||
service = argv[1];
|
service = argv[1];
|
||||||
@ -269,21 +294,11 @@ do_service(int argc, char **argv)
|
|||||||
if (service == NULL || *service == '\0')
|
if (service == NULL || *service == '\0')
|
||||||
eerrorx("%s: no service specified", applet);
|
eerrorx("%s: no service specified", applet);
|
||||||
|
|
||||||
if (strcmp(applet, "service_started") == 0)
|
state = rc_service_state(service);
|
||||||
ok = (rc_service_state(service) & RC_SERVICE_STARTED);
|
bit = lookup_service_state(service);
|
||||||
else if (strcmp(applet, "service_stopped") == 0)
|
if (bit) {
|
||||||
ok = (rc_service_state(service) & RC_SERVICE_STOPPED);
|
ok = (state & bit);
|
||||||
else if (strcmp(applet, "service_inactive") == 0)
|
} else if (strcmp(applet, "service_started_daemon") == 0) {
|
||||||
ok = (rc_service_state(service) & RC_SERVICE_INACTIVE);
|
|
||||||
else if (strcmp(applet, "service_starting") == 0)
|
|
||||||
ok = (rc_service_state(service) & RC_SERVICE_STARTING);
|
|
||||||
else if (strcmp(applet, "service_stopping") == 0)
|
|
||||||
ok = (rc_service_state(service) & RC_SERVICE_STOPPING);
|
|
||||||
else if (strcmp(applet, "service_hotplugged") == 0)
|
|
||||||
ok = (rc_service_state(service) & RC_SERVICE_HOTPLUGGED);
|
|
||||||
else if (strcmp(applet, "service_wasinactive") == 0)
|
|
||||||
ok = (rc_service_state(service) & RC_SERVICE_WASINACTIVE);
|
|
||||||
else if (strcmp(applet, "service_started_daemon") == 0) {
|
|
||||||
service = getenv("RC_SVCNAME");
|
service = getenv("RC_SVCNAME");
|
||||||
exec = argv[1];
|
exec = argv[1];
|
||||||
if (argc > 3) {
|
if (argc > 3) {
|
||||||
@ -317,6 +332,7 @@ do_mark_service(int argc, char **argv)
|
|||||||
char *runscript_pid;
|
char *runscript_pid;
|
||||||
/* char *mtime; */
|
/* char *mtime; */
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
|
RC_SERVICE bit;
|
||||||
/* size_t l; */
|
/* size_t l; */
|
||||||
|
|
||||||
if (argc > 1)
|
if (argc > 1)
|
||||||
@ -327,20 +343,9 @@ do_mark_service(int argc, char **argv)
|
|||||||
if (service == NULL || *service == '\0')
|
if (service == NULL || *service == '\0')
|
||||||
eerrorx("%s: no service specified", applet);
|
eerrorx("%s: no service specified", applet);
|
||||||
|
|
||||||
if (strcmp(applet, "mark_service_started") == 0)
|
if (strncmp(applet, "mark_", 5) &&
|
||||||
ok = rc_service_mark(service, RC_SERVICE_STARTED);
|
(bit = lookup_service_state(applet + 5)))
|
||||||
else if (strcmp(applet, "mark_service_stopped") == 0)
|
ok = rc_service_mark(service, bit);
|
||||||
ok = rc_service_mark(service, RC_SERVICE_STOPPED);
|
|
||||||
else if (strcmp(applet, "mark_service_inactive") == 0)
|
|
||||||
ok = rc_service_mark(service, RC_SERVICE_INACTIVE);
|
|
||||||
else if (strcmp(applet, "mark_service_starting") == 0)
|
|
||||||
ok = rc_service_mark(service, RC_SERVICE_STARTING);
|
|
||||||
else if (strcmp(applet, "mark_service_stopping") == 0)
|
|
||||||
ok = rc_service_mark(service, RC_SERVICE_STOPPING);
|
|
||||||
else if (strcmp(applet, "mark_service_hotplugged") == 0)
|
|
||||||
ok = rc_service_mark(service, RC_SERVICE_HOTPLUGGED);
|
|
||||||
else if (strcmp(applet, "mark_service_failed") == 0)
|
|
||||||
ok = rc_service_mark(service, RC_SERVICE_FAILED);
|
|
||||||
else
|
else
|
||||||
eerrorx("%s: unknown applet", applet);
|
eerrorx("%s: unknown applet", applet);
|
||||||
|
|
||||||
@ -409,7 +414,7 @@ do_value(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
do_shell_var(int argc, char **argv)
|
shell_var(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
char *p;
|
char *p;
|
||||||
@ -430,12 +435,102 @@ do_shell_var(int argc, char **argv)
|
|||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
is_older_than(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (argc < 3)
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
|
||||||
|
/* This test is perverted - historically the baselayout function
|
||||||
|
* returns 0 on *failure*, which is plain wrong */
|
||||||
|
for (i = 2; i < argc; ++i)
|
||||||
|
if (!rc_newer_than(argv[1], argv[i], NULL, NULL))
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
is_newer_than(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (argc < 3)
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
|
||||||
|
/* This test is correct as it's not present in baselayout */
|
||||||
|
for (i = 2; i < argc; ++i)
|
||||||
|
if (!rc_newer_than(argv[1], argv[i], NULL, NULL))
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
is_runlevel_start(_unused int argc, _unused char **argv)
|
||||||
|
{
|
||||||
|
return rc_runlevel_starting() ? 0 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
is_runlevel_stop(_unused int argc, _unused char **argv)
|
||||||
|
{
|
||||||
|
return rc_runlevel_stopping() ? 0 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
rc_abort(_unused int argc, _unused char **argv)
|
||||||
|
{
|
||||||
|
const char *p = getenv("RC_PID");
|
||||||
|
int pid;
|
||||||
|
|
||||||
|
if (p && sscanf(p, "%d", &pid) == 1) {
|
||||||
|
if (kill(pid, SIGUSR1) != 0)
|
||||||
|
eerrorx("rc-abort: failed to signal parent %d: %s",
|
||||||
|
pid, strerror(errno));
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct {
|
||||||
|
const char * const name;
|
||||||
|
int (* const applet)(int argc, char **argv);
|
||||||
|
} applets[] = {
|
||||||
|
#define A(a) { #a, a }
|
||||||
|
A(fstabinfo),
|
||||||
|
A(mountinfo),
|
||||||
|
{ "rc-depend", rc_depend, },
|
||||||
|
{ "rc-service", rc_service, },
|
||||||
|
{ "rc-status", rc_status, },
|
||||||
|
{ "rc-update", rc_update, },
|
||||||
|
{ "update-rc", rc_update, },
|
||||||
|
A(runscript),
|
||||||
|
{ "start-stop-daemon", start_stop_daemon, },
|
||||||
|
A(checkpath),
|
||||||
|
A(swclock),
|
||||||
|
A(shell_var),
|
||||||
|
A(is_older_than),
|
||||||
|
A(is_newer_than),
|
||||||
|
A(is_runlevel_start),
|
||||||
|
A(is_runlevel_stop),
|
||||||
|
{ "rc-abort", rc_abort, },
|
||||||
|
/* These are purely for init scripts and do not make sense as
|
||||||
|
* anything else */
|
||||||
|
{ "service_get_value", do_value, },
|
||||||
|
{ "service_set_value", do_value, },
|
||||||
|
{ "get_options", do_value, },
|
||||||
|
{ "save_options", do_value, },
|
||||||
|
#undef A
|
||||||
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
run_applets(int argc, char **argv)
|
run_applets(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int i = 2;
|
size_t i;
|
||||||
char *p;
|
|
||||||
pid_t pid = 0;
|
|
||||||
|
|
||||||
/* Bug 351712: We need an extra way to explicitly select an applet OTHER
|
/* Bug 351712: We need an extra way to explicitly select an applet OTHER
|
||||||
* than trusting argv[0], as argv[0] is not going to be the applet value if
|
* than trusting argv[0], as argv[0] is not going to be the applet value if
|
||||||
@ -448,88 +543,19 @@ run_applets(int argc, char **argv)
|
|||||||
argc -= 2;
|
argc -= 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* These are designed to be applications in their own right */
|
for (i = 0; i < ARRAY_SIZE(applets); ++i)
|
||||||
if (strcmp(applet, "fstabinfo") == 0)
|
if (!strcmp(applet, applets[i].name))
|
||||||
exit(fstabinfo(argc, argv));
|
exit(applets[i].applet(argc, argv));
|
||||||
else if (strcmp(applet, "mountinfo") == 0)
|
|
||||||
exit(mountinfo(argc, argv));
|
|
||||||
else if (strcmp(applet, "rc-depend") == 0)
|
|
||||||
exit(rc_depend(argc, argv));
|
|
||||||
else if (strcmp(applet, "rc-service") == 0)
|
|
||||||
exit(rc_service(argc, argv));
|
|
||||||
else if (strcmp(applet, "rc-status") == 0)
|
|
||||||
exit(rc_status(argc, argv));
|
|
||||||
else if (strcmp(applet, "rc-update") == 0 ||
|
|
||||||
strcmp(applet, "update-rc") == 0)
|
|
||||||
exit(rc_update(argc, argv));
|
|
||||||
else if (strcmp(applet, "runscript") == 0)
|
|
||||||
exit(runscript(argc, argv));
|
|
||||||
else if (strcmp(applet, "start-stop-daemon") == 0)
|
|
||||||
exit(start_stop_daemon(argc, argv));
|
|
||||||
else if (strcmp (applet, "checkpath") == 0)
|
|
||||||
exit(checkpath(argc, argv));
|
|
||||||
else if (strcmp(applet, "swclock") == 0)
|
|
||||||
exit(swclock(argc, argv));
|
|
||||||
|
|
||||||
/* These could also be applications in their own right */
|
|
||||||
if (strcmp(applet, "shell_var") == 0)
|
|
||||||
exit(do_shell_var(argc, argv));
|
|
||||||
|
|
||||||
/* This test is perverted - historically the baselayout function
|
|
||||||
* returns 0 on *failure*, which is plain wrong */
|
|
||||||
if (strcmp(applet, "is_older_than") == 0) {
|
|
||||||
if (argc < 3)
|
|
||||||
exit (EXIT_FAILURE);
|
|
||||||
while (i < argc) {
|
|
||||||
if (!rc_newer_than(argv[1], argv[i++], NULL, NULL))
|
|
||||||
exit(EXIT_SUCCESS);
|
|
||||||
}
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
};
|
|
||||||
/* This test is correct as it's not present in baselayout */
|
|
||||||
if (strcmp(applet, "is_newer_than") == 0) {
|
|
||||||
if (argc < 3)
|
|
||||||
exit (EXIT_FAILURE);
|
|
||||||
while (i < argc) {
|
|
||||||
if (!rc_newer_than(argv[1], argv[i++], NULL, NULL))
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
exit(EXIT_SUCCESS);
|
|
||||||
};
|
|
||||||
|
|
||||||
if (applet[0] == 'e' || (applet[0] == 'v' && applet[1] == 'e'))
|
if (applet[0] == 'e' || (applet[0] == 'v' && applet[1] == 'e'))
|
||||||
exit(do_e(argc, argv));
|
exit(do_e(argc, argv));
|
||||||
|
|
||||||
/* These are purely for init scripts and do not make sense as
|
|
||||||
* anything else */
|
|
||||||
if (strcmp(applet, "service_get_value") == 0 ||
|
|
||||||
strcmp(applet, "service_set_value") == 0 ||
|
|
||||||
strcmp(applet, "get_options") == 0 ||
|
|
||||||
strcmp(applet, "save_options") == 0)
|
|
||||||
exit(do_value(argc, argv));
|
|
||||||
|
|
||||||
if (strncmp(applet, "service_", strlen("service_")) == 0)
|
if (strncmp(applet, "service_", strlen("service_")) == 0)
|
||||||
exit(do_service(argc, argv));
|
exit(do_service(argc, argv));
|
||||||
|
|
||||||
if (strncmp(applet, "mark_service_", strlen("mark_service_")) == 0)
|
if (strncmp(applet, "mark_service_", strlen("mark_service_")) == 0)
|
||||||
exit(do_mark_service(argc, argv));
|
exit(do_mark_service(argc, argv));
|
||||||
|
|
||||||
if (strcmp(applet, "is_runlevel_start") == 0)
|
|
||||||
exit(rc_runlevel_starting() ? 0 : 1);
|
|
||||||
else if (strcmp (applet, "is_runlevel_stop") == 0)
|
|
||||||
exit(rc_runlevel_stopping() ? 0 : 1);
|
|
||||||
|
|
||||||
if (strcmp(applet, "rc-abort") == 0) {
|
|
||||||
p = getenv("RC_PID");
|
|
||||||
if (p && sscanf(p, "%d", &pid) == 1) {
|
|
||||||
if (kill(pid, SIGUSR1) != 0)
|
|
||||||
eerrorx("rc-abort: failed to signal parent %d: %s",
|
|
||||||
pid, strerror(errno));
|
|
||||||
exit(EXIT_SUCCESS);
|
|
||||||
}
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strcmp(applet, "rc") != 0)
|
if (strcmp(applet, "rc") != 0)
|
||||||
eerrorx("%s: unknown applet", applet);
|
eerrorx("%s: unknown applet", applet);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user