Refactor the error parts of set_default_entry() so the switch() is

mostly just calls to store_foo() functions.  Avoids a lot of
duplicated error checking and silences a cppcheck false positive.
This commit is contained in:
Todd C. Miller
2016-08-12 10:37:41 -06:00
parent 9051c92cb3
commit caf064e17b

View File

@@ -190,185 +190,94 @@ dump_defaults(void)
} }
static bool static bool
set_default_entry(struct sudo_defs_types *def, const char *val, int op, bool quiet, bool do_callback) set_default_entry(struct sudo_defs_types *def, const char *val, int op,
bool quiet, bool do_callback)
{ {
int rc;
debug_decl(set_default_entry, SUDOERS_DEBUG_DEFAULTS) debug_decl(set_default_entry, SUDOERS_DEBUG_DEFAULTS)
switch (def->type & T_MASK) { if (val == NULL) {
case T_LOGFAC: /* Check for bogus boolean usage or missing value if non-boolean. */
if (!store_syslogfac(val, def, op)) {
if (!quiet) {
if (val)
sudo_warnx(U_("value `%s' is invalid for option `%s'"),
val, def->name);
else
sudo_warnx(U_("no value specified for `%s'"), def->name);
}
debug_return_bool(false);
}
break;
case T_LOGPRI:
if (!store_syslogpri(val, def, op)) {
if (!quiet) {
if (val)
sudo_warnx(U_("value `%s' is invalid for option `%s'"),
val, def->name);
else
sudo_warnx(U_("no value specified for `%s'"), def->name);
}
debug_return_bool(false);
}
break;
case T_STR:
if (!val) {
/* Check for bogus boolean usage or lack of a value. */
if (!ISSET(def->type, T_BOOL) || op != false) { if (!ISSET(def->type, T_BOOL) || op != false) {
if (!quiet) if (!quiet)
sudo_warnx(U_("no value specified for `%s'"), def->name); sudo_warnx(U_("no value specified for `%s'"), def->name);
debug_return_bool(false); debug_return_bool(false);
} }
} }
if (ISSET(def->type, T_PATH) && val && *val != '/') {
switch (def->type & T_MASK) {
case T_LOGFAC:
rc = store_syslogfac(val, def, op);
break;
case T_LOGPRI:
rc = store_syslogpri(val, def, op);
break;
case T_STR:
if (ISSET(def->type, T_PATH) && val != NULL && *val != '/') {
if (!quiet) { if (!quiet) {
sudo_warnx(U_("values for `%s' must start with a '/'"), sudo_warnx(U_("values for `%s' must start with a '/'"),
def->name); def->name);
} }
debug_return_bool(false); rc = -1;
}
switch (store_str(val, def, op)) {
case true:
/* OK */
break; break;
case false:
if (!quiet) {
sudo_warnx(U_("value `%s' is invalid for option `%s'"),
val, def->name);
}
/* FALLTHROUGH */
default:
debug_return_bool(false);
} }
rc = store_str(val, def, op);
break; break;
case T_INT: case T_INT:
if (!val) { rc = store_int(val, def, op);
/* Check for bogus boolean usage or lack of a value. */
if (!ISSET(def->type, T_BOOL) || op != false) {
if (!quiet)
sudo_warnx(U_("no value specified for `%s'"), def->name);
debug_return_bool(false);
}
}
if (!store_int(val, def, op)) {
if (!quiet) {
sudo_warnx(U_("value `%s' is invalid for option `%s'"),
val, def->name);
}
debug_return_bool(false);
}
break; break;
case T_UINT: case T_UINT:
if (!val) { rc = store_uint(val, def, op);
/* Check for bogus boolean usage or lack of a value. */
if (!ISSET(def->type, T_BOOL) || op != false) {
if (!quiet)
sudo_warnx(U_("no value specified for `%s'"), def->name);
debug_return_bool(false);
}
}
if (!store_uint(val, def, op)) {
if (!quiet) {
sudo_warnx(U_("value `%s' is invalid for option `%s'"),
val, def->name);
}
debug_return_bool(false);
}
break; break;
case T_FLOAT: case T_FLOAT:
if (!val) { rc = store_float(val, def, op);
/* Check for bogus boolean usage or lack of a value. */
if (!ISSET(def->type, T_BOOL) || op != false) {
if (!quiet)
sudo_warnx(U_("no value specified for `%s'"), def->name);
debug_return_bool(false);
}
}
if (!store_float(val, def, op)) {
if (!quiet) {
sudo_warnx(U_("value `%s' is invalid for option `%s'"),
val, def->name);
}
debug_return_bool(false);
}
break; break;
case T_MODE: case T_MODE:
if (!val) { rc = store_mode(val, def, op);
/* Check for bogus boolean usage or lack of a value. */
if (!ISSET(def->type, T_BOOL) || op != false) {
if (!quiet)
sudo_warnx(U_("no value specified for `%s'"), def->name);
debug_return_bool(false);
}
}
if (!store_mode(val, def, op)) {
if (!quiet) {
sudo_warnx(U_("value `%s' is invalid for option `%s'"),
val, def->name);
}
debug_return_bool(false);
}
break; break;
case T_FLAG: case T_FLAG:
if (val) { if (val != NULL) {
if (!quiet) { if (!quiet) {
sudo_warnx(U_("option `%s' does not take a value"), sudo_warnx(U_("option `%s' does not take a value"),
def->name); def->name);
} }
debug_return_bool(false); rc = -1;
break;
} }
def->sd_un.flag = op; def->sd_un.flag = op;
break; break;
case T_LIST: case T_LIST:
if (!val) { rc = store_list(val, def, op);
/* Check for bogus boolean usage or lack of a value. */
if (!ISSET(def->type, T_BOOL) || op != false) {
if (!quiet)
sudo_warnx(U_("no value specified for `%s'"), def->name);
debug_return_bool(false);
}
}
if (!store_list(val, def, op)) {
if (!quiet) {
sudo_warnx(U_("value `%s' is invalid for option `%s'"),
val, def->name);
}
debug_return_bool(false);
}
break; break;
case T_TUPLE: case T_TUPLE:
if (!val && !ISSET(def->type, T_BOOL)) { rc = store_tuple(val, def, op);
if (!quiet)
sudo_warnx(U_("no value specified for `%s'"), def->name);
debug_return_bool(false);
}
if (!store_tuple(val, def, op)) {
if (!quiet) {
sudo_warnx(U_("value `%s' is invalid for option `%s'"),
val, def->name);
}
debug_return_bool(false);
}
break; break;
default: default:
if (!quiet) { if (!quiet) {
sudo_warnx(U_("invalid Defaults type 0x%x for option `%s'"), sudo_warnx(U_("invalid Defaults type 0x%x for option `%s'"),
def->type, def->name); def->type, def->name);
} }
debug_return_bool(false); rc = -1;
break;
} }
switch (rc) {
case -1:
/* Error message already displayed. */
rc = false;
break;
case false:
if (!quiet) {
sudo_warnx(U_("value `%s' is invalid for option `%s'"),
val, def->name);
}
break;
case true:
if (do_callback && def->callback) if (do_callback && def->callback)
debug_return_bool(def->callback(&def->sd_un)); rc = def->callback(&def->sd_un);
break;
}
debug_return_bool(true); debug_return_bool(rc);
} }
struct early_default * struct early_default *