From 40f09cb0f441ffcafb421e83bdc10ce939efe2d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=BD=D0=B0=D0=B1?= Date: Sat, 22 Jan 2022 23:44:33 +0100 Subject: [PATCH] zfs: list: only accept whole type for -t, not tp[=whatever] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Brian Behlendorf Signed-off-by: Ahelenia ZiemiaƄska Closes #12996 --- cmd/zfs/zfs_main.c | 61 +++++++++++++++++++--------------------------- 1 file changed, 25 insertions(+), 36 deletions(-) diff --git a/cmd/zfs/zfs_main.c b/cmd/zfs/zfs_main.c index 2db42dfc69..dd5d4de55d 100644 --- a/cmd/zfs/zfs_main.c +++ b/cmd/zfs/zfs_main.c @@ -498,7 +498,7 @@ usage_prop_cb(int prop, void *cb) * that command. Otherwise, iterate over the entire command table and display * a complete usage message. */ -static void +static _Noreturn void usage(boolean_t requested) { int i; @@ -3551,13 +3551,12 @@ static int zfs_do_list(int argc, char **argv) { int c; - static char default_fields[] = + char default_fields[] = "name,used,available,referenced,mountpoint"; int types = ZFS_TYPE_DATASET; boolean_t types_specified = B_FALSE; - char *fields = NULL; + char *fields = default_fields; list_cbdata_t cb = { 0 }; - char *value; int limit = 0; int ret = 0; zfs_sort_column_t *sortcol = NULL; @@ -3602,36 +3601,29 @@ zfs_do_list(int argc, char **argv) types = 0; types_specified = B_TRUE; flags &= ~ZFS_ITER_PROP_LISTSNAPS; - while (*optarg != '\0') { - static char *type_subopts[] = { "filesystem", - "volume", "snapshot", "snap", "bookmark", - "all", NULL }; - switch (getsubopt(&optarg, type_subopts, - &value)) { - case 0: - types |= ZFS_TYPE_FILESYSTEM; - break; - case 1: - types |= ZFS_TYPE_VOLUME; - break; - case 2: - case 3: - types |= ZFS_TYPE_SNAPSHOT; - break; - case 4: - types |= ZFS_TYPE_BOOKMARK; - break; - case 5: - types = ZFS_TYPE_DATASET | - ZFS_TYPE_BOOKMARK; - break; - default: - (void) fprintf(stderr, - gettext("invalid type '%s'\n"), - value); - usage(B_FALSE); - } + for (char *tok; (tok = strsep(&optarg, ",")); ) { + static const char *const type_subopts[] = { + "filesystem", "volume", + "snapshot", "snap", + "bookmark", + "all" }; + static const int type_types[] = { + ZFS_TYPE_FILESYSTEM, ZFS_TYPE_VOLUME, + ZFS_TYPE_SNAPSHOT, ZFS_TYPE_SNAPSHOT, + ZFS_TYPE_BOOKMARK, + ZFS_TYPE_DATASET | ZFS_TYPE_BOOKMARK }; + + for (c = 0; c < ARRAY_SIZE(type_subopts); ++c) + if (strcmp(tok, type_subopts[c]) == 0) { + types |= type_types[c]; + goto found3; + } + + (void) fprintf(stderr, + gettext("invalid type '%s'\n"), tok); + usage(B_FALSE); +found3:; } break; case ':': @@ -3649,9 +3641,6 @@ zfs_do_list(int argc, char **argv) argc -= optind; argv += optind; - if (fields == NULL) - fields = default_fields; - /* * If we are only going to list snapshot names and sort by name, * then we can use faster version.