Improve unit parsing of mpsutil.

Previously, it used atoi(3) to parse the unit parameter, which would silently
yield a unit of 0 in the presence of an invalid unit number.  As most users of
mpsutil(8) are likely to have at least a unit 0, this is could have confusing
results.

This behaviour was particularly unintuitive if one incorrectly passed an
adapter device name, or a device path, instead of a unit number.  In addition
to using strtoumax(3) instead of atoi(3) to parse unit numbers, support
stripping a device name (e.g. mps1) or path (e.g. /dev/mps2) to just its unit
number.

Reviewed by:	scottl (earlier version)
This commit is contained in:
Juli Mallett 2020-06-16 19:21:28 +00:00
parent 389f88cffd
commit e9de7669c3

View File

@ -37,6 +37,8 @@ __RCSID("$FreeBSD$");
#include <sys/param.h>
#include <sys/errno.h>
#include <err.h>
#include <inttypes.h>
#include <paths.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -91,6 +93,8 @@ int
main(int ac, char **av)
{
struct mpsutil_command **cmd;
uintmax_t unit;
char *end;
int ch;
is_mps = !strcmp(getprogname(), "mpsutil");
@ -98,7 +102,17 @@ main(int ac, char **av)
while ((ch = getopt(ac, av, "u:h?")) != -1) {
switch (ch) {
case 'u':
mps_unit = atoi(optarg);
if (strncmp(optarg, _PATH_DEV, strlen(_PATH_DEV)) == 0) {
optarg += strlen(_PATH_DEV);
if (strncmp(optarg, is_mps ? "mps" : "mpr", 3) != 0)
errx(1, "Invalid device: %s", optarg);
}
if (strncmp(optarg, is_mps ? "mps" : "mpr", 3) == 0)
optarg += 3;
unit = strtoumax(optarg, &end, 10);
if (*end != '\0' || unit == UINTMAX_MAX || unit > INT_MAX)
errx(1, "Invalid unit: %s", optarg);
mps_unit = unit;
break;
case 'h':
case '?':