Simplify conversion of command line args to name=value pairs.

This commit is contained in:
Todd C. Miller
2010-03-05 17:14:19 -05:00
parent 1e131d4278
commit 5ff6832e16

View File

@@ -72,52 +72,37 @@ static void usage_excl(int) __attribute__((__noreturn__));
/* /*
* Mapping of command line flags to name/value settings. * Mapping of command line flags to name/value settings.
*/ */
struct name_value_pair { static struct sudo_settings {
const char *name; const char *name;
const char *value; const char *value;
}; } sudo_settings[] = {
static struct sudo_settings { #define ARG_BSDAUTH_TYPE 0
struct name_value_pair a;
struct name_value_pair c;
struct name_value_pair D;
struct name_value_pair E;
struct name_value_pair g;
struct name_value_pair H;
struct name_value_pair i;
struct name_value_pair k;
struct name_value_pair p;
struct name_value_pair r;
struct name_value_pair t;
struct name_value_pair u;
} sudo_settings = {
{ "bsdauth_type" }, { "bsdauth_type" },
#define ARG_LOGIN_CLASS 1
{ "login_class" }, { "login_class" },
#define ARG_DEBUG_LEVEL 2
{ "debug_level" }, { "debug_level" },
#define ARG_PRESERVE_ENVIRONMENT 3
{ "preserve_environment" }, { "preserve_environment" },
#define ARG_RUNAS_GROUP 4
{ "runas_group" }, { "runas_group" },
#define ARG_SET_HOME 5
{ "set_home" }, { "set_home" },
#define ARG_LOGIN_SHELL 6
{ "login_shell" }, { "login_shell" },
#define ARG_IGNORE_TICKET 7
{ "ignore_ticket" }, { "ignore_ticket" },
#define ARG_PROMPT 8
{ "prompt" }, { "prompt" },
#define ARG_SELINUX_ROLE 9
{ "selinux_role" }, { "selinux_role" },
#define ARG_SELINUX_TYPE 10
{ "selinux_type" }, { "selinux_type" },
{ "runas_user" } #define ARG_RUNAS_USER 11
{ "runas_user" },
#define NUM_SETTINGS 12
{ NULL }
}; };
static struct name_value_pair *setting_pairs[] = {
&sudo_settings.a,
&sudo_settings.c,
&sudo_settings.D,
&sudo_settings.E,
&sudo_settings.g,
&sudo_settings.H,
&sudo_settings.i,
&sudo_settings.k,
&sudo_settings.p,
&sudo_settings.r,
&sudo_settings.t,
&sudo_settings.u
};
#define settings_size (sizeof(setting_pairs) / sizeof(setting_pairs[0]))
/* /*
* Command line argument parsing. * Command line argument parsing.
@@ -170,7 +155,7 @@ parse_args(int argc, char **argv, int *nargc, char ***nargv, char ***settingsp,
break; break;
#ifdef HAVE_BSD_AUTH_H #ifdef HAVE_BSD_AUTH_H
case 'a': case 'a':
sudo_settings.a.value = optarg; sudo_settings[ARG_BSDAUTH_TYPE].value = optarg;
break; break;
#endif #endif
case 'b': case 'b':
@@ -184,7 +169,7 @@ parse_args(int argc, char **argv, int *nargc, char ***nargv, char ***settingsp,
break; break;
#ifdef HAVE_LOGIN_CAP_H #ifdef HAVE_LOGIN_CAP_H
case 'c': case 'c':
sudo_settings.c.value = optarg; sudo_settings[ARG_LOGIN_CLASS].value = optarg;
break; break;
#endif #endif
case 'D': case 'D':
@@ -192,10 +177,10 @@ parse_args(int argc, char **argv, int *nargc, char ***nargv, char ***settingsp,
warningx("the argument to -D must be between 1 and 9 inclusive"); warningx("the argument to -D must be between 1 and 9 inclusive");
usage(1); usage(1);
} }
sudo_settings.D.value = optarg; sudo_settings[ARG_DEBUG_LEVEL].value = optarg;
break; break;
case 'E': case 'E':
sudo_settings.c.value = "true"; sudo_settings[ARG_PRESERVE_ENVIRONMENT].value = "true";
break; break;
case 'e': case 'e':
if (mode && mode != MODE_EDIT) if (mode && mode != MODE_EDIT)
@@ -205,10 +190,10 @@ parse_args(int argc, char **argv, int *nargc, char ***nargv, char ***settingsp,
break; break;
case 'g': case 'g':
runas_group = optarg; runas_group = optarg;
sudo_settings.g.value = optarg; sudo_settings[ARG_RUNAS_GROUP].value = optarg;
break; break;
case 'H': case 'H':
sudo_settings.H.value = optarg; sudo_settings[ARG_SET_HOME].value = "true";
break; break;
case 'h': case 'h':
if (mode && mode != MODE_HELP) { if (mode && mode != MODE_HELP) {
@@ -219,15 +204,15 @@ parse_args(int argc, char **argv, int *nargc, char ***nargv, char ***settingsp,
valid_flags = 0; valid_flags = 0;
break; break;
case 'i': case 'i':
sudo_settings.i.value = "true"; sudo_settings[ARG_LOGIN_SHELL].value = "true";
SET(flags, MODE_LOGIN_SHELL); SET(flags, MODE_LOGIN_SHELL);
break; break;
case 'k': case 'k':
sudo_settings.k.value = "true"; sudo_settings[ARG_IGNORE_TICKET].value = "true";
SET(flags, MODE_INVALIDATE); SET(flags, MODE_INVALIDATE);
break; break;
case 'K': case 'K':
sudo_settings.k.value = "true"; sudo_settings[ARG_IGNORE_TICKET].value = "true";
if (mode && mode != MODE_KILL) if (mode && mode != MODE_KILL)
usage_excl(1); usage_excl(1);
mode = MODE_KILL; mode = MODE_KILL;
@@ -250,14 +235,14 @@ parse_args(int argc, char **argv, int *nargc, char ***nargv, char ***settingsp,
SET(flags, MODE_PRESERVE_GROUPS); SET(flags, MODE_PRESERVE_GROUPS);
break; break;
case 'p': case 'p':
sudo_settings.i.value = optarg; sudo_settings[ARG_PROMPT].value = optarg;
break; break;
#ifdef HAVE_SELINUX #ifdef HAVE_SELINUX
case 'r': case 'r':
sudo_settings.r.value = optarg; sudo_settings[ARG_SELINUX_ROLE].value = optarg;
break; break;
case 't': case 't':
sudo_settings.t.value = optarg; sudo_settings[ARG_SELINUX_TYPE].value = optarg;
break; break;
#endif #endif
case 'S': case 'S':
@@ -274,7 +259,7 @@ parse_args(int argc, char **argv, int *nargc, char ***nargv, char ***settingsp,
break; break;
case 'u': case 'u':
runas_user = optarg; runas_user = optarg;
sudo_settings.u.value = optarg; sudo_settings[ARG_RUNAS_USER].value = optarg;
break; break;
case 'v': case 'v':
if (mode && mode != MODE_VALIDATE) if (mode && mode != MODE_VALIDATE)
@@ -314,7 +299,7 @@ parse_args(int argc, char **argv, int *nargc, char ***nargv, char ***settingsp,
if (ISSET(flags, MODE_INVALIDATE) && *nargc == 0) { if (ISSET(flags, MODE_INVALIDATE) && *nargc == 0) {
mode = MODE_INVALIDATE; /* -k by itself */ mode = MODE_INVALIDATE; /* -k by itself */
CLR(flags, MODE_INVALIDATE); CLR(flags, MODE_INVALIDATE);
sudo_settings.k.value = NULL; sudo_settings[ARG_IGNORE_TICKET].value = NULL;
valid_flags = 0; valid_flags = 0;
} else { } else {
mode = MODE_RUN; /* running a command */ mode = MODE_RUN; /* running a command */
@@ -369,13 +354,13 @@ parse_args(int argc, char **argv, int *nargc, char ***nargv, char ***settingsp,
/* /*
* Format setting_pairs into settings array. * Format setting_pairs into settings array.
*/ */
settings = emalloc2(settings_size + 1, sizeof (char *)); settings = emalloc2(NUM_SETTINGS + 1, sizeof (char *));
for (i = 0, j = 0; i < settings_size; i++) { for (i = 0, j = 0; i < NUM_SETTINGS; i++) {
if (setting_pairs[i]->value) { if (sudo_settings[i].value) {
sudo_debug(9, "settings: %s=%s", setting_pairs[i]->name, sudo_debug(9, "settings: %s=%s", sudo_settings[i].name,
setting_pairs[i]->value); sudo_settings[i].value);
settings[j++] = fmt_string(setting_pairs[i]->name, settings[j++] = fmt_string(sudo_settings[i].name,
setting_pairs[i]->value); sudo_settings[i].value);
} }
} }
settings[j] = NULL; settings[j] = NULL;