summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Amelkin <alexander@amelkin.msk.ru>2020-06-10 00:54:15 +0300
committerAlexander Amelkin <mocbuhtig@amelkin.msk.ru>2020-06-10 13:46:57 +0300
commite3fc775d26c9650bd6fbde30353d66fec12811b9 (patch)
treea83ebfe11ebbf957ae7aa39ce3380cc633f303f8
parent6e037d6bfbbb93b349c8ca331ebde03a837f76bf (diff)
downloadipmitool-e3fc775d26c9650bd6fbde30353d66fec12811b9.tar.gz
channel: Refactor set_user_access option processing
Reduce code duplication by extracting option names, types, and value ranges into a separate structure, and rewriting the option parsing code without mixing it with the data. Signed-off-by: Alexander Amelkin <alexander@amelkin.msk.ru>
-rw-r--r--include/ipmitool/ipmi_constants.h1
-rw-r--r--lib/ipmi_channel.c86
-rw-r--r--lib/ipmi_strings.c4
3 files changed, 62 insertions, 29 deletions
diff --git a/include/ipmitool/ipmi_constants.h b/include/ipmitool/ipmi_constants.h
index 5391d4f..fc8642d 100644
--- a/include/ipmitool/ipmi_constants.h
+++ b/include/ipmitool/ipmi_constants.h
@@ -74,6 +74,7 @@
#define IPMI_SESSION_PRIV_OPERATOR 0x3
#define IPMI_SESSION_PRIV_ADMIN 0x4
#define IPMI_SESSION_PRIV_OEM 0x5
+#define IPMI_SESSION_PRIV_NOACCESS 0xF
#define IPMI_SET_IN_PROGRESS_SET_COMPLETE 0x00
#define IPMI_SET_IN_PROGRESS_IN_PROGRESS 0x01
diff --git a/lib/ipmi_channel.c b/lib/ipmi_channel.c
index 2886899..ac3cf2d 100644
--- a/lib/ipmi_channel.c
+++ b/lib/ipmi_channel.c
@@ -803,8 +803,26 @@ ipmi_set_user_access(struct ipmi_intf *intf, int argc, char **argv)
int ccode = 0;
int i = 0;
uint8_t channel = 0;
- uint8_t priv = 0;
uint8_t user_id = 0;
+ struct {
+ const char *option;
+ enum {
+ UA_INTEGER, /* direct integer value */
+ UA_BOOLEAN, /* off/disable = false, on/enable = true */
+ UA_BOOLEAN_INVERSE /* off/disable = true, on/enable = false */
+ } type;
+ uint8_t *val;
+ uint8_t min; /* minimum value for UA_INTEGER options */
+ uint8_t max; /* maximum value for UA_INTEGER options */
+ } options[] = {
+ { "callin=", UA_BOOLEAN_INVERSE, &user_access.callin_callback, 0, 0},
+ { "link=", UA_BOOLEAN, &user_access.link_auth, 0, 0},
+ { "ipmi=", UA_BOOLEAN, &user_access.ipmi_messaging, 0, 0},
+ { "privilege=", UA_INTEGER, &user_access.privilege_limit
+ , IPMI_SESSION_PRIV_CALLBACK
+ , IPMI_SESSION_PRIV_NOACCESS },
+ };
+
if (argc > 0 && strcmp(argv[0], "help") == 0) {
printf_channel_usage();
return 0;
@@ -827,33 +845,47 @@ ipmi_set_user_access(struct ipmi_intf *intf, int argc, char **argv)
return (-1);
}
for (i = 2; i < argc; i ++) {
- if (strcmp(argv[i], "callin=") == 0) {
- if (strcmp(argv[i] + strlen("callin="), "off") == 0) {
- user_access.callin_callback = 1;
- } else {
- user_access.callin_callback = 0;
- }
- } else if (strcmp(argv[i], "link=") == 0) {
- if (strcmp(argv[i] + strlen("link="), "off") == 0) {
- user_access.link_auth = 0;
- } else {
- user_access.link_auth = 1;
- }
- } else if (strcmp(argv[i], "ipmi=") == 0) {
- if (strcmp(argv[i] + strlen("ipmi="), "off") == 0) {
- user_access.ipmi_messaging = 0;
- } else {
- user_access.ipmi_messaging = 1;
+ size_t j;
+ for (j = 0; j < ARRAY_SIZE(options); ++j) {
+ const char *opt = argv[i];
+ const int optlen = strlen(options[j].option);
+ if (!strncmp(opt, options[j].option, optlen)) {
+ const char *optval = opt + optlen;
+ uint16_t val;
+
+ if (UA_INTEGER != options[j].type) {
+ bool boolval = (UA_BOOLEAN_INVERSE == options[j].type)
+ ? false
+ : true;
+ *options[j].val = boolval;
+ if (!strcmp(optval, "off")
+ || !strcmp(optval, "disable")
+ || !strcmp(optval, "no")
+ )
+ {
+ boolval = !boolval;
+ }
+ } else if (UINT8_MAX
+ != (val = str2val(optval, ipmi_privlvl_vals)))
+ {
+ *options[j].val = (uint8_t)val;
+ } else if (str2uchar(optval, options[j].val)) {
+ lprintf(LOG_ERR
+ , "Numeric [%hhu-%hhu] value expected, "
+ "but '%s' given."
+ , options[j].min
+ , options[j].max
+ , optval);
+ return (-1);
+ }
+ lprintf(LOG_DEBUG
+ , "Option %s=%hhu"
+ , options[j].option
+ , *options[j].val);
+ break;
}
- } else if (strcmp(argv[i], "privilege=") == 0) {
- if (str2uchar(argv[i] + 10, &priv) != 0) {
- lprintf(LOG_ERR,
- "Numeric value expected, but '%s' given.",
- argv[i] + 10);
- return (-1);
- }
- user_access.privilege_limit = priv;
- } else {
+ }
+ if (ARRAY_SIZE(options) == j) {
lprintf(LOG_ERR, "Invalid option: %s\n", argv[i]);
return (-1);
}
diff --git a/lib/ipmi_strings.c b/lib/ipmi_strings.c
index aab50f6..9fc6b61 100644
--- a/lib/ipmi_strings.c
+++ b/lib/ipmi_strings.c
@@ -1031,8 +1031,8 @@ const struct valstr ipmi_privlvl_vals[] = {
{ IPMI_SESSION_PRIV_OPERATOR, "OPERATOR" },
{ IPMI_SESSION_PRIV_ADMIN, "ADMINISTRATOR" },
{ IPMI_SESSION_PRIV_OEM, "OEM" },
- { 0xF, "NO ACCESS" },
- { 0xFF, NULL },
+ { IPMI_SESSION_PRIV_NOACCESS, "NO ACCESS" },
+ { UINT8_MAX, NULL },
};