mirror of
https://github.com/troglobit/finit.git
synced 2026-11-03 13:28:27 +00:00
initctl: refactor command line parser, use concept from mroutectl
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit is contained in:
1 parent
b966d031c8
commit
32ca117949
1 file changed
+75
-90
+75
-90
@@ -49,9 +49,10 @@
|
|||||||
#define FORK plain ? "|-" : "├─"
|
#define FORK plain ? "|-" : "├─"
|
||||||
#define END plain ? "`-" : "└─"
|
#define END plain ? "`-" : "└─"
|
||||||
|
|
||||||
struct command {
|
struct cmd {
|
||||||
char *cmd;
|
char *cmd;
|
||||||
int (*cb)(char *arg);
|
struct cmd *ctx;
|
||||||
|
int (*cb)(char *arg);
|
||||||
};
|
};
|
||||||
|
|
||||||
int icreate = 0;
|
int icreate = 0;
|
||||||
@@ -364,32 +365,6 @@ static int do_cond_show(char *arg)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int do_cond(char *cmd)
|
|
||||||
{
|
|
||||||
int c;
|
|
||||||
char *arg;
|
|
||||||
struct command command[] = {
|
|
||||||
{ "show", do_cond_show },
|
|
||||||
{ "dump", do_cond_dump },
|
|
||||||
{ NULL, NULL }
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!cmd)
|
|
||||||
goto fallback;
|
|
||||||
|
|
||||||
arg = strpbrk(cmd, " \0");
|
|
||||||
if (arg)
|
|
||||||
*arg++ = 0;
|
|
||||||
|
|
||||||
for (c = 0; command[c].cmd; c++) {
|
|
||||||
if (string_match(command[c].cmd, cmd))
|
|
||||||
return command[c].cb(arg);
|
|
||||||
}
|
|
||||||
|
|
||||||
fallback:
|
|
||||||
return do_cond_show(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int do_cmd(int cmd)
|
static int do_cmd(int cmd)
|
||||||
{
|
{
|
||||||
struct init_request rq = {
|
struct init_request rq = {
|
||||||
@@ -835,45 +810,35 @@ static int do_help(char *arg)
|
|||||||
return usage(0);
|
return usage(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int cmd_parse(int argc, char *argv[], struct cmd *command)
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
|
||||||
|
for (i = 0; argc > 0 && command[i].cmd; i++) {
|
||||||
|
if (!string_match(command[i].cmd, argv[0]))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (command[i].ctx)
|
||||||
|
return cmd_parse(argc - 1, &argv[1], command[i].ctx);
|
||||||
|
|
||||||
|
if (command[i].cb) {
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
if (argc == 1)
|
||||||
|
return command[i].cb(NULL);
|
||||||
|
|
||||||
|
for (j = 1; j < argc; j++)
|
||||||
|
rc |= command[i].cb(argv[j]);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return command[0].cb(NULL); /* default cmd */
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
struct command command[] = {
|
|
||||||
{ "debug", toggle_debug },
|
|
||||||
{ "devel", do_devel },
|
|
||||||
{ "help", do_help },
|
|
||||||
{ "version", show_version },
|
|
||||||
|
|
||||||
{ "list", serv_list },
|
|
||||||
{ "ls", serv_list },
|
|
||||||
{ "enable", serv_enable },
|
|
||||||
{ "disable", serv_disable },
|
|
||||||
{ "touch", serv_touch },
|
|
||||||
{ "show", serv_show },
|
|
||||||
{ "edit", serv_edit },
|
|
||||||
{ "create", serv_creat },
|
|
||||||
{ "delete", serv_delete },
|
|
||||||
{ "reload", do_reload },
|
|
||||||
|
|
||||||
{ "cond", do_cond },
|
|
||||||
|
|
||||||
{ "log", do_log },
|
|
||||||
{ "start", do_start },
|
|
||||||
{ "stop", do_stop },
|
|
||||||
{ "restart", do_restart },
|
|
||||||
{ "status", show_status },
|
|
||||||
{ "show", show_status }, /* Convenience alias, for now */
|
|
||||||
|
|
||||||
{ "ps", show_cgroup },
|
|
||||||
|
|
||||||
{ "runlevel", do_runlevel },
|
|
||||||
{ "reboot", do_reboot },
|
|
||||||
{ "halt", do_halt },
|
|
||||||
{ "poweroff", do_poweroff },
|
|
||||||
{ "suspend", do_suspend },
|
|
||||||
|
|
||||||
{ "utmp", do_utmp },
|
|
||||||
{ NULL, NULL }
|
|
||||||
};
|
|
||||||
struct option long_options[] = {
|
struct option long_options[] = {
|
||||||
{ "batch", 0, NULL, 'b' },
|
{ "batch", 0, NULL, 'b' },
|
||||||
{ "create", 0, NULL, 'c' },
|
{ "create", 0, NULL, 'c' },
|
||||||
@@ -884,8 +849,49 @@ int main(int argc, char *argv[])
|
|||||||
{ "verbose", 0, NULL, 'v' },
|
{ "verbose", 0, NULL, 'v' },
|
||||||
{ NULL, 0, NULL, 0 }
|
{ NULL, 0, NULL, 0 }
|
||||||
};
|
};
|
||||||
|
struct cmd cond[] = {
|
||||||
|
{ "status", NULL, do_cond_show }, /* default cmd */
|
||||||
|
{ "dump", NULL, do_cond_dump },
|
||||||
|
{ NULL, NULL, NULL }
|
||||||
|
};
|
||||||
|
struct cmd command[] = {
|
||||||
|
{ "status", NULL, show_status }, /* default cmd */
|
||||||
|
|
||||||
|
{ "debug", NULL, toggle_debug },
|
||||||
|
{ "devel", NULL, do_devel },
|
||||||
|
{ "help", NULL, do_help },
|
||||||
|
{ "version", NULL, show_version },
|
||||||
|
|
||||||
|
{ "list", NULL, serv_list },
|
||||||
|
{ "ls", NULL, serv_list },
|
||||||
|
{ "enable", NULL, serv_enable },
|
||||||
|
{ "disable", NULL, serv_disable },
|
||||||
|
{ "touch", NULL, serv_touch },
|
||||||
|
{ "show", NULL, serv_show },
|
||||||
|
{ "edit", NULL, serv_edit },
|
||||||
|
{ "create", NULL, serv_creat },
|
||||||
|
{ "delete", NULL, serv_delete },
|
||||||
|
{ "reload", NULL, do_reload },
|
||||||
|
|
||||||
|
{ "cond", cond, NULL },
|
||||||
|
|
||||||
|
{ "log", NULL, do_log },
|
||||||
|
{ "start", NULL, do_start },
|
||||||
|
{ "stop", NULL, do_stop },
|
||||||
|
{ "restart", NULL, do_restart },
|
||||||
|
|
||||||
|
{ "ps", NULL, show_cgroup },
|
||||||
|
|
||||||
|
{ "runlevel", NULL, do_runlevel },
|
||||||
|
{ "reboot", NULL, do_reboot },
|
||||||
|
{ "halt", NULL, do_halt },
|
||||||
|
{ "poweroff", NULL, do_poweroff },
|
||||||
|
{ "suspend", NULL, do_suspend },
|
||||||
|
|
||||||
|
{ "utmp", NULL, do_utmp },
|
||||||
|
{ NULL, NULL, NULL }
|
||||||
|
};
|
||||||
int interactive = 1, c;
|
int interactive = 1, c;
|
||||||
char *cmd;
|
|
||||||
|
|
||||||
if (transform(progname(argv[0])))
|
if (transform(progname(argv[0])))
|
||||||
return reboot_main(argc, argv);
|
return reboot_main(argc, argv);
|
||||||
@@ -925,10 +931,8 @@ int main(int argc, char *argv[])
|
|||||||
if (interactive)
|
if (interactive)
|
||||||
screen_init();
|
screen_init();
|
||||||
|
|
||||||
if (optind >= argc)
|
|
||||||
return show_status(NULL);
|
|
||||||
|
|
||||||
if (!has_utmp()) {
|
if (!has_utmp()) {
|
||||||
|
/* system w/o utmp support, disable 'utmp' command */
|
||||||
for (c = 0; command[c].cmd; c++) {
|
for (c = 0; command[c].cmd; c++) {
|
||||||
if (!string_compare(command[c].cmd, "utmp"))
|
if (!string_compare(command[c].cmd, "utmp"))
|
||||||
continue;
|
continue;
|
||||||
@@ -938,26 +942,7 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd = argv[optind++];
|
return cmd_parse(argc - optind, &argv[optind], command);
|
||||||
for (c = 0; command[c].cmd; c++) {
|
|
||||||
int rc = 0;
|
|
||||||
|
|
||||||
if (!string_match(command[c].cmd, cmd))
|
|
||||||
continue;
|
|
||||||
if (!command[c].cb)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* no arg, just a command, e.g. initctl ls */
|
|
||||||
if (optind >= argc)
|
|
||||||
return command[c].cb(NULL);
|
|
||||||
|
|
||||||
/* >=1 arg, e.g., initctl del foo bar baz */
|
|
||||||
while (optind < argc)
|
|
||||||
rc |= command[c].cb(argv[optind++]);
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
return usage(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void logit(int prio, const char *fmt, ...)
|
void logit(int prio, const char *fmt, ...)
|
||||||
|
|||||||
Reference in new issue
Block a user