refactor more duplicated code.

This commit is contained in:
christos 2015-12-01 19:25:24 +00:00
parent 4f3e6067a8
commit bbb4a8ab26
12 changed files with 515 additions and 808 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.32 2015/12/01 16:32:19 christos Exp $");
__RCSID("$NetBSD: add.c,v 1.33 2015/12/01 19:25:24 christos Exp $");
#endif
#include <sys/types.h>
@ -79,6 +79,7 @@ add(gpt_t gpt)
struct gpt_ent *ent, e;
unsigned int i;
off_t alignsecs;
char buf[128];
if ((hdr = gpt_hdr(gpt)) == NULL)
return -1;
@ -141,29 +142,20 @@ add(gpt_t gpt)
memcpy(ent, &e, sizeof(e));
gpt_write_backup(gpt);
gpt_msg(gpt, "Partition %d added: %s %" PRIu64 " %" PRIu64 "\n", i + 1,
type, map->map_start, map->map_size);
gpt_uuid_snprintf(buf, sizeof(buf), "%d", type);
gpt_msg(gpt, "Partition %d added: %s %" PRIu64 " %" PRIu64, i + 1,
buf, map->map_start, map->map_size);
return 0;
}
static int
cmd_add(gpt_t gpt, int argc, char *argv[])
{
char *p;
int ch;
int64_t human_num;
while ((ch = getopt(argc, argv, "a:b:i:l:s:t:")) != -1) {
while ((ch = getopt(argc, argv, GPT_AIS "bl:t:")) != -1) {
switch(ch) {
case 'a':
if (alignment > 0)
return usage();
if (dehumanize_number(optarg, &human_num) < 0)
return usage();
alignment = human_num;
if (alignment < 1)
return usage();
break;
case 'b':
if (block > 0)
return usage();
@ -173,45 +165,11 @@ cmd_add(gpt_t gpt, int argc, char *argv[])
if (block < 1)
return usage();
break;
case 'i':
if (entry > 0)
usage();
entry = strtoul(optarg, &p, 10);
if (*p != 0 || entry < 1)
return usage();
break;
case 'l':
if (name != NULL)
return usage();
name = (uint8_t *)strdup(optarg);
break;
case 's':
if (sectors > 0 || size > 0)
return usage();
sectors = strtoll(optarg, &p, 10);
if (sectors < 1)
return usage();
if (*p == '\0')
break;
if (*p == 's' || *p == 'S') {
if (*(p + 1) == '\0')
break;
else
return usage();
}
if (*p == 'b' || *p == 'B') {
if (*(p + 1) == '\0') {
size = sectors;
sectors = 0;
break;
} else
return usage();
}
if (dehumanize_number(optarg, &human_num) < 0)
return usage();
size = human_num;
sectors = 0;
break;
case 't':
if (!gpt_uuid_is_nil(type))
return usage();
@ -219,11 +177,14 @@ cmd_add(gpt_t gpt, int argc, char *argv[])
return usage();
break;
default:
return usage();
if (gpt_add_ais(gpt, &alignment, &entry, &size, ch)
== -1)
return usage();
break;
}
}
if (argc == optind)
if (argc != optind)
return usage();
/* Create NetBSD FFS partitions by default. */
@ -234,7 +195,7 @@ cmd_add(gpt_t gpt, int argc, char *argv[])
if (optind != argc)
return usage();
if ((sectors = gpt_check(gpt, alignment, size)) == -1)
if ((sectors = gpt_check_ais(gpt, alignment, entry, size)) == -1)
return -1;
return add(gpt);

View File

@ -33,7 +33,7 @@
__FBSDID("$FreeBSD: src/sbin/gpt/create.c,v 1.11 2005/08/31 01:47:19 marcel Exp $");
#endif
#ifdef __RCSID
__RCSID("$NetBSD: create.c,v 1.15 2015/12/01 16:32:19 christos Exp $");
__RCSID("$NetBSD: create.c,v 1.16 2015/12/01 19:25:24 christos Exp $");
#endif
#include <sys/types.h>
@ -74,21 +74,10 @@ struct gpt_cmd c_create = {
static int
create(gpt_t gpt)
{
off_t blocks, last;
off_t last = gpt_last(gpt);
map_t map;
struct mbr *mbr;
struct gpt_hdr *hdr;
struct gpt_ent *ent;
unsigned int i;
void *p;
last = gpt->mediasz / gpt->secsz - 1LL;
if (map_find(gpt, MAP_TYPE_PRI_GPT_HDR) != NULL ||
map_find(gpt, MAP_TYPE_SEC_GPT_HDR) != NULL) {
gpt_warnx(gpt, "Device already contains a GPT");
return -1;
}
map = map_find(gpt, MAP_TYPE_MBR);
if (map != NULL) {
if (!force) {
@ -117,110 +106,21 @@ create(gpt_t gpt)
gpt_create_pmbr_part(mbr->mbr_part, last);
map = map_add(gpt, 0LL, 1LL, MAP_TYPE_PMBR, mbr);
gpt_write(gpt, map);
if (gpt_write(gpt, map) == -1) {
gpt_warn(gpt, "Can't write PMBR");
return -1;
}
}
/* Get the amount of free space after the MBR */
blocks = map_free(gpt, 1LL, 0LL);
if (blocks == 0LL) {
gpt_warnx(gpt, "No room for the GPT header");
if (gpt_create(gpt, last, parts, primary_only) == -1)
return -1;
}
/* Don't create more than parts entries. */
if ((uint64_t)(blocks - 1) * gpt->secsz >
parts * sizeof(struct gpt_ent)) {
blocks = (parts * sizeof(struct gpt_ent)) / gpt->secsz;
if ((parts * sizeof(struct gpt_ent)) % gpt->secsz)
blocks++;
blocks++; /* Don't forget the header itself */
}
/* Never cross the median of the device. */
if ((blocks + 1LL) > ((last + 1LL) >> 1))
blocks = ((last + 1LL) >> 1) - 1LL;
/*
* Get the amount of free space at the end of the device and
* calculate the size for the GPT structures.
*/
map = map_last(gpt);
if (map->map_type != MAP_TYPE_UNUSED) {
gpt_warnx(gpt, "No room for the backup header");
return -1;
}
if (map->map_size < blocks)
blocks = map->map_size;
if (blocks == 1LL) {
gpt_warnx(gpt, "No room for the GPT table");
return -1;
}
if ((p = calloc(1, gpt->secsz)) == NULL) {
gpt_warnx(gpt, "Can't allocate the GPT");
return -1;
}
if ((gpt->gpt = map_add(gpt, 1LL, 1LL,
MAP_TYPE_PRI_GPT_HDR, p)) == NULL) {
free(p);
gpt_warnx(gpt, "Can't add the GPT");
return -1;
}
blocks--; /* Number of blocks in the GPT table. */
if ((p = calloc(blocks, gpt->secsz)) == NULL) {
gpt_warnx(gpt, "Can't allocate the GPT table");
return -1;
}
if ((gpt->tbl = map_add(gpt, 2LL, blocks,
MAP_TYPE_PRI_GPT_TBL, p)) == NULL) {
free(p);
gpt_warnx(gpt, "Can't add the GPT table");
return -1;
}
hdr = gpt->gpt->map_data;
memcpy(hdr->hdr_sig, GPT_HDR_SIG, sizeof(hdr->hdr_sig));
hdr->hdr_revision = htole32(GPT_HDR_REVISION);
hdr->hdr_size = htole32(GPT_HDR_SIZE);
hdr->hdr_lba_self = htole64(gpt->gpt->map_start);
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);
hdr->hdr_lba_table = htole64(gpt->tbl->map_start);
hdr->hdr_entries = htole32((blocks * gpt->secsz) /
sizeof(struct gpt_ent));
if (le32toh(hdr->hdr_entries) > parts)
hdr->hdr_entries = htole32(parts);
hdr->hdr_entsz = htole32(sizeof(struct gpt_ent));
ent = gpt->tbl->map_data;
for (i = 0; i < le32toh(hdr->hdr_entries); i++) {
gpt_uuid_generate(ent[i].ent_guid);
}
if (gpt_write_primary(gpt) == -1)
return -1;
/*
* Create backup GPT if the user didn't suppress it.
*/
if (!primary_only) {
// XXX: error checks
gpt->tpg = map_add(gpt, last, 1LL, MAP_TYPE_SEC_GPT_HDR,
calloc(1, gpt->secsz));
gpt->lbt = map_add(gpt, last - blocks, blocks,
MAP_TYPE_SEC_GPT_TBL, gpt->tbl->map_data);
memcpy(gpt->tpg->map_data, gpt->gpt->map_data, gpt->secsz);
hdr = gpt->tpg->map_data;
hdr->hdr_lba_self = htole64(gpt->tpg->map_start);
hdr->hdr_lba_alt = htole64(gpt->gpt->map_start);
hdr->hdr_lba_table = htole64(gpt->lbt->map_start);
if (gpt_write_backup(gpt) == -1)
return -1;
}
if (!primary_only && gpt_write_backup(gpt) == -1)
return -1;
return 0;
}

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.50 2015/12/01 16:32:19 christos Exp $");
__RCSID("$NetBSD: gpt.c,v 1.51 2015/12/01 19:25:24 christos Exp $");
#endif
#include <sys/param.h>
@ -712,24 +712,7 @@ gpt_create_pmbr_part(struct mbr_part *part, off_t last)
}
}
off_t
gpt_check(gpt_t gpt, off_t alignment, off_t size)
{
if (alignment % gpt->secsz != 0) {
gpt_warnx(gpt, "Alignment (%#jx) must be a multiple of "
"sector size (%#x)", (uintmax_t)alignment, gpt->secsz);
return -1;
}
if (size % gpt->secsz != 0) {
gpt_warnx(gpt, "Size (%#jx) must be a multiple of "
"sector size (%#x)", (uintmax_t)size, gpt->secsz);
return -1;
}
if (size > 0)
return size / gpt->secsz;
return 0;
}
struct gpt_ent *
gpt_ent(map_t map, map_t tbl, unsigned int i)
{
@ -770,3 +753,392 @@ gpt_usage(const char *prefix, const struct gpt_cmd *cmd)
}
return -1;
}
off_t
gpt_last(gpt_t gpt)
{
return gpt->mediasz / gpt->secsz - 1LL;
}
int
gpt_create(gpt_t gpt, off_t last, u_int parts, int primary_only)
{
off_t blocks;
map_t map;
struct gpt_hdr *hdr;
struct gpt_ent *ent;
unsigned int i;
void *p;
if (map_find(gpt, MAP_TYPE_PRI_GPT_HDR) != NULL ||
map_find(gpt, MAP_TYPE_SEC_GPT_HDR) != NULL) {
gpt_warnx(gpt, "Device already contains a GPT");
return -1;
}
/* Get the amount of free space after the MBR */
blocks = map_free(gpt, 1LL, 0LL);
if (blocks == 0LL) {
gpt_warnx(gpt, "No room for the GPT header");
return -1;
}
/* Don't create more than parts entries. */
if ((uint64_t)(blocks - 1) * gpt->secsz >
parts * sizeof(struct gpt_ent)) {
blocks = (parts * sizeof(struct gpt_ent)) / gpt->secsz;
if ((parts * sizeof(struct gpt_ent)) % gpt->secsz)
blocks++;
blocks++; /* Don't forget the header itself */
}
/* Never cross the median of the device. */
if ((blocks + 1LL) > ((last + 1LL) >> 1))
blocks = ((last + 1LL) >> 1) - 1LL;
/*
* Get the amount of free space at the end of the device and
* calculate the size for the GPT structures.
*/
map = map_last(gpt);
if (map->map_type != MAP_TYPE_UNUSED) {
gpt_warnx(gpt, "No room for the backup header");
return -1;
}
if (map->map_size < blocks)
blocks = map->map_size;
if (blocks == 1LL) {
gpt_warnx(gpt, "No room for the GPT table");
return -1;
}
blocks--; /* Number of blocks in the GPT table. */
if ((p = calloc(1, gpt->secsz)) == NULL) {
gpt_warnx(gpt, "Can't allocate the primary GPT");
return -1;
}
if ((gpt->gpt = map_add(gpt, 1LL, 1LL,
MAP_TYPE_PRI_GPT_HDR, p)) == NULL) {
free(p);
gpt_warnx(gpt, "Can't add the primary GPT");
return -1;
}
if ((p = calloc(blocks, gpt->secsz)) == NULL) {
gpt_warnx(gpt, "Can't allocate the primary GPT table");
return -1;
}
if ((gpt->tbl = map_add(gpt, 2LL, blocks,
MAP_TYPE_PRI_GPT_TBL, p)) == NULL) {
free(p);
gpt_warnx(gpt, "Can't add the primary GPT table");
return -1;
}
hdr = gpt->gpt->map_data;
memcpy(hdr->hdr_sig, GPT_HDR_SIG, sizeof(hdr->hdr_sig));
/*
* XXX struct gpt_hdr is not a multiple of 8 bytes in size and thus
* contains padding we must not include in the size.
*/
hdr->hdr_revision = htole32(GPT_HDR_REVISION);
hdr->hdr_size = htole32(GPT_HDR_SIZE);
hdr->hdr_lba_self = htole64(gpt->gpt->map_start);
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);
hdr->hdr_lba_table = htole64(gpt->tbl->map_start);
hdr->hdr_entries = htole32((blocks * gpt->secsz) /
sizeof(struct gpt_ent));
if (le32toh(hdr->hdr_entries) > parts)
hdr->hdr_entries = htole32(parts);
hdr->hdr_entsz = htole32(sizeof(struct gpt_ent));
ent = gpt->tbl->map_data;
for (i = 0; i < le32toh(hdr->hdr_entries); i++) {
gpt_uuid_generate(ent[i].ent_guid);
}
/*
* Create backup GPT if the user didn't suppress it.
*/
if (primary_only)
return last;
if ((p = calloc(1, gpt->secsz)) == NULL) {
gpt_warnx(gpt, "Can't allocate the secondary GPT");
return -1;
}
if ((gpt->tpg = map_add(gpt, last, 1LL,
MAP_TYPE_SEC_GPT_HDR, p)) == NULL) {
gpt_warnx(gpt, "Can't add the secondary GPT");
return -1;
}
if ((gpt->lbt = map_add(gpt, last - blocks, blocks,
MAP_TYPE_SEC_GPT_TBL, gpt->tbl->map_data)) == NULL) {
gpt_warnx(gpt, "Can't add the secondary GPT table");
return -1;
}
memcpy(gpt->tpg->map_data, gpt->gpt->map_data, gpt->secsz);
hdr = gpt->tpg->map_data;
hdr->hdr_lba_self = htole64(gpt->tpg->map_start);
hdr->hdr_lba_alt = htole64(gpt->gpt->map_start);
hdr->hdr_lba_table = htole64(gpt->lbt->map_start);
return last;
}
int
gpt_add_find(gpt_t gpt, struct gpt_find *find, int ch)
{
int64_t human_num;
char *p;
switch (ch) {
case 'a':
if (find->all > 0)
return -1;
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)
return -1;
break;
case 'i':
if (find->entry > 0)
return -1;
find->entry = strtoul(optarg, &p, 10);
if (*p != 0 || find->entry < 1)
return -1;
break;
case 'L':
if (find->label != NULL)
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)
return -1;
break;
case 't':
if (!gpt_uuid_is_nil(find->type))
return -1;
if (gpt_uuid_parse(optarg, find->type) != 0)
return -1;
break;
default:
return -1;
}
return 0;
}
int
gpt_change_ent(gpt_t gpt, const struct gpt_find *find,
void (*cfn)(struct gpt_ent *, void *), void *v)
{
map_t m;
struct gpt_hdr *hdr;
struct gpt_ent *ent;
unsigned int i;
if (!find->all ^
(find->block > 0 || find->entry > 0 || find->label != NULL
|| find->size > 0 || !gpt_uuid_is_nil(find->type)))
return -1;
if ((hdr = gpt_hdr(gpt)) == NULL)
return -1;
/* Relabel all matching entries in the map. */
for (m = map_first(gpt); m != NULL; m = m->map_next) {
if (m->map_type != MAP_TYPE_GPT_PART || m->map_index < 1)
continue;
if (find->entry > 0 && find->entry != m->map_index)
continue;
if (find->block > 0 && find->block != m->map_start)
continue;
if (find->size > 0 && find->size != m->map_size)
continue;
i = m->map_index - 1;
ent = gpt_ent_primary(gpt, i);
if (find->label != NULL)
if (strcmp((char *)find->label,
(char *)utf16_to_utf8(ent->ent_name)) != 0)
continue;
if (!gpt_uuid_is_nil(find->type) &&
!gpt_uuid_equal(find->type, ent->ent_type))
continue;
/* Change the primary entry. */
(*cfn)(ent, v);
if (gpt_write_primary(gpt) == -1)
return -1;
ent = gpt_ent_backup(gpt, i);
/* Change the secondary entry. */
(*cfn)(ent, v);
if (gpt_write_backup(gpt) == -1)
return -1;
gpt_msg(gpt, "Partition %d %s", m->map_index, find->msg);
}
return 0;
}
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)
return -1;
return 0;
case 'i':
if (*entry > 0)
return -1;
*entry = strtoul(optarg, &p, 10);
if (*p != 0 || *entry < 1)
return -1;
return 0;
case 's':
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;
default:
return -1;
}
}
off_t
gpt_check_ais(gpt_t gpt, off_t alignment, u_int entry, off_t size)
{
if (entry == 0) {
gpt_warnx(gpt, "Entry not specified");
return -1;
}
if (alignment % gpt->secsz != 0) {
gpt_warnx(gpt, "Alignment (%#jx) must be a multiple of "
"sector size (%#x)", (uintmax_t)alignment, gpt->secsz);
return -1;
}
if (size % gpt->secsz != 0) {
gpt_warnx(gpt, "Size (%#jx) must be a multiple of "
"sector size (%#x)", (uintmax_t)size, gpt->secsz);
return -1;
}
if (size > 0)
return size / gpt->secsz;
return 0;
}
int
gpt_attr_get(uint64_t *attributes)
{
if (strcmp(optarg, "biosboot") == 0)
*attributes |= GPT_ENT_ATTR_LEGACY_BIOS_BOOTABLE;
else if (strcmp(optarg, "bootme") == 0)
*attributes |= GPT_ENT_ATTR_BOOTME;
else if (strcmp(optarg, "bootonce") == 0)
*attributes |= GPT_ENT_ATTR_BOOTONCE;
else if (strcmp(optarg, "bootfailed") == 0)
*attributes |= GPT_ENT_ATTR_BOOTFAILED;
else
return -1;
return 0;
}
int
gpt_attr_update(gpt_t gpt, u_int entry, uint64_t set, uint64_t clr)
{
struct gpt_hdr *hdr;
struct gpt_ent *ent;
unsigned int i;
if (entry == 0 || (set == 0 && clr == 0))
return -1;
if ((hdr = gpt_hdr(gpt)) == NULL)
return -1;
if (entry > le32toh(hdr->hdr_entries)) {
gpt_warnx(gpt, "Index %u out of range (%u max)",
entry, le32toh(hdr->hdr_entries));
return -1;
}
i = entry - 1;
ent = gpt_ent_primary(gpt, i);
if (gpt_uuid_is_nil(ent->ent_type)) {
gpt_warnx(gpt, "Entry at index %u is unused", entry);
return -1;
}
ent->ent_attr &= ~clr;
ent->ent_attr |= set;
if (gpt_write_primary(gpt) == -1)
return -1;
ent = gpt_ent_backup(gpt, i);
ent->ent_attr &= ~clr;
ent->ent_attr |= set;
if (gpt_write_backup(gpt) == -1)
return -1;
gpt_msg(gpt, "Partition %d attributes updated", entry);
return 0;
}
int
gpt_entry_get(u_int *entry)
{
char *p;
if (*entry > 0)
return -1;
*entry = strtoul(optarg, &p, 10);
if (*p != 0 || *entry < 1)
return -1;
return 0;
}

View File

@ -75,7 +75,14 @@ uint32_t crc32(const void *, size_t);
void gpt_close(gpt_t);
int gpt_gpt(gpt_t, off_t, int);
gpt_t gpt_open(const char *, int, int, off_t, u_int);
#define GPT_READONLY 1
#define GPT_MODIFIED 2
#define GPT_QUIET 4
#define GPT_NOSYNC 8
void* gpt_read(gpt_t, off_t, size_t);
off_t gpt_last(gpt_t);
int gpt_create(gpt_t, off_t, u_int, int);
int gpt_write(gpt_t, map_t);
int gpt_write_crc(gpt_t, map_t, map_t);
int gpt_write_primary(gpt_t);
@ -85,7 +92,6 @@ void gpt_msg(gpt_t, const char *, ...) __printflike(2, 3);
void gpt_warn(gpt_t, const char *, ...) __printflike(2, 3);
void gpt_warnx(gpt_t, const char *, ...) __printflike(2, 3);
void gpt_create_pmbr_part(struct mbr_part *, off_t);
off_t gpt_check(gpt_t, off_t, off_t);
struct gpt_ent *gpt_ent(map_t, map_t, unsigned int);
struct gpt_ent *gpt_ent_primary(gpt_t, unsigned int);
struct gpt_ent *gpt_ent_backup(gpt_t, unsigned int);
@ -94,9 +100,26 @@ int gpt_usage(const char *, const struct gpt_cmd *);
uint8_t *utf16_to_utf8(uint16_t *);
void utf8_to_utf16(const uint8_t *, uint16_t *, size_t);
#define GPT_READONLY 1
#define GPT_MODIFIED 2
#define GPT_QUIET 4
#define GPT_NOSYNC 8
#define GPT_FIND "ab:i:L:s:t:"
struct gpt_find {
int all;
gpt_uuid_t type;
off_t block, size;
unsigned int entry;
uint8_t *name, *label;
const char *msg;
};
int gpt_change_ent(gpt_t, const struct gpt_find *,
void (*)(struct gpt_ent *, void *), void *);
int gpt_add_find(gpt_t, struct gpt_find *, int);
#define GPT_AIS "a:i:s:"
int gpt_add_ais(gpt_t, off_t *, u_int *, off_t *, int);
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 *);
#endif /* _GPT_H_ */

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.21 2015/12/01 16:32:19 christos Exp $");
__RCSID("$NetBSD: label.c,v 1.22 2015/12/01 19:25:24 christos Exp $");
#endif
#include <sys/types.h>
@ -50,12 +50,6 @@ __RCSID("$NetBSD: label.c,v 1.21 2015/12/01 16:32:19 christos Exp $");
#include "gpt_private.h"
#include "gpt_uuid.h"
static int all;
static gpt_uuid_t type;
static off_t block, size;
static unsigned int entry;
static uint8_t *name, *xlabel;
static int cmd_label(gpt_t, int, char *[]);
static const char *labelhelp[] = {
@ -72,65 +66,21 @@ struct gpt_cmd c_label = {
#define usage() gpt_usage(NULL, &c_label)
static int
label(gpt_t gpt)
static void
change(struct gpt_ent *ent, void *v)
{
map_t m;
struct gpt_hdr *hdr;
struct gpt_ent *ent;
unsigned int i;
if ((hdr = gpt_hdr(gpt)) == NULL)
return -1;
/* Relabel all matching entries in the map. */
for (m = map_first(gpt); m != NULL; m = m->map_next) {
if (m->map_type != MAP_TYPE_GPT_PART || m->map_index < 1)
continue;
if (entry > 0 && entry != m->map_index)
continue;
if (block > 0 && block != m->map_start)
continue;
if (size > 0 && size != m->map_size)
continue;
i = m->map_index - 1;
ent = gpt_ent_primary(gpt, i);
if (xlabel != NULL)
if (strcmp((char *)xlabel,
(char *)utf16_to_utf8(ent->ent_name)) != 0)
continue;
if (!gpt_uuid_is_nil(type) &&
!gpt_uuid_equal(type, ent->ent_type))
continue;
/* Label the primary entry. */
utf8_to_utf16(name, ent->ent_name, 36);
if (gpt_write_primary(gpt) == -1)
return -1;
ent = gpt_ent_backup(gpt, i);
/* Label the secondary entry. */
utf8_to_utf16(name, ent->ent_name, 36);
if (gpt_write_backup(gpt) == -1)
return -1;
gpt_msg(gpt, "Partition %d labeled %s", m->map_index, name);
}
return 0;
uint8_t *name = v;
utf8_to_utf16(name, ent->ent_name, 36);
}
static void
static char *
name_from_file(const char *fn)
{
FILE *f;
char *p;
size_t maxlen = 1024;
size_t len;
char *name;
if (strcmp(fn, "-") != 0) {
f = fopen(fn, "r");
@ -149,79 +99,41 @@ name_from_file(const char *fn)
p = strchr((const char *)name, '\n');
if (p != NULL)
*p = '\0';
return name;
}
static int
cmd_label(gpt_t gpt, int argc, char *argv[])
{
char *p;
int ch;
int64_t human_num;
struct gpt_find find;
char *name = NULL;
memset(&find, 0, sizeof(find));
find.msg = "label changed";
/* Get the label options */
while ((ch = getopt(argc, argv, "ab:f:i:L:l:s:t:")) != -1) {
while ((ch = getopt(argc, argv, GPT_FIND "f:l:")) != -1) {
switch(ch) {
case 'a':
if (all > 0)
return usage();
all = 1;
break;
case 'b':
if (block > 0)
return usage();
if (dehumanize_number(optarg, &human_num) < 0)
return usage();
block = human_num;
if (block < 1)
return usage();
break;
case 'f':
if (name != NULL)
return usage();
name_from_file(optarg);
break;
case 'i':
if (entry > 0)
return usage();
entry = strtoul(optarg, &p, 10);
if (*p != 0 || entry < 1)
return usage();
break;
case 'L':
if (xlabel != NULL)
return usage();
xlabel = (uint8_t *)strdup(optarg);
name = name_from_file(optarg);
break;
case 'l':
if (name != NULL)
return usage();
name = (uint8_t *)strdup(optarg);
break;
case 's':
if (size > 0)
return usage();
size = strtoll(optarg, &p, 10);
if (*p != 0 || size < 1)
return usage();
break;
case 't':
if (!gpt_uuid_is_nil(type))
return usage();
if (gpt_uuid_parse(optarg, type) != 0)
return usage();
name = strdup(optarg);
break;
default:
return usage();
if (gpt_add_find(gpt, &find, ch) == -1)
return usage();
break;
}
}
if (!all ^
(block > 0 || entry > 0 || xlabel != NULL || size > 0 ||
!gpt_uuid_is_nil(type)))
return usage();
if (name == NULL || argc != optind)
return usage();
return label(gpt);
return gpt_change_ent(gpt, &find, change, name);
}

View File

@ -33,7 +33,7 @@
__FBSDID("$FreeBSD: src/sbin/gpt/migrate.c,v 1.16 2005/09/01 02:42:52 marcel Exp $");
#endif
#ifdef __RCSID
__RCSID("$NetBSD: migrate.c,v 1.24 2015/12/01 16:32:19 christos Exp $");
__RCSID("$NetBSD: migrate.c,v 1.25 2015/12/01 19:25:24 christos Exp $");
#endif
#include <sys/types.h>
@ -262,16 +262,13 @@ migrate_netbsd_disklabel(gpt_t gpt, off_t start, struct gpt_ent *ent)
static int
migrate(gpt_t gpt)
{
off_t blocks, last;
off_t last = gpt_last(gpt);
map_t map;
struct gpt_hdr *hdr;
struct gpt_ent *ent;
struct mbr *mbr;
uint32_t start, size;
unsigned int i;
last = gpt->mediasz / gpt->secsz - 1LL;
map = map_find(gpt, MAP_TYPE_MBR);
if (map == NULL || map->map_start != 0) {
gpt_warnx(gpt, "No partitions to convert");
@ -280,86 +277,10 @@ migrate(gpt_t gpt)
mbr = map->map_data;
if (map_find(gpt, MAP_TYPE_PRI_GPT_HDR) != NULL ||
map_find(gpt, MAP_TYPE_SEC_GPT_HDR) != NULL) {
gpt_warnx(gpt, "Device already contains a GPT");
if (gpt_create(gpt, last, parts, 0) == -1)
return -1;
}
/* Get the amount of free space after the MBR */
blocks = map_free(gpt, 1LL, 0LL);
if (blocks == 0LL) {
gpt_warnx(gpt, "No room for the GPT header");
return -1;
}
/* Don't create more than parts entries. */
if ((uint64_t)(blocks - 1) * gpt->secsz >
parts * sizeof(struct gpt_ent)) {
blocks = (parts * sizeof(struct gpt_ent)) / gpt->secsz;
if ((parts * sizeof(struct gpt_ent)) % gpt->secsz)
blocks++;
blocks++; /* Don't forget the header itself */
}
/* Never cross the median of the device. */
if ((blocks + 1LL) > ((last + 1LL) >> 1))
blocks = ((last + 1LL) >> 1) - 1LL;
/*
* Get the amount of free space at the end of the device and
* calculate the size for the GPT structures.
*/
map = map_last(gpt);
if (map->map_type != MAP_TYPE_UNUSED) {
gpt_warnx(gpt, "No room for the backup header");
return -1;
}
if (map->map_size < blocks)
blocks = map->map_size;
if (blocks == 1LL) {
gpt_warnx(gpt, "No room for the GPT table");
return -1;
}
blocks--; /* Number of blocks in the GPT table. */
gpt->gpt = map_add(gpt, 1LL, 1LL, MAP_TYPE_PRI_GPT_HDR,
calloc(1, gpt->secsz));
gpt->tbl = map_add(gpt, 2LL, blocks, MAP_TYPE_PRI_GPT_TBL,
calloc(blocks, gpt->secsz));
if (gpt->gpt == NULL || gpt->tbl == NULL)
return -1;
gpt->lbt = map_add(gpt, last - blocks, blocks, MAP_TYPE_SEC_GPT_TBL,
gpt->tbl->map_data);
gpt->tpg = map_add(gpt, last, 1LL, MAP_TYPE_SEC_GPT_HDR,
calloc(1, gpt->secsz));
hdr = gpt->gpt->map_data;
memcpy(hdr->hdr_sig, GPT_HDR_SIG, sizeof(hdr->hdr_sig));
hdr->hdr_revision = htole32(GPT_HDR_REVISION);
/*
* XXX struct gpt_hdr is not a multiple of 8 bytes in size and thus
* contains padding we must not include in the size.
*/
hdr->hdr_size = htole32(GPT_HDR_SIZE);
hdr->hdr_lba_self = htole64(gpt->gpt->map_start);
hdr->hdr_lba_alt = htole64(gpt->tpg->map_start);
hdr->hdr_lba_start = htole64(gpt->tbl->map_start + blocks);
hdr->hdr_lba_end = htole64(gpt->lbt->map_start - 1LL);
gpt_uuid_generate(hdr->hdr_guid);
hdr->hdr_lba_table = htole64(gpt->tbl->map_start);
hdr->hdr_entries = htole32((blocks * gpt->secsz) / sizeof(struct gpt_ent));
if (le32toh(hdr->hdr_entries) > parts)
hdr->hdr_entries = htole32(parts);
hdr->hdr_entsz = htole32(sizeof(struct gpt_ent));
ent = gpt->tbl->map_data;
for (i = 0; i < le32toh(hdr->hdr_entries); i++) {
gpt_uuid_generate(ent[i].ent_guid);
}
/* Mirror partitions. */
for (i = 0; i < 4; i++) {
@ -408,26 +329,18 @@ migrate(gpt_t gpt)
if (gpt_write_primary(gpt) == -1)
return -1;
/*
* Create backup GPT.
*/
memcpy(gpt->tpg->map_data, gpt->gpt->map_data, gpt->secsz);
hdr = gpt->tpg->map_data;
hdr->hdr_lba_self = htole64(gpt->tpg->map_start);
hdr->hdr_lba_alt = htole64(gpt->gpt->map_start);
hdr->hdr_lba_table = htole64(gpt->lbt->map_start);
if (gpt_write_backup(gpt) == -1)
return -1;
map = map_find(gpt, MAP_TYPE_MBR);
mbr = map->map_data;
/*
* Turn the MBR into a Protective MBR.
*/
memset(mbr->mbr_part, 0, sizeof(mbr->mbr_part));
gpt_create_pmbr_part(mbr->mbr_part, last);
gpt_write(gpt, map);
if (gpt_write(gpt, map) == -1) {
gpt_warn(gpt, "Cant write PMBR");
return -1;
}
return 0;
}

View File

@ -33,7 +33,7 @@
__FBSDID("$FreeBSD: src/sbin/gpt/remove.c,v 1.10 2006/10/04 18:20:25 marcel Exp $");
#endif
#ifdef __RCSID
__RCSID("$NetBSD: remove.c,v 1.19 2015/12/01 16:32:19 christos Exp $");
__RCSID("$NetBSD: remove.c,v 1.20 2015/12/01 19:25:24 christos Exp $");
#endif
#include <sys/types.h>
@ -49,12 +49,6 @@ __RCSID("$NetBSD: remove.c,v 1.19 2015/12/01 16:32:19 christos Exp $");
#include "gpt.h"
#include "gpt_private.h"
static int all;
static gpt_uuid_t type;
static off_t block, size;
static unsigned int entry;
static uint8_t *label;
static int cmd_remove(gpt_t, int, char *[]);
static const char *removehelp[] = {
@ -71,119 +65,29 @@ struct gpt_cmd c_remove = {
#define usage() gpt_usage(NULL, &c_remove)
static int
rem(gpt_t gpt)
static void
change(struct gpt_ent *ent, void *v)
{
map_t m;
struct gpt_ent *ent;
unsigned int i;
if (gpt_hdr(gpt) == NULL)
return -1;
/* Remove all matching entries in the map. */
for (m = map_first(gpt); m != NULL; m = m->map_next) {
if (m->map_type != MAP_TYPE_GPT_PART || m->map_index < 1)
continue;
if (entry > 0 && entry != m->map_index)
continue;
if (block > 0 && block != m->map_start)
continue;
if (size > 0 && size != m->map_size)
continue;
i = m->map_index - 1;
ent = gpt_ent_primary(gpt, i);
if (label != NULL)
if (strcmp((char *)label,
(char *)utf16_to_utf8(ent->ent_name)) != 0)
continue;
if (!gpt_uuid_is_nil(type) &&
!gpt_uuid_equal(type, ent->ent_type))
continue;
/* Remove the primary entry by clearing the partition type. */
gpt_uuid_copy(ent->ent_type, gpt_uuid_nil);
if (gpt_write_primary(gpt) == -1)
return -1;
ent = gpt_ent_backup(gpt, i);
/* Remove the secondary entry. */
gpt_uuid_copy(ent->ent_type, gpt_uuid_nil);
if (gpt_write_backup(gpt) == -1)
return -1;
gpt_msg(gpt, "partition %d removed", m->map_index);
}
return 0;
/* Remove the primary entry by clearing the partition type. */
gpt_uuid_copy(ent->ent_type, gpt_uuid_nil);
}
static int
cmd_remove(gpt_t gpt, int argc, char *argv[])
{
char *p;
int ch;
int64_t human_num;
struct gpt_find find;
memset(&find, 0, sizeof(find));
find.msg = "removed";
/* Get the remove options */
while ((ch = getopt(argc, argv, "ab:i:L:s:t:")) != -1) {
switch(ch) {
case 'a':
if (all > 0)
return usage();
all = 1;
break;
case 'b':
if (block > 0)
return usage();
if (dehumanize_number(optarg, &human_num) < 0)
return usage();
block = human_num;
if (block < 1)
return usage();
break;
case 'i':
if (entry > 0)
return usage();
entry = strtoul(optarg, &p, 10);
if (*p != 0 || entry < 1)
return usage();
break;
case 'L':
if (label != NULL)
return usage();
label = (uint8_t *)strdup(optarg);
break;
case 's':
if (size > 0)
usage();
size = strtoll(optarg, &p, 10);
if (*p != 0 || size < 1)
return usage();
break;
case 't':
if (!gpt_uuid_is_nil(type))
return usage();
if (gpt_uuid_parse(optarg, type) != 0)
return usage();
break;
default:
while ((ch = getopt(argc, argv, GPT_FIND)) != -1)
if (gpt_add_find(gpt, &find, ch) == -1)
return usage();
}
}
if (!all ^
(block > 0 || entry > 0 || label != NULL || size > 0 ||
!gpt_uuid_is_nil(type)))
return usage();
if (argc != optind)
return usage();
return rem(gpt);
return gpt_change_ent(gpt, &find, change, NULL);
}

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: resize.c,v 1.16 2015/12/01 16:32:19 christos Exp $");
__RCSID("$NetBSD: resize.c,v 1.17 2015/12/01 19:25:24 christos Exp $");
#endif
#include <sys/types.h>
@ -139,67 +139,17 @@ resize(gpt_t gpt)
static int
cmd_resize(gpt_t gpt, int argc, char *argv[])
{
char *p;
int ch;
int64_t human_num;
while ((ch = getopt(argc, argv, "a:i:s:")) != -1) {
switch(ch) {
case 'a':
if (alignment > 0)
return usage();
if (dehumanize_number(optarg, &human_num) < 0)
return usage();
alignment = human_num;
if (alignment < 1)
return usage();
break;
case 'i':
if (entry > 0)
return usage();
entry = strtoul(optarg, &p, 10);
if (*p != 0 || entry < 1)
return usage();
break;
case 's':
if (sectors > 0 || size > 0)
return usage();
sectors = strtoll(optarg, &p, 10);
if (sectors < 1)
return usage();
if (*p == '\0')
break;
if (*p == 's' || *p == 'S') {
if (*(p + 1) == '\0')
break;
else
return usage();
}
if (*p == 'b' || *p == 'B') {
if (*(p + 1) == '\0') {
size = sectors;
sectors = 0;
break;
} else
return usage();
}
if (dehumanize_number(optarg, &human_num) < 0)
return usage();
size = human_num;
sectors = 0;
break;
default:
while ((ch = getopt(argc, argv, GPT_AIS)) != -1) {
if (gpt_add_ais(gpt, &alignment, &entry, &size, ch) == -1)
return usage();
}
}
if (argc != optind)
return usage();
if (entry == 0)
return usage();
if ((sectors = gpt_check(gpt, alignment, size)) == -1)
if ((sectors = gpt_check_ais(gpt, alignment, entry, size)) == -1)
return -1;
return resize(gpt);

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: resizedisk.c,v 1.9 2015/12/01 16:32:19 christos Exp $");
__RCSID("$NetBSD: resizedisk.c,v 1.10 2015/12/01 19:25:24 christos Exp $");
#endif
#include <sys/bootblock.h>
@ -223,38 +223,13 @@ resizedisk(gpt_t gpt)
static int
cmd_resizedisk(gpt_t gpt, int argc, char *argv[])
{
char *p;
int ch;
int64_t human_num;
while ((ch = getopt(argc, argv, "s:")) != -1) {
switch(ch) {
case 's':
if (sector > 0 || size > 0)
return usage();
sector = strtoll(optarg, &p, 10);
if (sector < 1)
return usage();
if (*p == '\0')
break;
if (*p == 's' || *p == 'S') {
if (*(p + 1) == '\0')
break;
else
return usage();
}
if (*p == 'b' || *p == 'B') {
if (*(p + 1) == '\0') {
size = sector;
sector = 0;
break;
} else
return usage();
}
if (dehumanize_number(optarg, &human_num) < 0)
return usage();
size = human_num;
sector = 0;
if (gpt_add_ais(gpt, NULL, NULL, &size, ch) == -1)
return -1;
break;
default:
return usage();
@ -264,7 +239,7 @@ cmd_resizedisk(gpt_t gpt, int argc, char *argv[])
if (argc != optind)
return usage();
if ((sector = gpt_check(gpt, 0, size)) == -1)
if ((sector = gpt_check_ais(gpt, 0, ~0, size)) == -1)
return -1;
return resizedisk(gpt);

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: set.c,v 1.8 2015/12/01 16:32:19 christos Exp $");
__RCSID("$NetBSD: set.c,v 1.9 2015/12/01 19:25:24 christos Exp $");
#endif
#include <sys/types.h>
@ -49,9 +49,6 @@ __RCSID("$NetBSD: set.c,v 1.8 2015/12/01 16:32:19 christos Exp $");
#include "gpt.h"
#include "gpt_private.h"
static unsigned int entry;
static uint64_t attributes;
static int cmd_set(gpt_t, int, char *[]);
static const char *sethelp[] = {
@ -67,71 +64,21 @@ struct gpt_cmd c_set = {
#define usage() gpt_usage(NULL, &c_set)
static int
set(gpt_t gpt)
{
struct gpt_hdr *hdr;
struct gpt_ent *ent;
unsigned int i;
if ((hdr = gpt_hdr(gpt)) == NULL)
return -1;
if (entry > le32toh(hdr->hdr_entries)) {
gpt_warnx(gpt, "Index %u out of range (%u max)",
entry, le32toh(hdr->hdr_entries));
return -1;
}
i = entry - 1;
ent = gpt_ent_primary(gpt, i);
if (gpt_uuid_is_nil(ent->ent_type)) {
gpt_warnx(gpt, "Entry at index %u is unused", entry);
return -1;
}
ent->ent_attr |= attributes;
if (gpt_write_primary(gpt) == -1)
return -1;
ent = gpt_ent_backup(gpt, i);
ent->ent_attr |= attributes;
if (gpt_write_backup(gpt) == -1)
return -1;
gpt_msg(gpt, "Partition %d attributes updated", entry);
return 0;
}
static int
cmd_set(gpt_t gpt, int argc, char *argv[])
{
char *p;
int ch;
unsigned int entry = 0;
uint64_t attributes = 0;
while ((ch = getopt(argc, argv, "a:i:")) != -1) {
switch(ch) {
case 'a':
if (strcmp(optarg, "biosboot") == 0)
attributes |= GPT_ENT_ATTR_LEGACY_BIOS_BOOTABLE;
else if (strcmp(optarg, "bootme") == 0)
attributes |= GPT_ENT_ATTR_BOOTME;
else if (strcmp(optarg, "bootonce") == 0)
attributes |= GPT_ENT_ATTR_BOOTONCE;
else if (strcmp(optarg, "bootfailed") == 0)
attributes |= GPT_ENT_ATTR_BOOTFAILED;
else
if (gpt_attr_get(&attributes) == -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;
default:
@ -142,8 +89,5 @@ cmd_set(gpt_t gpt, int argc, char *argv[])
if (argc != optind)
return usage();
if (entry == 0 || attributes == 0)
return usage();
return set(gpt);
return gpt_attr_update(gpt, entry, attributes, 0);
}

View File

@ -33,7 +33,7 @@
__FBSDID("$FreeBSD: src/sbin/gpt/remove.c,v 1.10 2006/10/04 18:20:25 marcel Exp $");
#endif
#ifdef __RCSID
__RCSID("$NetBSD: type.c,v 1.9 2015/12/01 16:32:19 christos Exp $");
__RCSID("$NetBSD: type.c,v 1.10 2015/12/01 19:25:24 christos Exp $");
#endif
#include <sys/types.h>
@ -49,12 +49,6 @@ __RCSID("$NetBSD: type.c,v 1.9 2015/12/01 16:32:19 christos Exp $");
#include "gpt.h"
#include "gpt_private.h"
static int all;
static gpt_uuid_t type, newtype;
static off_t block, size;
static unsigned int entry;
static uint8_t *label;
static int cmd_type(gpt_t, int, char *[]);
static const char *typehelp[] = {
@ -71,108 +65,26 @@ struct gpt_cmd c_type = {
#define usage() gpt_usage(NULL, &c_type)
static int
chtype(gpt_t gpt)
static void
change(struct gpt_ent *ent, void *v)
{
map_t m;
struct gpt_ent *ent;
unsigned int i;
if (gpt_hdr(gpt) == NULL)
return -1;
/* Change type of all matching entries in the map. */
for (m = map_first(gpt); m != NULL; m = m->map_next) {
if (m->map_type != MAP_TYPE_GPT_PART || m->map_index < 1)
continue;
if (entry > 0 && entry != m->map_index)
continue;
if (block > 0 && block != m->map_start)
continue;
if (size > 0 && size != m->map_size)
continue;
i = m->map_index - 1;
ent = gpt_ent_primary(gpt, i);
if (label != NULL)
if (strcmp((char *)label,
(char *)utf16_to_utf8(ent->ent_name)) != 0)
continue;
if (!gpt_uuid_is_nil(type) &&
!gpt_uuid_equal(type, ent->ent_type))
continue;
/* Change the primary entry. */
gpt_uuid_copy(ent->ent_type, newtype);
if (gpt_write_primary(gpt) == -1)
return -1;
ent = gpt_ent_backup(gpt, i);
/* Change the secondary entry. */
gpt_uuid_copy(ent->ent_type, newtype);
if (gpt_write_backup(gpt) == -1)
return -1;
gpt_msg(gpt, "Partition %d type changed", m->map_index);
}
return 0;
gpt_uuid_t *newtype = v;
gpt_uuid_copy(ent->ent_type, *newtype);
}
static int
cmd_type(gpt_t gpt, int argc, char *argv[])
{
char *p;
int ch;
int64_t human_num;
gpt_uuid_t newtype;
struct gpt_find find;
memset(&find, 0, sizeof(find));
find.msg = "type changed";
/* Get the type options */
while ((ch = getopt(argc, argv, "ab:i:L:s:t:T:")) != -1) {
while ((ch = getopt(argc, argv, GPT_FIND "T:")) != -1) {
switch(ch) {
case 'a':
if (all > 0)
return usage();
all = 1;
break;
case 'b':
if (block > 0)
return usage();
if (dehumanize_number(optarg, &human_num) < 0)
return usage();
block = human_num;
if (block < 1)
return usage();
break;
case 'i':
if (entry > 0)
return usage();
entry = strtoul(optarg, &p, 10);
if (*p != 0 || entry < 1)
return usage();
break;
case 'L':
if (label != NULL)
return usage();
label = (uint8_t *)strdup(optarg);
break;
case 's':
if (size > 0)
return usage();
size = strtoll(optarg, &p, 10);
if (*p != 0 || size < 1)
return usage();
break;
case 't':
if (!gpt_uuid_is_nil(type))
return usage();
if (gpt_uuid_parse(optarg, type) != 0)
return usage();
break;
case 'T':
if (!gpt_uuid_is_nil(newtype))
return usage();
@ -180,19 +92,14 @@ cmd_type(gpt_t gpt, int argc, char *argv[])
return usage();
break;
default:
return usage();
if (gpt_add_find(gpt, &find, ch) == -1)
return usage();
break;
}
}
if (!all ^
(block > 0 || entry > 0 || label != NULL || size > 0 ||
!gpt_uuid_is_nil(type)))
return usage();
if (gpt_uuid_is_nil(newtype))
if (gpt_uuid_is_nil(newtype) || argc != optind)
return usage();
if (argc != optind)
return usage();
return chtype(gpt);
return gpt_change_ent(gpt, &find, change, &newtype);
}

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: unset.c,v 1.8 2015/12/01 16:32:19 christos Exp $");
__RCSID("$NetBSD: unset.c,v 1.9 2015/12/01 19:25:24 christos Exp $");
#endif
#include <sys/types.h>
@ -49,9 +49,6 @@ __RCSID("$NetBSD: unset.c,v 1.8 2015/12/01 16:32:19 christos Exp $");
#include "gpt.h"
#include "gpt_private.h"
static unsigned int entry;
static uint64_t attributes;
static int cmd_unset(gpt_t, int, char *[]);
static const char *unsethelp[] = {
@ -67,69 +64,21 @@ struct gpt_cmd c_unset = {
#define usage() gpt_usage(NULL, &c_unset)
static int
unset(gpt_t gpt)
{
struct gpt_hdr *hdr;
struct gpt_ent *ent;
unsigned int i;
if ((hdr = gpt_hdr(gpt)) == NULL)
return -1;
if (entry > le32toh(hdr->hdr_entries)) {
gpt_warnx(gpt, "Index %u out of range (%u max)",
entry, le32toh(hdr->hdr_entries));
return -1;
}
i = entry - 1;
ent = gpt_ent_primary(gpt, i);
if (gpt_uuid_is_nil(ent->ent_type)) {
gpt_warnx(gpt, "Entry at index %u is unused", entry);
return -1;
}
ent->ent_attr &= ~attributes;
if (gpt_write_primary(gpt) == -1)
return -1;
ent = gpt_ent_backup(gpt, i);
ent->ent_attr &= ~attributes;
if (gpt_write_backup(gpt) == -1)
return -1;
gpt_msg(gpt, "Partition %d attributes updated", entry);
return 0;
}
static int
cmd_unset(gpt_t gpt, int argc, char *argv[])
{
char *p;
int ch;
unsigned int entry = 0;
uint64_t attributes = 0;
while ((ch = getopt(argc, argv, "a:i:")) != -1) {
switch(ch) {
case 'a':
if (strcmp(optarg, "biosboot") == 0)
attributes |= GPT_ENT_ATTR_LEGACY_BIOS_BOOTABLE;
else if (strcmp(optarg, "bootme") == 0)
attributes |= GPT_ENT_ATTR_BOOTME;
else if (strcmp(optarg, "bootonce") == 0)
attributes |= GPT_ENT_ATTR_BOOTONCE;
else if (strcmp(optarg, "bootfailed") == 0)
attributes |= GPT_ENT_ATTR_BOOTFAILED;
else
if (gpt_attr_get(&attributes) == -1)
return usage();
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;
default:
@ -140,8 +89,5 @@ cmd_unset(gpt_t gpt, int argc, char *argv[])
if (argc != optind)
return usage();
if (entry == 0 || attributes == 0)
return usage();
return unset(gpt);
return gpt_attr_update(gpt, entry, 0, attributes);
}