#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <unistd.h>
#include <string.h>
#include <assert.h>
#include <err.h>
#include "mkfs_hammer2.h"
static void parse_fs_size(hammer2_mkfs_options_t *, const char *);
static void usage(void);
int
main(int ac, char **av)
{
hammer2_mkfs_options_t opt;
int ch;
int label_specified = 0;
hammer2_mkfs_init(&opt);
while ((ch = getopt(ac, av, "L:b:r:V:s:d")) != -1) {
int i;
switch(ch) {
case 'b':
opt.BootAreaSize = getsize(optarg,
HAMMER2_NEWFS_ALIGN,
HAMMER2_BOOT_MAX_BYTES, 2);
break;
case 'r':
opt.AuxAreaSize = getsize(optarg,
HAMMER2_NEWFS_ALIGN,
HAMMER2_AUX_MAX_BYTES, 2);
break;
case 'V':
opt.Hammer2Version = strtol(optarg, NULL, 0);
if (opt.Hammer2Version < HAMMER2_VOL_VERSION_MIN ||
opt.Hammer2Version >= HAMMER2_VOL_VERSION_WIP) {
errx(1, "I don't understand how to format "
"HAMMER2 version %d",
opt.Hammer2Version);
}
break;
case 'L':
label_specified = 1;
if (strcasecmp(optarg, "none") == 0) {
break;
}
for (i = 0; i < opt.NLabels; i++) {
if (strcasecmp(opt.Label[i], optarg) == 0) {
errx(1, "duplicate label \"%s\"; "
"note \"LOCAL\" is auto-created",
optarg);
}
}
if (opt.NLabels >= MAXLABELS) {
errx(1, "Limit of %d local labels",
MAXLABELS - 1);
}
if (strlen(optarg) == 0) {
errx(1, "Volume label '%s' cannot be 0-length",
optarg);
}
if (strlen(optarg) >= HAMMER2_INODE_MAXNAME) {
errx(1, "Volume label '%s' is too long "
"(%d chars max)",
optarg,
HAMMER2_INODE_MAXNAME - 1);
}
opt.Label[opt.NLabels++] = strdup(optarg);
break;
case 's':
parse_fs_size(&opt, optarg);
break;
case 'd':
opt.DebugOpt = 1;
break;
default:
usage();
break;
}
}
ac -= optind;
av += optind;
if (ac == 0)
errx(1, "You must specify at least one disk device");
if (ac > HAMMER2_MAX_VOLUMES)
errx(1, "The maximum number of volumes is %d",
HAMMER2_MAX_VOLUMES);
if (!label_specified) {
char c = av[0][strlen(av[0]) - 1];
if (c == 'a')
opt.DefaultLabelType = HAMMER2_LABEL_BOOT;
else if (c == 'd')
opt.DefaultLabelType = HAMMER2_LABEL_ROOT;
else
opt.DefaultLabelType = HAMMER2_LABEL_DATA;
}
assert(opt.CompType == HAMMER2_COMP_DEFAULT);
assert(opt.CheckType == HAMMER2_CHECK_DEFAULT);
hammer2_mkfs(ac, av, &opt);
hammer2_mkfs_cleanup(&opt);
return(0);
}
static
void
parse_fs_size(hammer2_mkfs_options_t *opt, const char *arg)
{
char *o, *p, *s;
opt->NFileSystemSizes = 0;
o = p = strdup(arg);
while ((s = p) != NULL) {
if ((p = strchr(p, ':')) != NULL)
*p++ = 0;
opt->FileSystemSize[opt->NFileSystemSizes++] = getsize(s,
HAMMER2_FREEMAP_LEVEL1_SIZE,
0x7fffffffffffffff, 2);
if (opt->NFileSystemSizes >= HAMMER2_MAX_VOLUMES)
break;
}
free(o);
}
static
void
usage(void)
{
fprintf(stderr,
"usage: newfs_hammer2 [-b bootsize] [-r auxsize] "
"[-V version] [-L label ...] [-s size] special ...\n"
);
exit(1);
}