Skip to content

Commit 843dc4a

Browse files
committed
openrc-run: simplify main with a command table
1 parent 01b6fbd commit 843dc4a

1 file changed

Lines changed: 153 additions & 98 deletions

File tree

src/openrc-run/openrc-run.c

Lines changed: 153 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -797,7 +797,7 @@ static void svc_start_real(void)
797797
rc_plugin_run(RC_HOOK_SERVICE_START_OUT, applet);
798798
}
799799

800-
static void
800+
static int
801801
svc_start(void)
802802
{
803803
if (dry_run)
@@ -810,6 +810,8 @@ svc_start(void)
810810
printf(" %s\n", applet);
811811
else
812812
svc_start_real();
813+
814+
return 0;
813815
}
814816

815817
static int
@@ -1000,7 +1002,7 @@ svc_stop(void)
10001002
return 0;
10011003
}
10021004

1003-
static void
1005+
static int
10041006
svc_restart(void)
10051007
{
10061008
if (!(rc_service_state(applet) & RC_SERVICE_STOPPED)) {
@@ -1015,6 +1017,8 @@ svc_restart(void)
10151017
start_services(restart_services);
10161018
rc_stringlist_free(restart_services);
10171019
restart_services = NULL;
1020+
1021+
return 0;
10181022
}
10191023

10201024
static bool
@@ -1047,11 +1051,130 @@ service_plugable(void)
10471051
return allow;
10481052
}
10491053

1050-
int main(int argc, char **argv)
1054+
static int
1055+
simple_command(void)
1056+
{
1057+
char *save = prefix;
1058+
int retval;
1059+
1060+
eprefix(NULL);
1061+
prefix = NULL;
1062+
1063+
retval = svc_exec(optarg);
1064+
1065+
eprefix(save);
1066+
prefix = save;
1067+
1068+
return retval;
1069+
}
1070+
1071+
static int
1072+
resolve_deptype(void)
10511073
{
1052-
bool doneone = false;
1053-
int retval, opt, depoptions = RC_DEP_TRACE;
1074+
int depoptions = RC_DEP_TRACE;
10541075
RC_STRING *svc;
1076+
1077+
errno = 0;
1078+
if (rc_conf_yesno("rc_depend_strict") || errno == ENOENT)
1079+
depoptions |= RC_DEP_STRICT;
1080+
1081+
if (!deptree && ((deptree = _rc_deptree_load(0, NULL)) == NULL))
1082+
eerrorx("failed to load deptree");
1083+
1084+
tmplist = rc_stringlist_new();
1085+
rc_stringlist_add(tmplist, optarg);
1086+
services = rc_deptree_depends(deptree, tmplist, applet_list, runlevel, depoptions);
1087+
rc_stringlist_free(tmplist);
1088+
1089+
tmplist = NULL;
1090+
TAILQ_FOREACH(svc, services, entries)
1091+
printf("%s ", svc->value);
1092+
printf ("\n");
1093+
1094+
rc_stringlist_free(services);
1095+
services = NULL;
1096+
1097+
return 0;
1098+
}
1099+
1100+
static int
1101+
cmd_condrestart(void)
1102+
{
1103+
if (rc_service_state(applet) & RC_SERVICE_STARTED)
1104+
svc_restart();
1105+
return 0;
1106+
}
1107+
1108+
static int
1109+
cmd_stop(void)
1110+
{
1111+
RC_STRING *svc;
1112+
1113+
if (strcmp(optarg, "pause") == 0) {
1114+
ewarn("WARNING: 'pause' is deprecated; please use '--nodeps stop'");
1115+
deps = false;
1116+
}
1117+
1118+
if (deps && in_background)
1119+
get_started_services();
1120+
1121+
if (svc_stop() == 1)
1122+
return 0; /* Service has been stopped already */
1123+
1124+
if (deps) {
1125+
if (!in_background && !rc_runlevel_stopping() && rc_service_state(applet) & RC_SERVICE_STOPPED)
1126+
unhotplug();
1127+
1128+
if (in_background && rc_service_state(applet) & RC_SERVICE_INACTIVE) {
1129+
TAILQ_FOREACH(svc, restart_services, entries)
1130+
if (rc_service_state(svc->value) & RC_SERVICE_STOPPED)
1131+
rc_service_schedule_start(applet, svc->value);
1132+
}
1133+
}
1134+
1135+
return 0;
1136+
}
1137+
1138+
static int
1139+
cmd_zap(void)
1140+
{
1141+
einfo("Manually resetting %s to stopped state", applet);
1142+
if (!rc_service_mark(applet, RC_SERVICE_STOPPED))
1143+
eerrorx("rc_service_mark: %s", strerror(errno));
1144+
unhotplug();
1145+
1146+
return 0;
1147+
}
1148+
1149+
struct {
1150+
const char *name;
1151+
int (*handler)(void);
1152+
bool reset_restart_list;
1153+
} commands[] = {
1154+
{ "describe", simple_command, false },
1155+
{ "help", simple_command, false },
1156+
{ "depend", simple_command, false },
1157+
{ "status", simple_command, false },
1158+
{ "ineed", resolve_deptype, false },
1159+
{ "iuse", resolve_deptype, false },
1160+
{ "iwant", resolve_deptype, false },
1161+
{ "needsme", resolve_deptype, false },
1162+
{ "usesme", resolve_deptype, false },
1163+
{ "wantsme", resolve_deptype, false },
1164+
{ "iafter", resolve_deptype, false },
1165+
{ "ibefore", resolve_deptype, false },
1166+
{ "iprovide", resolve_deptype, false },
1167+
{ "start", svc_start, true },
1168+
{ "stop", cmd_stop, true },
1169+
{ "restart", svc_restart, true },
1170+
{ "condrestart", cmd_condrestart, true },
1171+
{ "conditionalrestart", cmd_condrestart, true },
1172+
{ "zap", cmd_zap, true },
1173+
};
1174+
1175+
int main(int argc, char **argv)
1176+
{
1177+
int retval, opt;
10551178
const char *workingdir = "/";
10561179
char *pidstr = NULL;
10571180
size_t l = 0, ll;
@@ -1066,8 +1189,7 @@ int main(int argc, char **argv)
10661189
applet = basename_c(argv[0]);
10671190

10681191
if (stat(argv[1], &stbuf) != 0) {
1069-
fprintf(stderr, "openrc-run `%s': %s\n",
1070-
argv[1], strerror(errno));
1192+
fprintf(stderr, "openrc-run `%s': %s\n", argv[1], strerror(errno));
10711193
exit(EXIT_FAILURE);
10721194
}
10731195

@@ -1151,6 +1273,7 @@ int main(int argc, char **argv)
11511273

11521274
/* eprefix is kinda klunky, but it works for our purposes */
11531275
if (rc_conf_yesno("rc_parallel")) {
1276+
RC_STRING *svc;
11541277
/* Get the longest service name */
11551278
services = rc_services_in_runlevel(NULL);
11561279
TAILQ_FOREACH(svc, services, entries) {
@@ -1212,9 +1335,15 @@ int main(int argc, char **argv)
12121335
applet_list = rc_stringlist_new();
12131336
rc_stringlist_add(applet_list, applet);
12141337

1338+
if (optind >= argc)
1339+
usage(EXIT_FAILURE);
1340+
12151341
/* Now run each option */
12161342
retval = EXIT_SUCCESS;
1343+
1344+
next_cmd:
12171345
while (optind < argc) {
1346+
int cmdval;
12181347
optarg = argv[optind++];
12191348

12201349
/* Abort on a sighup here */
@@ -1228,101 +1357,27 @@ int main(int argc, char **argv)
12281357
unsetenv("RC_CMD");
12291358
setenv("RC_CMD", optarg, 1);
12301359

1231-
doneone = true;
1360+
for (size_t i = 0; i < ARRAY_SIZE(commands); i++) {
1361+
if (strcmp(optarg, commands[i].name) != 0)
1362+
continue;
12321363

1233-
if (strcmp(optarg, "describe") == 0 ||
1234-
strcmp(optarg, "help") == 0 ||
1235-
strcmp(optarg, "depend") == 0)
1236-
{
1237-
char *save = prefix;
1238-
eprefix(NULL);
1239-
prefix = NULL;
1240-
svc_exec(optarg);
1241-
eprefix(save);
1242-
prefix = save;
1243-
} else if (strcmp(optarg, "ineed") == 0 ||
1244-
strcmp(optarg, "iuse") == 0 ||
1245-
strcmp(optarg, "iwant") == 0 ||
1246-
strcmp(optarg, "needsme") == 0 ||
1247-
strcmp(optarg, "usesme") == 0 ||
1248-
strcmp(optarg, "wantsme") == 0 ||
1249-
strcmp(optarg, "iafter") == 0 ||
1250-
strcmp(optarg, "ibefore") == 0 ||
1251-
strcmp(optarg, "iprovide") == 0)
1252-
{
1253-
errno = 0;
1254-
if (rc_conf_yesno("rc_depend_strict") ||
1255-
errno == ENOENT)
1256-
depoptions |= RC_DEP_STRICT;
1257-
1258-
if (!deptree &&
1259-
((deptree = _rc_deptree_load(0, NULL)) == NULL))
1260-
eerrorx("failed to load deptree");
1261-
1262-
tmplist = rc_stringlist_new();
1263-
rc_stringlist_add(tmplist, optarg);
1264-
services = rc_deptree_depends(deptree, tmplist,
1265-
applet_list,
1266-
runlevel, depoptions);
1267-
rc_stringlist_free(tmplist);
1268-
tmplist = NULL;
1269-
TAILQ_FOREACH(svc, services, entries)
1270-
printf("%s ", svc->value);
1271-
printf ("\n");
1272-
rc_stringlist_free(services);
1273-
services = NULL;
1274-
} else if (strcmp (optarg, "status") == 0) {
1275-
eprefix(NULL);
1276-
prefix = NULL;
1277-
retval = svc_exec("status");
1278-
} else {
1279-
if (strcmp(optarg, "conditionalrestart") == 0 ||
1280-
strcmp(optarg, "condrestart") == 0)
1281-
{
1282-
if (rc_service_state(applet) & RC_SERVICE_STARTED)
1283-
svc_restart();
1284-
} else if (strcmp(optarg, "restart") == 0) {
1285-
svc_restart();
1286-
} else if (strcmp(optarg, "start") == 0) {
1287-
svc_start();
1288-
} else if (strcmp(optarg, "stop") == 0 || strcmp(optarg, "pause") == 0) {
1289-
if (strcmp(optarg, "pause") == 0) {
1290-
ewarn("WARNING: 'pause' is deprecated; please use '--nodeps stop'");
1291-
deps = false;
1292-
}
1293-
if (deps && in_background)
1294-
get_started_services();
1295-
if (svc_stop() == 1)
1296-
continue; /* Service has been stopped already */
1297-
if (deps) {
1298-
if (!in_background && !rc_runlevel_stopping() && rc_service_state(applet) & RC_SERVICE_STOPPED)
1299-
unhotplug();
1300-
1301-
if (in_background && rc_service_state(applet) & RC_SERVICE_INACTIVE) {
1302-
TAILQ_FOREACH(svc, restart_services, entries)
1303-
if (rc_service_state(svc->value) & RC_SERVICE_STOPPED)
1304-
rc_service_schedule_start(applet, svc->value);
1305-
}
1306-
}
1307-
} else if (strcmp(optarg, "zap") == 0) {
1308-
einfo("Manually resetting %s to stopped state",
1309-
applet);
1310-
if (!rc_service_mark(applet,
1311-
RC_SERVICE_STOPPED))
1312-
eerrorx("rc_service_mark: %s",
1313-
strerror(errno));
1314-
unhotplug();
1315-
} else
1316-
retval = svc_exec(optarg);
1364+
if ((cmdval = commands[i].handler()) != 0)
1365+
retval = cmdval;
1366+
1367+
if (commands[i].reset_restart_list) {
1368+
/* We should ensure this list is empty after
1369+
* an action is done */
1370+
rc_stringlist_free(restart_services);
1371+
restart_services = NULL;
1372+
}
13171373

1318-
/* We should ensure this list is empty after
1319-
* an action is done */
1320-
rc_stringlist_free(restart_services);
1321-
restart_services = NULL;
1374+
goto next_cmd;
13221375
}
13231376

1324-
if (!doneone)
1325-
usage(EXIT_FAILURE);
1377+
if ((cmdval = svc_exec(optarg)) != 0)
1378+
retval = cmdval;
1379+
rc_stringlist_free(restart_services);
1380+
restart_services = NULL;
13261381
}
13271382

13281383
return retval;

0 commit comments

Comments
 (0)