diff --git a/usr.sbin/makefs/Makefile b/usr.sbin/makefs/Makefile index 42f30273458e..b34f36504194 100644 --- a/usr.sbin/makefs/Makefile +++ b/usr.sbin/makefs/Makefile @@ -1,4 +1,4 @@ -# $NetBSD: Makefile,v 1.31 2012/04/19 17:28:25 christos Exp $ +# $NetBSD: Makefile,v 1.32 2013/01/23 20:46:39 christos Exp $ # WARNS?= 5 @@ -6,7 +6,7 @@ WARNS?= 5 .include PROG= makefs -SRCS= cd9660.c chfs.c ffs.c v7fs.c \ +SRCS= cd9660.c chfs.c ffs.c v7fs.c msdos.c \ getid.c \ makefs.c misc.c \ pack_dev.c \ @@ -24,6 +24,7 @@ CPPFLAGS+= -I${.CURDIR} -I${MKNODSRC} -I${MTREESRC} .include "${.CURDIR}/chfs/Makefile.inc" .include "${.CURDIR}/ffs/Makefile.inc" .include "${.CURDIR}/v7fs/Makefile.inc" +.include "${.CURDIR}/msdos/Makefile.inc" .if !defined(HOSTPROG) DPADD+= ${LIBUTIL} diff --git a/usr.sbin/makefs/cd9660.c b/usr.sbin/makefs/cd9660.c index 8c5bd3b71080..50e91c8c6727 100644 --- a/usr.sbin/makefs/cd9660.c +++ b/usr.sbin/makefs/cd9660.c @@ -1,4 +1,4 @@ -/* $NetBSD: cd9660.c,v 1.35 2012/01/28 02:35:46 christos Exp $ */ +/* $NetBSD: cd9660.c,v 1.36 2013/01/23 20:46:39 christos Exp $ */ /* * Copyright (c) 2005 Daniel Watt, Walter Deignan, Ryan Gabrys, Alan @@ -103,7 +103,7 @@ #include #if defined(__RCSID) && !defined(__lint) -__RCSID("$NetBSD: cd9660.c,v 1.35 2012/01/28 02:35:46 christos Exp $"); +__RCSID("$NetBSD: cd9660.c,v 1.36 2013/01/23 20:46:39 christos Exp $"); #endif /* !__lint */ #include @@ -304,29 +304,20 @@ cd9660_parse_opts(const char *option, fsinfo_t *fsopts) int rv; /* Set up allowed options - integer options ONLY */ option_t cd9660_options[] = { - { "l", &diskStructure.isoLevel, 1, 3, "ISO Level" }, - { "isolevel", &diskStructure.isoLevel, 1, 3, "ISO Level" }, - { "verbose", &diskStructure.verbose_level, 0, 2, - "Turns on verbose output" }, - { "v", &diskStructure.verbose_level, 0 , 2, - "Turns on verbose output"}, + { 'l', "isolevel", &diskStructure.isoLevel, + OPT_INT32, 1, 3, "ISO Level" }, + { 'v', "verbose", &diskStructure.verbose_level, + OPT_INT32, 0, 2, "Turns on verbose output" }, + { 'L', "Label", diskStructure.primaryDescriptor.volume_id, + OPT_STRARRAY, 1, + sizeof(diskStructure.primaryDescriptor.volume_id), + "Disk Label" }, { .name = NULL } }; if (cd9660_defaults_set == 0) cd9660_set_defaults(); - /* - * 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) diff --git a/usr.sbin/makefs/chfs.c b/usr.sbin/makefs/chfs.c index c7712e9c4d71..b6f638af5aca 100644 --- a/usr.sbin/makefs/chfs.c +++ b/usr.sbin/makefs/chfs.c @@ -74,10 +74,12 @@ int chfs_parse_opts(const char *option, fsinfo_t *fsopts) { static const option_t chfs_options[] = { - { "pagesize", &chfs_opts.pagesize, 1, INT_MAX, "page size" }, - { "eraseblock", &chfs_opts.eraseblock, 1, INT_MAX, "eraseblock size" }, - { "mediatype", &chfs_opts.mediatype, 0, 1, - "type of the media, 0 (nor) or 1 (nand)" }, + { 'p', "pagesize", &chfs_opts.pagesize, OPT_INT32, + 1, INT_MAX, "page size" }, + { 'e', "eraseblock", &chfs_opts.eraseblock, OPT_INT32, + 1, INT_MAX, "eraseblock size" }, + { 'm', "mediatype", &chfs_opts.mediatype, OPT_INT32, + 0, 1, "type of the media, 0 (nor) or 1 (nand)" }, { .name = NULL } }; diff --git a/usr.sbin/makefs/ffs.c b/usr.sbin/makefs/ffs.c index 7f724abe9215..83256ddfc8cb 100644 --- a/usr.sbin/makefs/ffs.c +++ b/usr.sbin/makefs/ffs.c @@ -1,4 +1,4 @@ -/* $NetBSD: ffs.c,v 1.49 2013/01/22 09:39:19 dholland Exp $ */ +/* $NetBSD: ffs.c,v 1.50 2013/01/23 20:46:39 christos Exp $ */ /* * Copyright (c) 2001 Wasabi Systems, Inc. @@ -71,7 +71,7 @@ #include #if defined(__RCSID) && !defined(__lint) -__RCSID("$NetBSD: ffs.c,v 1.49 2013/01/22 09:39:19 dholland Exp $"); +__RCSID("$NetBSD: ffs.c,v 1.50 2013/01/23 20:46:39 christos Exp $"); #endif /* !__lint */ #include @@ -188,27 +188,27 @@ ffs_parse_opts(const char *option, fsinfo_t *fsopts) ffs_opt_t *ffs_opts = fsopts->fs_specific; 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" }, - { "maxbpf", &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 } + { '\0', "bsize", &ffs_opts->bsize, OPT_INT32, + 1, INT_MAX, "block size" }, + { '\0', "fsize", &ffs_opts->fsize, OPT_INT32, + 1, INT_MAX, "fragment size" }, + { '\0', "density", &ffs_opts->density, OPT_INT32, + 1, INT_MAX, "bytes per inode" }, + { '\0', "minfree", &ffs_opts->minfree, OPT_INT32, + 0, 99, "minfree" }, + { '\0', "maxbpf", &ffs_opts->maxbpg, OPT_INT32, + 1, INT_MAX, "max blocks per file in a cg" }, + { '\0', "avgfilesize", &ffs_opts->avgfilesize, OPT_INT32, + 1, INT_MAX, "expected average file size" }, + { '\0', "avgfpdir", &ffs_opts->avgfpdir, OPT_INT32, + 1, INT_MAX, "expected # of files per directory" }, + { '\0', "extent", &ffs_opts->maxbsize, OPT_INT32, + 1, INT_MAX, "maximum # extent size" }, + { '\0', "maxbpcg", &ffs_opts->maxblkspercg, OPT_INT32, + 1, INT_MAX, "max # of blocks per group" }, + { '\0', "version", &ffs_opts->version, OPT_INT32, + 1, 2, "UFS version" }, + { .name = NULL } }; char *var, *val; diff --git a/usr.sbin/makefs/makefs.c b/usr.sbin/makefs/makefs.c index ac8847608258..1b486ede15f2 100644 --- a/usr.sbin/makefs/makefs.c +++ b/usr.sbin/makefs/makefs.c @@ -1,4 +1,4 @@ -/* $NetBSD: makefs.c,v 1.35 2012/06/22 06:15:18 sjg Exp $ */ +/* $NetBSD: makefs.c,v 1.36 2013/01/23 20:46:39 christos Exp $ */ /* * Copyright (c) 2001-2003 Wasabi Systems, Inc. @@ -41,7 +41,7 @@ #include #if defined(__RCSID) && !defined(__lint) -__RCSID("$NetBSD: makefs.c,v 1.35 2012/06/22 06:15:18 sjg Exp $"); +__RCSID("$NetBSD: makefs.c,v 1.36 2013/01/23 20:46:39 christos Exp $"); #endif /* !__lint */ #include @@ -52,6 +52,7 @@ __RCSID("$NetBSD: makefs.c,v 1.35 2012/06/22 06:15:18 sjg Exp $"); #include #include #include +#include #include "makefs.h" #include "mtree.h" @@ -70,13 +71,15 @@ typedef struct { } fstype_t; static fstype_t fstypes[] = { - { "ffs", ffs_prep_opts, ffs_parse_opts, ffs_cleanup_opts, ffs_makefs }, - { "cd9660", cd9660_prep_opts, cd9660_parse_opts, cd9660_cleanup_opts, - cd9660_makefs}, - { "chfs", chfs_prep_opts, chfs_parse_opts, chfs_cleanup_opts, - chfs_makefs }, - { "v7fs", v7fs_prep_opts, v7fs_parse_opts, v7fs_cleanup_opts, - v7fs_makefs }, +#define ENTRY(name) { \ + # name, name ## _prep_opts, name ## _parse_opts, \ + name ## _cleanup_opts, name ## _makefs \ +} + ENTRY(ffs), + ENTRY(cd9660), + ENTRY(chfs), + ENTRY(v7fs), + ENTRY(msdos), { .type = NULL }, }; @@ -301,14 +304,46 @@ main(int argc, char *argv[]) int set_option(const option_t *options, const char *var, const char *val) { - int i; + char *s; + size_t i; + +#define NUM(width) *(uint ## width ## _t *)options[i].value = \ + (uint ## width ## _t)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 (options[i].letter != var[0] || var[1] != '\0') continue; - *options[i].value = (int)strsuftoll(options[i].desc, val, - options[i].minimum, options[i].maximum); - return (1); + else if (strcmp(options[i].name, var) != 0) + continue; + 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_INT64: + NUM(64); + case OPT_INT32: + NUM(32); + case OPT_INT16: + NUM(16); + case OPT_INT8: + NUM(8); + default: + warnx("Unknown type %d in option %s", options[i].type, + val); + return 0; + } + return 1; } warnx("Unknown option `%s'", var); return (0); diff --git a/usr.sbin/makefs/makefs.h b/usr.sbin/makefs/makefs.h index 3ba2ea23b393..c780fafab59b 100644 --- a/usr.sbin/makefs/makefs.h +++ b/usr.sbin/makefs/makefs.h @@ -1,4 +1,4 @@ -/* $NetBSD: makefs.h,v 1.27 2012/06/22 06:15:18 sjg Exp $ */ +/* $NetBSD: makefs.h,v 1.28 2013/01/23 20:46:39 christos Exp $ */ /* * Copyright (c) 2001 Wasabi Systems, Inc. @@ -147,11 +147,23 @@ typedef struct { * result, and range checks for the result. Used to simplify fs specific * option setting */ +typedef enum { + OPT_STRARRAY, + OPT_STRPTR, + 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 */ - int *value; /* where to stuff the value */ - int minimum; /* minimum for value */ - int maximum; /* maximum for value */ + 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; @@ -163,25 +175,17 @@ int set_option(const option_t *, const char *, const char *); fsnode * walk_dir(const char *, const char *, fsnode *, fsnode *); void free_fsnodes(fsnode *); -void ffs_prep_opts(fsinfo_t *); -int ffs_parse_opts(const char *, fsinfo_t *); -void ffs_cleanup_opts(fsinfo_t *); -void ffs_makefs(const char *, const char *, fsnode *, fsinfo_t *); +#define DECLARE_FUN(fs) \ +void fs ## _prep_opts(fsinfo_t *); \ +int fs ## _parse_opts(const char *, fsinfo_t *); \ +void fs ## _cleanup_opts(fsinfo_t *); \ +void fs ## _makefs(const char *, const char *, fsnode *, fsinfo_t *) -void cd9660_prep_opts(fsinfo_t *); -int cd9660_parse_opts(const char *, fsinfo_t *); -void cd9660_cleanup_opts(fsinfo_t *); -void cd9660_makefs(const char *, const char *, fsnode *, fsinfo_t *); - -void chfs_prep_opts(fsinfo_t *); -int chfs_parse_opts(const char *, fsinfo_t *); -void chfs_cleanup_opts(fsinfo_t *); -void chfs_makefs(const char *, const char *, fsnode *, fsinfo_t *); - -void v7fs_prep_opts(fsinfo_t *); -int v7fs_parse_opts(const char *, fsinfo_t *); -void v7fs_cleanup_opts(fsinfo_t *); -void v7fs_makefs(const char *, const char *, fsnode *, fsinfo_t *); +DECLARE_FUN(ffs); +DECLARE_FUN(cd9660); +DECLARE_FUN(chfs); +DECLARE_FUN(v7fs); +DECLARE_FUN(msdos); extern u_int debug; extern struct timespec start_time; diff --git a/usr.sbin/makefs/msdos.c b/usr.sbin/makefs/msdos.c new file mode 100644 index 000000000000..bacbea945e03 --- /dev/null +++ b/usr.sbin/makefs/msdos.c @@ -0,0 +1,166 @@ +/* $NetBSD: msdos.c,v 1.1 2013/01/23 20:46:39 christos Exp $ */ + +/*- + * Copyright (c) 2013 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#if HAVE_NBTOOL_CONFIG_H +#include "nbtool_config.h" +#endif + +#include +#if defined(__RCSID) && !defined(__lint) +__RCSID("$NetBSD: msdos.c,v 1.1 2013/01/23 20:46:39 christos Exp $"); +#endif /* !__lint */ + +#include + +#if !HAVE_NBTOOL_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "makefs.h" +#include "mkfs_msdos.h" + +void +msdos_prep_opts(fsinfo_t *fsopts) +{ + struct msdos_options *msdos_opts; + + if ((msdos_opts = calloc(1, sizeof(*msdos_opts))) == NULL) + err(1, "Allocating memory for msdos_options"); + + fsopts->fs_specific = msdos_opts; +} + +void +msdos_cleanup_opts(fsinfo_t *fsopts) +{ + if (fsopts->fs_specific) + free(fsopts->fs_specific); +} + +int +msdos_parse_opts(const char *option, fsinfo_t *fsopts) +{ + struct msdos_options *msdos_opt = fsopts->fs_specific; + + option_t msdos_options[] = { +#define AOPT(_opt, _type, _name, _min, _desc) { \ + .letter = _opt, \ + .name = # _name, \ + .type = _min == -1 ? OPT_STRPTR : \ + (_min == -2 ? OPT_BOOL : \ + (sizeof(_type) == 1 ? OPT_INT8 : \ + (sizeof(_type) == 2 ? OPT_INT16 : \ + (sizeof(_type) == 4 ? OPT_INT32 : OPT_INT64)))), \ + .value = &msdos_opt->_name, \ + .minimum = _min, \ + .maximum = sizeof(_type) == 1 ? 0xff : \ + (sizeof(_type) == 2 ? 0xffff : \ + (sizeof(_type) == 4 ? 0xffffffff : 0xffffffffffffffffLL)), \ + .desc = _desc, \ +}, +ALLOPTS +#undef AOPT + { .name = NULL } + }; + + assert(option != NULL); + assert(fsopts != NULL); + assert(msdos_opt != NULL); + + if (debug & DEBUG_FS_PARSE_OPTS) + printf("msdos_parse_opts: got `%s'\n", option); + + set_option(msdos_options, option, "1"); + + return 1; +} + + +void +msdos_makefs(const char *image, const char *dir, fsnode *root, fsinfo_t *fsopts) +{ +#ifdef notyet + struct fs *superblock; + struct timeval start; + + assert(image != NULL); + assert(dir != NULL); + assert(root != NULL); + assert(fsopts != NULL); + + if (debug & DEBUG_FS_MAKEFS) + printf("msdos_makefs: image %s directory %s root %p\n", + image, dir, root); + + /* validate tree and options */ + TIMER_START(start); + msdos_validate(dir, root, fsopts); + TIMER_RESULTS(start, "msdos_validate"); + + printf("Calculated size of `%s': %lld bytes, %lld inodes\n", + image, (long long)fsopts->size, (long long)fsopts->inodes); + + /* create image */ + TIMER_START(start); + if (msdos_create_image(image, fsopts) == -1) + errx(1, "Image file `%s' not created.", image); + TIMER_RESULTS(start, "msdos_create_image"); + + fsopts->curinode = ROOTINO; + + if (debug & DEBUG_FS_MAKEFS) + putchar('\n'); + + /* populate image */ + printf("Populating `%s'\n", image); + TIMER_START(start); + if (! msdos_populate_dir(dir, root, fsopts)) + errx(1, "Image file `%s' not populated.", image); + TIMER_RESULTS(start, "msdos_populate_dir"); + + /* ensure no outstanding buffers remain */ + if (debug & DEBUG_FS_MAKEFS) + bcleanup(); + + printf("Image `%s' complete\n", image); +#endif +} diff --git a/usr.sbin/makefs/msdos/Makefile.inc b/usr.sbin/makefs/msdos/Makefile.inc new file mode 100644 index 000000000000..ea4f312a5b5a --- /dev/null +++ b/usr.sbin/makefs/msdos/Makefile.inc @@ -0,0 +1,9 @@ +# $NetBSD: Makefile.inc,v 1.1 2013/01/23 20:46:39 christos Exp $ +# + +MSDOS= ${NETBSDSRCDIR}/sys/fs/msdosfs +NEWFS= ${NETBSDSRCDIR}/sbin/newfs_msdos + +.PATH: ${.CURDIR}/v7fs ${MSDOS} ${NEWFS} + +CPPFLAGS+= -DMSDOS_EI -I${MSDOS} -I${NEWFS} diff --git a/usr.sbin/makefs/v7fs.c b/usr.sbin/makefs/v7fs.c index c55c09702327..58b9b06617fc 100644 --- a/usr.sbin/makefs/v7fs.c +++ b/usr.sbin/makefs/v7fs.c @@ -1,4 +1,4 @@ -/* $NetBSD: v7fs.c,v 1.3 2011/08/10 11:31:49 uch Exp $ */ +/* $NetBSD: v7fs.c,v 1.4 2013/01/23 20:46:39 christos Exp $ */ /*- * Copyright (c) 2011 The NetBSD Foundation, Inc. @@ -35,7 +35,7 @@ #include #if defined(__RCSID) && !defined(__lint) -__RCSID("$NetBSD: v7fs.c,v 1.3 2011/08/10 11:31:49 uch Exp $"); +__RCSID("$NetBSD: v7fs.c,v 1.4 2013/01/23 20:46:39 christos Exp $"); #endif /* !__lint */ #include @@ -75,8 +75,9 @@ int v7fs_parse_opts(const char *option, fsinfo_t *fsopts) { static option_t v7fs_options[] = { - { "pdp", &v7fs_opts.pdp_endian, false, true, "PDP endian" }, - { "progress", &v7fs_opts.progress, false, true, + { '\0', "pdp", &v7fs_opts.pdp_endian, OPT_INT32, false, true, + "PDP endian" }, + { '\0', "progress", &v7fs_opts.progress, OPT_INT32, false, true, "Progress bar" }, { .name = NULL } };