- add support for parsing different types; not just int.

- add beginning of msdos support.
This commit is contained in:
christos 2013-01-23 20:46:39 +00:00
parent 24eac4746d
commit 3d364f5471
9 changed files with 297 additions and 88 deletions

View File

@ -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 <bsd.own.mk>
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}

View File

@ -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 <sys/cdefs.h>
#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 <string.h>
@ -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)

View File

@ -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 }
};

View File

@ -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 <sys/cdefs.h>
#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 <sys/param.h>
@ -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;

View File

@ -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 <sys/cdefs.h>
#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 <assert.h>
@ -52,6 +52,7 @@ __RCSID("$NetBSD: makefs.c,v 1.35 2012/06/22 06:15:18 sjg Exp $");
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdbool.h>
#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);

View File

@ -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;

166
usr.sbin/makefs/msdos.c Normal file
View File

@ -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 <sys/cdefs.h>
#if defined(__RCSID) && !defined(__lint)
__RCSID("$NetBSD: msdos.c,v 1.1 2013/01/23 20:46:39 christos Exp $");
#endif /* !__lint */
#include <sys/param.h>
#if !HAVE_NBTOOL_CONFIG_H
#include <sys/mount.h>
#endif
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#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
}

View File

@ -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}

View File

@ -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 <sys/cdefs.h>
#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 <stdio.h>
@ -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 }
};