svn commit: r332978 - stable/11/usr.sbin/makefs
Benno Rice
benno at FreeBSD.org
Wed Apr 25 01:20:26 UTC 2018
Author: benno
Date: Wed Apr 25 01:20:25 2018
New Revision: 332978
URL: https://svnweb.freebsd.org/changeset/base/332978
Log:
MFC r315304
makefs: sync option parsing with NetBSD
- add support for parsing different types; not just int
- homogenize option parsing
- fix single letter parsing
- remove duplicated code
NetBSD revisions:
cd9660.c 1.36 1.37 1.38 1.41 1.42 1.43
ffs.c 1.50 1.51 1.52 1.53 1.56 1.57
makefs.c 1.36 1.37 1.38 1.39 1.40 1.42 1.43 1.44 1.46
makefs.h 1.28 1.29 1.31 1.32
Sponsored by: iXsystems, Inc.
Modified:
stable/11/usr.sbin/makefs/cd9660.c
stable/11/usr.sbin/makefs/cd9660.h
stable/11/usr.sbin/makefs/ffs.c
stable/11/usr.sbin/makefs/makefs.c
stable/11/usr.sbin/makefs/makefs.h
Directory Properties:
stable/11/ (props changed)
Modified: stable/11/usr.sbin/makefs/cd9660.c
==============================================================================
--- stable/11/usr.sbin/makefs/cd9660.c Wed Apr 25 01:12:40 2018 (r332977)
+++ stable/11/usr.sbin/makefs/cd9660.c Wed Apr 25 01:20:25 2018 (r332978)
@@ -257,7 +257,70 @@ cd9660_prep_opts(fsinfo_t *fsopts)
if ((diskStructure = calloc(1, sizeof(*diskStructure))) == NULL)
err(EXIT_FAILURE, "%s: calloc", __func__);
+#define OPT_STR(letter, name, desc) \
+ { letter, name, NULL, OPT_STRBUF, 0, 0, desc }
+
+#define OPT_NUM(letter, name, field, min, max, desc) \
+ { letter, name, &diskStructure->field, \
+ sizeof(diskStructure->field) == 8 ? OPT_INT64 : \
+ (sizeof(diskStructure->field) == 4 ? OPT_INT32 : \
+ (sizeof(diskStructure->field) == 2 ? OPT_INT16 : OPT_INT8)), \
+ min, max, desc }
+
+#define OPT_BOOL(letter, name, field, desc) \
+ OPT_NUM(letter, name, field, 0, 1, desc)
+
+ const option_t cd9660_options[] = {
+ OPT_NUM('l', "isolevel", isoLevel,
+ 1, 2, "ISO Level"),
+ OPT_NUM('v', "verbose", verbose_level,
+ 0, 2, "Turns on verbose output"),
+
+ OPT_BOOL('h', "help", displayHelp,
+ "Show help message"),
+ OPT_BOOL('S', "follow-symlinks", follow_sym_links,
+ "Resolve symlinks in pathnames"),
+ OPT_BOOL('R', "rockridge", rock_ridge_enabled,
+ "Enable Rock-Ridge extensions"),
+ OPT_BOOL('C', "chrp-boot", chrp_boot,
+ "Enable CHRP boot"),
+ OPT_BOOL('K', "keep-bad-images", keep_bad_images,
+ "Keep bad images"),
+ OPT_BOOL('D', "allow-deep-trees", allow_deep_trees,
+ "Allow trees more than 8 levels"),
+ OPT_BOOL('a', "allow-max-name", allow_max_name,
+ "Allow 37 char filenames (unimplemented)"),
+ OPT_BOOL('i', "allow-illegal-chars", allow_illegal_chars,
+ "Allow illegal characters in filenames"),
+ OPT_BOOL('d', "allow-multidot", allow_multidot,
+ "Allow multiple periods in filenames"),
+ OPT_BOOL('o', "omit-trailing-period", omit_trailing_period,
+ "Omit trailing periods in filenames"),
+ OPT_BOOL('\0', "allow-lowercase", allow_lowercase,
+ "Allow lowercase characters in filenames"),
+ OPT_BOOL('\0', "archimedes", archimedes_enabled,
+ "Enable Archimedes structure"),
+ OPT_BOOL('\0', "no-trailing-padding", include_padding_areas,
+ "Include padding areas"),
+
+ OPT_STR('A', "applicationid", "Application Identifier"),
+ OPT_STR('P', "publisher", "Publisher Identifier"),
+ OPT_STR('p', "preparer", "Preparer Identifier"),
+ OPT_STR('L', "label", "Disk Label"),
+ OPT_STR('V', "volumeid", "Volume Set Identifier"),
+ OPT_STR('B', "bootimage", "Boot image parameter"),
+ OPT_STR('G', "generic-bootimage", "Generic boot image param"),
+ OPT_STR('\0', "bootimagedir", "Boot image directory"),
+ OPT_STR('\0', "no-emul-boot", "No boot emulation"),
+ OPT_STR('\0', "no-boot", "No boot support"),
+ OPT_STR('\0', "hard-disk-boot", "Boot from hard disk"),
+ OPT_STR('\0', "boot-load-segment", "Boot load segment"),
+
+ { .name = NULL }
+ };
+
fsopts->fs_specific = diskStructure;
+ fsopts->fs_options = copy_opts(cd9660_options);
cd9660_set_defaults(diskStructure);
}
@@ -266,6 +329,7 @@ void
cd9660_cleanup_opts(fsinfo_t *fsopts)
{
free(fsopts->fs_specific);
+ free(fsopts->fs_options);
}
static int
@@ -302,144 +366,106 @@ cd9660_arguments_set_string(const char *val, const cha
int
cd9660_parse_opts(const char *option, fsinfo_t *fsopts)
{
- char *var, *val;
- int rv;
+ int rv, i;
iso9660_disk *diskStructure = fsopts->fs_specific;
+ option_t *cd9660_options = fsopts->fs_options;
+ char buf[1024];
+ const char *name, *desc;
- /* Set up allowed options - integer options ONLY */
- option_t cd9660_options[] = {
- { "l", &diskStructure->isoLevel, 1, 2, "ISO Level" },
- { "isolevel", &diskStructure->isoLevel, 1, 2, "ISO Level" },
- { "verbose", &diskStructure->verbose_level, 0, 2,
- "Turns on verbose output" },
- { "v", &diskStructure->verbose_level, 0 , 2,
- "Turns on verbose output"},
- { .name = NULL }
- };
-
- /*
- * Todo : finish implementing this, and make a function that
- * parses them
- */
- /*
- string_option_t cd9660_string_options[] = {
- { "L", "Label", &diskStructure.primaryDescriptor.volume_id, 1, 32, "Disk Label", ISO_STRING_FILTER_DCHARS },
- { NULL }
- }
- */
-
assert(option != NULL);
if (debug & DEBUG_FS_PARSE_OPTS)
printf("cd9660_parse_opts: got `%s'\n", option);
- if ((var = strdup(option)) == NULL)
- err(1, "allocating memory for copy of option string");
- rv = 1;
+ i = set_option(cd9660_options, option, buf, sizeof(buf));
+ if (i == -1)
+ return 0;
- val = strchr(var, '=');
- if (val != NULL)
- *val++ = '\0';
+ if (cd9660_options[i].name == NULL)
+ abort();
- /* First handle options with no parameters */
- if (strcmp(var, "h") == 0) {
- diskStructure->displayHelp = 1;
- rv = 1;
- } else if (CD9660_IS_COMMAND_ARG_DUAL(var, "S", "follow-symlinks")) {
- /* this is not handled yet */
- diskStructure->follow_sym_links = 1;
- rv = 1;
- } else if (CD9660_IS_COMMAND_ARG_DUAL(var, "L", "label")) {
- rv = cd9660_arguments_set_string(val, "Disk Label", 32, 'd',
- diskStructure->primaryDescriptor.volume_id);
- } else if (CD9660_IS_COMMAND_ARG_DUAL(var, "A", "applicationid")) {
- rv = cd9660_arguments_set_string(val, "Application Identifier", 128, 'a',
- diskStructure->primaryDescriptor.application_id);
- } else if(CD9660_IS_COMMAND_ARG_DUAL(var, "P", "publisher")) {
- rv = cd9660_arguments_set_string(val, "Publisher Identifier",
- 128, 'a', diskStructure->primaryDescriptor.publisher_id);
- } else if (CD9660_IS_COMMAND_ARG_DUAL(var, "p", "preparer")) {
- rv = cd9660_arguments_set_string(val, "Preparer Identifier",
- 128, 'a', diskStructure->primaryDescriptor.preparer_id);
- } else if (CD9660_IS_COMMAND_ARG_DUAL(var, "V", "volumeid")) {
- rv = cd9660_arguments_set_string(val, "Volume Set Identifier",
- 128, 'a', diskStructure->primaryDescriptor.volume_set_id);
+ name = cd9660_options[i].name;
+ desc = cd9660_options[i].desc;
+ switch (cd9660_options[i].letter) {
+ case 'h':
+ case 'S':
+ rv = 0; /* this is not handled yet */
+ break;
+ case 'L':
+ rv = cd9660_arguments_set_string(buf, desc, 32, 'd',
+ diskStructure->primaryDescriptor.volume_id);
+ break;
+ case 'A':
+ rv = cd9660_arguments_set_string(buf, desc, 128, 'a',
+ diskStructure->primaryDescriptor.application_id);
+ break;
+ case 'P':
+ rv = cd9660_arguments_set_string(buf, desc, 128, 'a',
+ diskStructure->primaryDescriptor.publisher_id);
+ break;
+ case 'p':
+ rv = cd9660_arguments_set_string(buf, desc, 128, 'a',
+ diskStructure->primaryDescriptor.preparer_id);
+ break;
+ case 'V':
+ rv = cd9660_arguments_set_string(buf, desc, 128, 'a',
+ diskStructure->primaryDescriptor.volume_set_id);
+ break;
/* Boot options */
- } else if (CD9660_IS_COMMAND_ARG_DUAL(var, "B", "bootimage")) {
- if (val == NULL)
- warnx("error: The Boot Image parameter requires a valid boot information string");
- else
- rv = cd9660_add_boot_disk(diskStructure, val);
- } else if (CD9660_IS_COMMAND_ARG(var, "bootimagedir")) {
- /*
- * XXXfvdl this is unused.
- */
- if (val == NULL)
- errx(1, "error: The Boot Image Directory parameter"
- " requires a directory name\n");
- else {
- if ((diskStructure->boot_image_directory =
- malloc(strlen(val) + 1)) == NULL) {
- CD9660_MEM_ALLOC_ERROR("cd9660_parse_opts");
- exit(1);
- }
-
- /* BIG TODO: Add the max length function here */
- cd9660_arguments_set_string(val, "Boot Image Directory",
- 12 , 'd', diskStructure->boot_image_directory);
- }
- } else if (CD9660_IS_COMMAND_ARG_DUAL(var, "G", "generic-bootimage")) {
- if (val == NULL)
- warnx("error: The Boot Image parameter requires a valid boot information string");
- else
- rv = cd9660_add_generic_bootimage(diskStructure, val);
- } else if (CD9660_IS_COMMAND_ARG(var, "no-trailing-padding"))
- diskStructure->include_padding_areas = 0;
- /* RRIP */
- else if (CD9660_IS_COMMAND_ARG_DUAL(var, "R", "rockridge"))
- diskStructure->rock_ridge_enabled = 1;
- else if (CD9660_IS_COMMAND_ARG_DUAL(var, "A", "archimedes"))
- diskStructure->archimedes_enabled = 1;
- else if (CD9660_IS_COMMAND_ARG(var, "chrp-boot"))
- diskStructure->chrp_boot = 1;
- else if (CD9660_IS_COMMAND_ARG_DUAL(var, "K", "keep-bad-images"))
- diskStructure->keep_bad_images = 1;
- else if (CD9660_IS_COMMAND_ARG(var, "allow-deep-trees"))
- diskStructure->allow_deep_trees = 1;
- else if (CD9660_IS_COMMAND_ARG(var, "allow-max-name"))
- diskStructure->allow_max_name = 1;
- else if (CD9660_IS_COMMAND_ARG(var, "allow-illegal-chars"))
- diskStructure->allow_illegal_chars = 1;
- else if (CD9660_IS_COMMAND_ARG(var, "allow-lowercase"))
- diskStructure->allow_lowercase = 1;
- else if (CD9660_IS_COMMAND_ARG(var,"allow-multidot"))
- diskStructure->allow_multidot = 1;
- else if (CD9660_IS_COMMAND_ARG(var, "omit-trailing-period"))
- diskStructure->omit_trailing_period = 1;
- else if (CD9660_IS_COMMAND_ARG(var, "no-emul-boot") ||
- CD9660_IS_COMMAND_ARG(var, "no-boot") ||
- CD9660_IS_COMMAND_ARG(var, "hard-disk-boot")) {
- cd9660_eltorito_add_boot_option(diskStructure, var, 0);
-
- /* End of flag variables */
- } else if (CD9660_IS_COMMAND_ARG(var, "boot-load-segment")) {
- if (val == NULL) {
- warnx("Option `%s' doesn't contain a value", var);
+ case 'B':
+ if (buf[0] == '\0') {
+ warnx("The Boot Image parameter requires a valid boot"
+ "information string");
rv = 0;
- } else {
- cd9660_eltorito_add_boot_option(diskStructure, var,
- val);
- }
- } else {
- if (val == NULL) {
- warnx("Option `%s' doesn't contain a value", var);
+ } else
+ rv = cd9660_add_boot_disk(diskStructure, buf);
+ break;
+ case 'G':
+ if (buf[0] == '\0') {
+ warnx("The Generic Boot Image parameter requires a"
+ " valid boot information string");
rv = 0;
} else
- rv = set_option(cd9660_options, var, val);
+ rv = cd9660_add_generic_bootimage(diskStructure, buf);
+ break;
+ default:
+ if (strcmp(name, "bootimagedir") == 0) {
+ /*
+ * XXXfvdl this is unused.
+ */
+ if (buf[0] == '\0') {
+ warnx("The Boot Image Directory parameter"
+ " requires a directory name\n");
+ rv = 0;
+ } else {
+ diskStructure->boot_image_directory =
+ malloc(strlen(buf) + 1);
+ if (diskStructure->boot_image_directory == NULL)
+ err(1, "malloc");
+ /* BIG TODO: Add the max length function here */
+ rv = cd9660_arguments_set_string(buf, desc, 12,
+ 'd', diskStructure->boot_image_directory);
+ }
+ } else if (strcmp(name, "no-emul-boot") == 0 ||
+ strcmp(name, "no-boot") == 0 ||
+ strcmp(name, "hard-disk-boot") == 0) {
+ /* RRIP */
+ cd9660_eltorito_add_boot_option(diskStructure, name, 0);
+ rv = 1;
+ } else if (strcmp(name, "boot-load-segment") == 0) {
+ if (buf[0] == '\0') {
+ warnx("Option `%s' doesn't contain a value",
+ name);
+ rv = 0;
+ } else {
+ cd9660_eltorito_add_boot_option(diskStructure,
+ name, buf);
+ rv = 1;
+ }
+ } else
+ rv = 1;
}
-
- free(var);
- return (rv);
+ return rv;
}
/*
Modified: stable/11/usr.sbin/makefs/cd9660.h
==============================================================================
--- stable/11/usr.sbin/makefs/cd9660.h Wed Apr 25 01:12:40 2018 (r332977)
+++ stable/11/usr.sbin/makefs/cd9660.h Wed Apr 25 01:20:25 2018 (r332978)
@@ -122,12 +122,6 @@ typedef struct {
#define CD9660_MEM_ALLOC_ERROR(_F) \
err(EXIT_FAILURE, "%s, %s l. %d", _F, __FILE__, __LINE__)
-#define CD9660_IS_COMMAND_ARG_DUAL(var,short,long)\
- (strcmp((var),(short)) == 0) || (strcmp((var),(long))==0)
-
-#define CD9660_IS_COMMAND_ARG(var,arg)\
- (strcmp((var),(arg)) == 0)
-
#define CD9660_TYPE_FILE 0x01
#define CD9660_TYPE_DIR 0x02
#define CD9660_TYPE_DOT 0x04
Modified: stable/11/usr.sbin/makefs/ffs.c
==============================================================================
--- stable/11/usr.sbin/makefs/ffs.c Wed Apr 25 01:12:40 2018 (r332977)
+++ stable/11/usr.sbin/makefs/ffs.c Wed Apr 25 01:20:25 2018 (r332978)
@@ -144,7 +144,6 @@ static void *ffs_build_dinode2(struct ufs2_dinode *,
int sectorsize; /* XXX: for buf.c::getblk() */
-
/* publicly visible functions */
void
@@ -155,7 +154,33 @@ ffs_prep_opts(fsinfo_t *fsopts)
if ((ffs_opts = calloc(1, sizeof(ffs_opt_t))) == NULL)
err(1, "Allocating memory for ffs_options");
- fsopts->fs_specific = ffs_opts;
+ const option_t ffs_options[] = {
+ { 'b', "bsize", &ffs_opts->bsize, OPT_INT32,
+ 1, INT_MAX, "block size" },
+ { 'f', "fsize", &ffs_opts->fsize, OPT_INT32,
+ 1, INT_MAX, "fragment size" },
+ { 'd', "density", &ffs_opts->density, OPT_INT32,
+ 1, INT_MAX, "bytes per inode" },
+ { 'm', "minfree", &ffs_opts->minfree, OPT_INT32,
+ 0, 99, "minfree" },
+ { 'M', "maxbpg", &ffs_opts->maxbpg, OPT_INT32,
+ 1, INT_MAX, "max blocks per file in a cg" },
+ { 'a', "avgfilesize", &ffs_opts->avgfilesize, OPT_INT32,
+ 1, INT_MAX, "expected average file size" },
+ { 'n', "avgfpdir", &ffs_opts->avgfpdir, OPT_INT32,
+ 1, INT_MAX, "expected # of files per directory" },
+ { 'x', "extent", &ffs_opts->maxbsize, OPT_INT32,
+ 1, INT_MAX, "maximum # extent size" },
+ { 'g', "maxbpcg", &ffs_opts->maxblkspercg, OPT_INT32,
+ 1, INT_MAX, "max # of blocks per group" },
+ { 'v', "version", &ffs_opts->version, OPT_INT32,
+ 1, 2, "UFS version" },
+ { 'o', "optimization", NULL, OPT_STRBUF,
+ 0, 0, "Optimization (time|space)" },
+ { 'l', "label", ffs_opts->label, OPT_STRARRAY,
+ 1, sizeof(ffs_opts->label), "UFS label" },
+ { .name = NULL }
+ };
ffs_opts->bsize= -1;
ffs_opts->fsize= -1;
@@ -168,45 +193,25 @@ ffs_prep_opts(fsinfo_t *fsopts)
ffs_opts->avgfilesize= -1;
ffs_opts->avgfpdir= -1;
ffs_opts->version = 1;
+
+ fsopts->fs_specific = ffs_opts;
+ fsopts->fs_options = copy_opts(ffs_options);
}
void
ffs_cleanup_opts(fsinfo_t *fsopts)
{
- if (fsopts->fs_specific)
- free(fsopts->fs_specific);
+ free(fsopts->fs_specific);
+ free(fsopts->fs_options);
}
int
ffs_parse_opts(const char *option, fsinfo_t *fsopts)
{
ffs_opt_t *ffs_opts = fsopts->fs_specific;
+ option_t *ffs_options = fsopts->fs_options;
+ char buf[1024];
- option_t ffs_options[] = {
- { "bsize", &ffs_opts->bsize, 1, INT_MAX,
- "block size" },
- { "fsize", &ffs_opts->fsize, 1, INT_MAX,
- "fragment size" },
- { "density", &ffs_opts->density, 1, INT_MAX,
- "bytes per inode" },
- { "minfree", &ffs_opts->minfree, 0, 99,
- "minfree" },
- { "maxbpg", &ffs_opts->maxbpg, 1, INT_MAX,
- "max blocks per file in a cg" },
- { "avgfilesize", &ffs_opts->avgfilesize,1, INT_MAX,
- "expected average file size" },
- { "avgfpdir", &ffs_opts->avgfpdir, 1, INT_MAX,
- "expected # of files per directory" },
- { "extent", &ffs_opts->maxbsize, 1, INT_MAX,
- "maximum # extent size" },
- { "maxbpcg", &ffs_opts->maxblkspercg,1, INT_MAX,
- "max # of blocks per group" },
- { "version", &ffs_opts->version, 1, 2,
- "UFS version" },
- { .name = NULL }
- };
-
- char *var, *val;
int rv;
assert(option != NULL);
@@ -216,36 +221,28 @@ ffs_parse_opts(const char *option, fsinfo_t *fsopts)
if (debug & DEBUG_FS_PARSE_OPTS)
printf("ffs_parse_opts: got `%s'\n", option);
- if ((var = strdup(option)) == NULL)
- err(1, "Allocating memory for copy of option string");
- rv = 0;
+ rv = set_option(ffs_options, option, buf, sizeof(buf));
+ if (rv == -1)
+ return 0;
- if ((val = strchr(var, '=')) == NULL) {
- warnx("Option `%s' doesn't contain a value", var);
- goto leave_ffs_parse_opts;
- }
- *val++ = '\0';
+ if (ffs_options[rv].name == NULL)
+ abort();
- if (strcmp(var, "optimization") == 0) {
- if (strcmp(val, "time") == 0) {
+ switch (ffs_options[rv].letter) {
+ case 'o':
+ if (strcmp(buf, "time") == 0) {
ffs_opts->optimization = FS_OPTTIME;
- } else if (strcmp(val, "space") == 0) {
+ } else if (strcmp(buf, "space") == 0) {
ffs_opts->optimization = FS_OPTSPACE;
} else {
- warnx("Invalid optimization `%s'", val);
- goto leave_ffs_parse_opts;
+ warnx("Invalid optimization `%s'", buf);
+ return 0;
}
- rv = 1;
- } else if (strcmp(var, "label") == 0) {
- strlcpy(ffs_opts->label, val, sizeof(ffs_opts->label));
- rv = 1;
- } else
- rv = set_option(ffs_options, var, val);
-
- leave_ffs_parse_opts:
- if (var)
- free(var);
- return (rv);
+ break;
+ default:
+ break;
+ }
+ return 1;
}
Modified: stable/11/usr.sbin/makefs/makefs.c
==============================================================================
--- stable/11/usr.sbin/makefs/makefs.c Wed Apr 25 01:12:40 2018 (r332977)
+++ stable/11/usr.sbin/makefs/makefs.c Wed Apr 25 01:20:25 2018 (r332978)
@@ -51,6 +51,7 @@ __FBSDID("$FreeBSD$");
#include <string.h>
#include <time.h>
#include <unistd.h>
+#include <stdbool.h>
#include "makefs.h"
#include "mtree.h"
@@ -84,7 +85,7 @@ struct stat stampst;
static fstype_t *get_fstype(const char *);
static int get_tstamp(const char *, struct stat *);
-static void usage(void);
+static void usage(fstype_t *, fsinfo_t *);
int main(int, char *[]);
int
@@ -140,7 +141,7 @@ main(int argc, char *argv[])
#endif
} else {
warnx("Invalid endian `%s'.", optarg);
- usage();
+ usage(fstype, &fsoptions);
}
break;
@@ -209,7 +210,7 @@ main(int argc, char *argv[])
if (*p == '\0')
errx(1, "Empty option");
if (! fstype->parse_options(p, &fsoptions))
- usage();
+ usage(fstype, &fsoptions);
}
break;
}
@@ -262,7 +263,7 @@ main(int argc, char *argv[])
case '?':
default:
- usage();
+ usage(fstype, &fsoptions);
/* NOTREACHED */
}
@@ -277,7 +278,7 @@ main(int argc, char *argv[])
argv += optind;
if (argc < 2)
- usage();
+ usage(fstype, &fsoptions);
/* -x must be accompanied by -F */
if (fsoptions.onlyspec != 0 && specfile == NULL)
@@ -343,21 +344,84 @@ main(int argc, char *argv[])
/* NOTREACHED */
}
+int
+set_option(const option_t *options, const char *option, char *buf, size_t len)
+{
+ char *var, *val;
+ int retval;
+ assert(option != NULL);
+
+ if ((var = strdup(option)) == NULL) {
+ err(EXIT_FAILURE, "Allocating memory for copy of option string");
+ }
+
+ for (val = var; *val; val++)
+ if (*val == '=') {
+ *val++ = '\0';
+ break;
+ }
+ retval = set_option_var(options, var, val, buf, len);
+ free(var);
+ return retval;
+}
+
int
-set_option(option_t *options, const char *var, const char *val)
+set_option_var(const option_t *options, const char *var, const char *val,
+ char *buf, size_t len)
{
- int i;
+ char *s;
+ size_t i;
+#define NUM(type) \
+ if (!*val) { \
+ *(type *)options[i].value = 1; \
+ break; \
+ } \
+ *(type *)options[i].value = (type)strsuftoll(options[i].desc, val, \
+ options[i].minimum, options[i].maximum); break
+
for (i = 0; options[i].name != NULL; i++) {
- if (strcmp(options[i].name, var) != 0)
+ if (var[1] == '\0') {
+ if (options[i].letter != var[0])
+ continue;
+ } else if (strcmp(options[i].name, var) != 0)
continue;
- *options[i].value = (int)strsuftoll(options[i].desc, val,
- options[i].minimum, options[i].maximum);
- return (1);
+ switch (options[i].type) {
+ case OPT_BOOL:
+ *(bool *)options[i].value = 1;
+ break;
+ case OPT_STRARRAY:
+ strlcpy((void *)options[i].value, val, (size_t)
+ options[i].maximum);
+ break;
+ case OPT_STRPTR:
+ if ((s = strdup(val)) == NULL)
+ err(1, NULL);
+ *(char **)options[i].value = s;
+ break;
+ case OPT_STRBUF:
+ if (buf == NULL)
+ abort();
+ strlcpy(buf, val, len);
+ break;
+ case OPT_INT64:
+ NUM(uint64_t);
+ case OPT_INT32:
+ NUM(uint32_t);
+ case OPT_INT16:
+ NUM(uint16_t);
+ case OPT_INT8:
+ NUM(uint8_t);
+ default:
+ warnx("Unknown type %d in option %s", options[i].type,
+ val);
+ return 0;
+ }
+ return i;
}
warnx("Unknown option `%s'", var);
- return (0);
+ return -1;
}
@@ -372,6 +436,20 @@ get_fstype(const char *type)
return (NULL);
}
+option_t *
+copy_opts(const option_t *o)
+{
+ size_t i;
+ void *rv;
+
+ for (i = 0; o[i].name; i++)
+ continue;
+ i++;
+ if ((rv = calloc(i, sizeof(*o))) == NULL)
+ err(1, "calloc");
+ return memcpy(rv, o, i * sizeof(*o));
+}
+
static int
get_tstamp(const char *b, struct stat *st)
{
@@ -399,17 +477,29 @@ get_tstamp(const char *b, struct stat *st)
}
static void
-usage(void)
+usage(fstype_t *fstype, fsinfo_t *fsoptions)
{
const char *prog;
prog = getprogname();
fprintf(stderr,
-"usage: %s [-xZ] [-B endian] [-b free-blocks] [-d debug-mask]\n"
+"Usage: %s [-xZ] [-B endian] [-b free-blocks] [-d debug-mask]\n"
"\t[-F mtree-specfile] [-f free-files] [-M minimum-size] [-m maximum-size]\n"
"\t[-N userdb-dir] [-o fs-options] [-R roundup-size] [-S sector-size]\n"
"\t[-s image-size] [-T <timestamp/file>] [-t fs-type]\n"
"\timage-file directory | manifest [extra-directory ...]\n",
prog);
+
+ if (fstype) {
+ size_t i;
+ option_t *o = fsoptions->fs_options;
+
+ fprintf(stderr, "\n%s specific options:\n", fstype->type);
+ for (i = 0; o[i].name != NULL; i++)
+ fprintf(stderr, "\t%c%c%20.20s\t%s\n",
+ o[i].letter ? o[i].letter : ' ',
+ o[i].letter ? ',' : ' ',
+ o[i].name, o[i].desc);
+ }
exit(1);
}
Modified: stable/11/usr.sbin/makefs/makefs.h
==============================================================================
--- stable/11/usr.sbin/makefs/makefs.h Wed Apr 25 01:12:40 2018 (r332977)
+++ stable/11/usr.sbin/makefs/makefs.h Wed Apr 25 01:20:25 2018 (r332978)
@@ -106,11 +106,37 @@ typedef struct _fsnode {
#define FSNODE_F_OPTIONAL 0x02 /* fsnode is optional */
/*
+ * option_t - contains option name, description, pointer to location to store
+ * result, and range checks for the result. Used to simplify fs specific
+ * option setting
+ */
+typedef enum {
+ OPT_STRARRAY,
+ OPT_STRPTR,
+ OPT_STRBUF,
+ OPT_BOOL,
+ OPT_INT8,
+ OPT_INT16,
+ OPT_INT32,
+ OPT_INT64
+} opttype_t;
+
+typedef struct {
+ char letter; /* option letter NUL for none */
+ const char *name; /* option name */
+ void *value; /* where to stuff the value */
+ opttype_t type; /* type of entry */
+ long long minimum; /* minimum for value */
+ long long maximum; /* maximum for value */
+ const char *desc; /* option description */
+} option_t;
+
+/*
* fsinfo_t - contains various settings and parameters pertaining to
* the image, including current settings, global options, and fs
* specific options
*/
-typedef struct {
+typedef struct makefs_fsinfo {
/* current settings */
off_t size; /* total size */
off_t inodes; /* number of inodes */
@@ -135,30 +161,20 @@ typedef struct {
int sparse; /* sparse image, don't fill it with zeros */
void *fs_specific; /* File system specific additions. */
+ option_t *fs_options; /* File system specific options */
} fsinfo_t;
-/*
- * option_t - contains option name, description, pointer to location to store
- * result, and range checks for the result. Used to simplify fs specific
- * option setting
- */
-typedef struct {
- const char *name; /* option name */
- int *value; /* where to stuff the value */
- int minimum; /* minimum for value */
- int maximum; /* maximum for value */
- const char *desc; /* option description */
-} option_t;
-
-
void apply_specfile(const char *, const char *, fsnode *, int);
void dump_fsnodes(fsnode *);
const char * inode_type(mode_t);
fsnode * read_mtree(const char *, fsnode *);
-int set_option(option_t *, const char *, const char *);
+int set_option(const option_t *, const char *, char *, size_t);
+int set_option_var(const option_t *, const char *, const char *,
+ char *, size_t);
fsnode * walk_dir(const char *, const char *, fsnode *, fsnode *);
void free_fsnodes(fsnode *);
+option_t * copy_opts(const option_t *);
void ffs_prep_opts(fsinfo_t *);
int ffs_parse_opts(const char *, fsinfo_t *);
More information about the svn-src-stable
mailing list