merge command line parsers and check all memory allocations.

This commit is contained in:
christos 2015-12-01 23:29:07 +00:00
parent 1c8d6ff1b4
commit 0f004afe33
8 changed files with 148 additions and 119 deletions

View File

@ -33,7 +33,7 @@
__FBSDID("$FreeBSD: src/sbin/gpt/add.c,v 1.14 2006/06/22 22:05:28 marcel Exp $");
#endif
#ifdef __RCSID
__RCSID("$NetBSD: add.c,v 1.33 2015/12/01 19:25:24 christos Exp $");
__RCSID("$NetBSD: add.c,v 1.34 2015/12/01 23:29:07 christos Exp $");
#endif
#include <sys/types.h>
@ -152,28 +152,19 @@ static int
cmd_add(gpt_t gpt, int argc, char *argv[])
{
int ch;
int64_t human_num;
while ((ch = getopt(argc, argv, GPT_AIS "bl:t:")) != -1) {
switch(ch) {
case 'b':
if (block > 0)
return usage();
if (dehumanize_number(optarg, &human_num) < 0)
return usage();
block = human_num;
if (block < 1)
if (gpt_human_get(&block) == -1)
return usage();
break;
case 'l':
if (name != NULL)
if (gpt_name_get(gpt, &name) == -1)
return usage();
name = (uint8_t *)strdup(optarg);
break;
case 't':
if (!gpt_uuid_is_nil(type))
return usage();
if (gpt_uuid_parse(optarg, type) != 0)
if (gpt_uuid_get(gpt, &type) == -1)
return usage();
break;
default:
@ -188,9 +179,8 @@ cmd_add(gpt_t gpt, int argc, char *argv[])
return usage();
/* Create NetBSD FFS partitions by default. */
if (gpt_uuid_is_nil(type)) {
if (gpt_uuid_is_nil(type))
gpt_uuid_create(GPT_TYPE_NETBSD_FFS, type, NULL, 0);
}
if (optind != argc)
return usage();

View File

@ -1,4 +1,4 @@
/* $NetBSD: biosboot.c,v 1.17 2015/12/01 16:32:19 christos Exp $ */
/* $NetBSD: biosboot.c,v 1.18 2015/12/01 23:29:07 christos Exp $ */
/*
* Copyright (c) 2009 The NetBSD Foundation, Inc.
@ -37,7 +37,7 @@
#include <sys/cdefs.h>
#ifdef __RCSID
__RCSID("$NetBSD: biosboot.c,v 1.17 2015/12/01 16:32:19 christos Exp $");
__RCSID("$NetBSD: biosboot.c,v 1.18 2015/12/01 23:29:07 christos Exp $");
#endif
#include <sys/stat.h>
@ -252,34 +252,23 @@ cmd_biosboot(gpt_t gpt, int argc, char *argv[])
#ifdef DIOCGWEDGEINFO
struct dkwedge_info dkw;
#endif
char *dev, *p;
char *dev;
int ch;
gpt_t ngpt = gpt;
while ((ch = getopt(argc, argv, "c:i:L:")) != -1) {
switch(ch) {
case 'c':
if (bootpath != NULL)
usage();
if ((bootpath = strdup(optarg)) == NULL) {
gpt_warn(gpt, "strdup failed");
return -1;
}
if (gpt_name_get(gpt, &bootpath) == -1)
return usage();
break;
case 'i':
if (entry > 0)
usage();
entry = strtoul(optarg, &p, 10);
if (*p != 0 || entry < 1)
if (gpt_entry_get(&entry) == -1)
return usage();
break;
case 'L':
if (label != NULL)
if (gpt_name_get(gpt, &label) == -1)
return usage();
if ((label = (uint8_t *)strdup(optarg)) == NULL) {
gpt_warn(gpt, "strdup failed");
return -1;
}
break;
default:
return usage();

View File

@ -35,7 +35,7 @@
__FBSDID("$FreeBSD: src/sbin/gpt/gpt.c,v 1.16 2006/07/07 02:44:23 marcel Exp $");
#endif
#ifdef __RCSID
__RCSID("$NetBSD: gpt.c,v 1.51 2015/12/01 19:25:24 christos Exp $");
__RCSID("$NetBSD: gpt.c,v 1.52 2015/12/01 23:29:07 christos Exp $");
#endif
#include <sys/param.h>
@ -850,7 +850,8 @@ gpt_create(gpt_t gpt, off_t last, u_int parts, int primary_only)
hdr->hdr_lba_alt = htole64(last);
hdr->hdr_lba_start = htole64(gpt->tbl->map_start + blocks);
hdr->hdr_lba_end = htole64(last - blocks - 1LL);
gpt_uuid_generate(hdr->hdr_guid);
if (gpt_uuid_generate(gpt, hdr->hdr_guid) == -1)
return -1;
hdr->hdr_lba_table = htole64(gpt->tbl->map_start);
hdr->hdr_entries = htole32((blocks * gpt->secsz) /
sizeof(struct gpt_ent));
@ -860,7 +861,8 @@ gpt_create(gpt_t gpt, off_t last, u_int parts, int primary_only)
ent = gpt->tbl->map_data;
for (i = 0; i < le32toh(hdr->hdr_entries); i++) {
gpt_uuid_generate(ent[i].ent_guid);
if (gpt_uuid_generate(gpt, ent[i].ent_guid) == -1)
return -1;
}
/*
@ -895,12 +897,50 @@ gpt_create(gpt_t gpt, off_t last, u_int parts, int primary_only)
return last;
}
int
gpt_add_find(gpt_t gpt, struct gpt_find *find, int ch)
static int
gpt_size_get(gpt_t gpt, off_t *size)
{
off_t sectors;
int64_t human_num;
char *p;
if (*size > 0)
return -1;
sectors = strtoll(optarg, &p, 10);
if (sectors < 1)
return -1;
if (*p == '\0' || ((*p == 's' || *p == 'S') && p[1] == '\0')) {
*size = sectors * gpt->secsz;
return 0;
}
if ((*p == 'b' || *p == 'B') && p[1] == '\0') {
*size = sectors;
return 0;
}
if (dehumanize_number(optarg, &human_num) < 0)
return -1;
*size = human_num;
return 0;
}
int
gpt_human_get(off_t *human)
{
int64_t human_num;
if (*human > 0)
return -1;
if (dehumanize_number(optarg, &human_num) < 0)
return -1;
*human = human_num;
if (*human < 1)
return -1;
return 0;
}
int
gpt_add_find(gpt_t gpt, struct gpt_find *find, int ch)
{
switch (ch) {
case 'a':
if (find->all > 0)
@ -908,31 +948,19 @@ gpt_add_find(gpt_t gpt, struct gpt_find *find, int ch)
find->all = 1;
break;
case 'b':
if (find->block > 0)
return -1;
if (dehumanize_number(optarg, &human_num) < 0)
return -1;
find->block = human_num;
if (find->block < 1)
if (gpt_human_get(&find->block) == -1)
return -1;
break;
case 'i':
if (find->entry > 0)
return -1;
find->entry = strtoul(optarg, &p, 10);
if (*p != 0 || find->entry < 1)
if (gpt_entry_get(&find->entry) == -1)
return -1;
break;
case 'L':
if (find->label != NULL)
if (gpt_name_get(gpt, &find->label) == -1)
return -1;
find->label = (uint8_t *)strdup(optarg);
break;
case 's':
if (find->size > 0)
return -1;
find->size = strtoll(optarg, &p, 10);
if (*p != 0 || find->size < 1)
if (gpt_size_get(gpt, &find->size) == -1)
return -1;
break;
case 't':
@ -1008,44 +1036,18 @@ gpt_change_ent(gpt_t gpt, const struct gpt_find *find,
int
gpt_add_ais(gpt_t gpt, off_t *alignment, u_int *entry, off_t *size, int ch)
{
int64_t human_num;
off_t sectors;
char *p;
switch (ch) {
case 'a':
if (*alignment > 0)
return -1;
if (dehumanize_number(optarg, &human_num) < 0)
return -1;
*alignment = human_num;
if (*alignment < 1)
if (gpt_human_get(alignment) == -1)
return -1;
return 0;
case 'i':
if (*entry > 0)
return -1;
*entry = strtoul(optarg, &p, 10);
if (*p != 0 || *entry < 1)
if (gpt_entry_get(entry) == -1)
return -1;
return 0;
case 's':
if (*size > 0)
if (gpt_size_get(gpt, size) == -1)
return -1;
sectors = strtoll(optarg, &p, 10);
if (sectors < 1)
return -1;
if (*p == '\0' || ((*p == 's' || *p == 'S') && p[1] == '\0')) {
*size = sectors * gpt->secsz;
return 0;
}
if ((*p == 'b' || *p == 'B') && p[1] == '\0') {
*size = sectors;
return 0;
}
if (dehumanize_number(optarg, &human_num) < 0)
return -1;
*size = human_num;
return 0;
default:
return -1;
@ -1142,3 +1144,28 @@ gpt_entry_get(u_int *entry)
return -1;
return 0;
}
int
gpt_uuid_get(gpt_t gpt, gpt_uuid_t *uuid)
{
if (!gpt_uuid_is_nil(*uuid))
return -1;
if (gpt_uuid_parse(optarg, *uuid) != 0) {
gpt_warn(gpt, "Can't parse uuid");
return -1;
}
return 0;
}
int
gpt_name_get(gpt_t gpt, void *v)
{
char **name = v;
if (*name != NULL)
return -1;
*name = strdup(optarg);
if (*name == NULL) {
gpt_warn(gpt, "Can't copy string");
return -1;
}
return 0;
}

View File

@ -121,5 +121,8 @@ off_t gpt_check_ais(gpt_t, off_t, u_int, off_t);
int gpt_attr_get(uint64_t *);
int gpt_attr_update(gpt_t, u_int, uint64_t, uint64_t);
int gpt_entry_get(u_int *);
int gpt_human_get(off_t *);
int gpt_uuid_get(gpt_t, gpt_uuid_t *);
int gpt_name_get(gpt_t, void *);
#endif /* _GPT_H_ */

View File

@ -1,4 +1,4 @@
/* $NetBSD: gpt_uuid.c,v 1.10 2014/12/06 12:24:22 mlelstv Exp $ */
/* $NetBSD: gpt_uuid.c,v 1.11 2015/12/01 23:29:07 christos Exp $ */
/*-
* Copyright (c) 2014 The NetBSD Foundation, Inc.
@ -32,7 +32,7 @@
#include <sys/cdefs.h>
#ifdef __RCSID
__RCSID("$NetBSD: gpt_uuid.c,v 1.10 2014/12/06 12:24:22 mlelstv Exp $");
__RCSID("$NetBSD: gpt_uuid.c,v 1.11 2015/12/01 23:29:07 christos Exp $");
#endif
#include <err.h>
@ -238,8 +238,8 @@ gpt_uuid_create(gpt_type_t t, gpt_uuid_t u, uint16_t *b, size_t s)
utf8_to_utf16((const uint8_t *)gpt_nv[t].d, b, s / sizeof(*b));
}
void
gpt_uuid_generate(gpt_uuid_t t)
int
gpt_uuid_generate(gpt_t gpt, gpt_uuid_t t)
{
struct dce_uuid u;
int fd;
@ -249,16 +249,24 @@ gpt_uuid_generate(gpt_uuid_t t)
/* Randomly generate the content. */
fd = open("/dev/urandom", O_RDONLY | O_CLOEXEC);
if (fd == -1)
err(1, "open(/dev/urandom)");
if (fd == -1) {
gpt_warn(gpt, "Can't open `/dev/urandom'");
return -1;
}
for (p = (void *)&u, n = sizeof u; 0 < n; p += nread, n -= nread) {
nread = read(fd, p, n);
if (nread < 0)
err(1, "read(/dev/urandom)");
if (nread == 0)
errx(1, "EOF from /dev/urandom");
if ((size_t)nread > n)
errx(1, "read too much: %zd > %zu", nread, n);
if (nread < 0) {
gpt_warn(gpt, "Can't read `/dev/urandom'");
goto out;
}
if (nread == 0) {
gpt_warn(gpt, "EOF from /dev/urandom");
goto out;
}
if ((size_t)nread > n) {
gpt_warnx(gpt, "read too much: %zd > %zu", nread, n);
goto out;
}
}
(void)close(fd);
@ -271,4 +279,8 @@ gpt_uuid_generate(gpt_uuid_t t)
u.clock_seq_hi_and_reserved |= 0x80;
gpt_dce_to_uuid(&u, t);
close(fd);
return 0;
out:
return -1;
}

View File

@ -94,7 +94,8 @@ void gpt_uuid_create(gpt_type_t, gpt_uuid_t, uint16_t *, size_t);
int gpt_uuid_parse(const char *, gpt_uuid_t);
void gpt_uuid_generate(gpt_uuid_t);
struct gpt;
int gpt_uuid_generate(struct gpt *, gpt_uuid_t);
__END_DECLS

View File

@ -33,7 +33,7 @@
__FBSDID("$FreeBSD: src/sbin/gpt/label.c,v 1.3 2006/10/04 18:20:25 marcel Exp $");
#endif
#ifdef __RCSID
__RCSID("$NetBSD: label.c,v 1.22 2015/12/01 19:25:24 christos Exp $");
__RCSID("$NetBSD: label.c,v 1.23 2015/12/01 23:29:07 christos Exp $");
#endif
#include <sys/types.h>
@ -73,33 +73,46 @@ change(struct gpt_ent *ent, void *v)
utf8_to_utf16(name, ent->ent_name, 36);
}
static char *
name_from_file(const char *fn)
static int
name_from_file(gpt_t gpt, void *v)
{
FILE *f;
char *p;
size_t maxlen = 1024;
size_t len;
char *name;
const char *fn = optarg;
char **name = v;
if (*name != NULL)
return -1;
if (strcmp(fn, "-") != 0) {
f = fopen(fn, "r");
if (f == NULL)
err(1, "unable to open file %s", fn);
if (f == NULL) {
gpt_warn(gpt, "Can't open `%s'", fn);
return -1;
}
} else
f = stdin;
name = malloc(maxlen);
len = fread(name, 1, maxlen - 1, f);
if (ferror(f))
err(1, "unable to read label from file %s", fn);
if ((*name = malloc(maxlen)) == NULL) {
gpt_warn(gpt, "Can't copy string");
return -1;
}
len = fread(*name, 1, maxlen - 1, f);
if (ferror(f)) {
free(*name);
gpt_warn(gpt, "Can't label from `%s'", fn);
return -1;
}
if (f != stdin)
fclose(f);
name[len] = '\0';
(*name)[len] = '\0';
/* Only keep the first line, excluding the newline character. */
p = strchr((const char *)name, '\n');
p = strchr(*name, '\n');
if (p != NULL)
*p = '\0';
return name;
return 0;
}
static int
@ -116,14 +129,12 @@ cmd_label(gpt_t gpt, int argc, char *argv[])
while ((ch = getopt(argc, argv, GPT_FIND "f:l:")) != -1) {
switch(ch) {
case 'f':
if (name != NULL)
if (name_from_file(gpt, &name) == -1)
return usage();
name = name_from_file(optarg);
break;
case 'l':
if (name != NULL)
if (gpt_name_get(gpt, &name) == -1)
return usage();
name = strdup(optarg);
break;
default:
if (gpt_add_find(gpt, &find, ch) == -1)

View File

@ -33,7 +33,7 @@
__FBSDID("$FreeBSD: src/sbin/gpt/show.c,v 1.14 2006/06/22 22:22:32 marcel Exp $");
#endif
#ifdef __RCSID
__RCSID("$NetBSD: show.c,v 1.25 2015/12/01 16:32:19 christos Exp $");
__RCSID("$NetBSD: show.c,v 1.26 2015/12/01 23:29:07 christos Exp $");
#endif
#include <sys/types.h>
@ -237,7 +237,6 @@ show_one(gpt_t gpt)
static int
cmd_show(gpt_t gpt, int argc, char *argv[])
{
char *p;
int ch;
while ((ch = getopt(argc, argv, "gi:lu")) != -1) {
@ -246,10 +245,7 @@ cmd_show(gpt_t gpt, int argc, char *argv[])
show_guid = 1;
break;
case 'i':
if (entry > 0)
return usage();
entry = strtoul(optarg, &p, 10);
if (*p != 0 || entry < 1)
if (gpt_entry_get(&entry) == -1)
return usage();
break;
case 'l':