aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sbin/gpt/Makefile2
-rw-r--r--sbin/gpt/add.c192
-rw-r--r--sbin/gpt/create.c6
-rw-r--r--sbin/gpt/gpt.c104
-rw-r--r--sbin/gpt/gpt.h42
-rw-r--r--sbin/gpt/map.c77
-rw-r--r--sbin/gpt/map.h6
-rw-r--r--sbin/gpt/migrate.c6
-rw-r--r--sbin/gpt/show.c58
9 files changed, 389 insertions, 104 deletions
diff --git a/sbin/gpt/Makefile b/sbin/gpt/Makefile
index e6d76cb21b40..0e521976f7c1 100644
--- a/sbin/gpt/Makefile
+++ b/sbin/gpt/Makefile
@@ -1,7 +1,7 @@
# $FreeBSD$
PROG= gpt
-SRCS= create.c destroy.c gpt.c map.c migrate.c recover.c show.c
+SRCS= add.c create.c destroy.c gpt.c map.c migrate.c recover.c show.c
WARNS= 4
NOMAN= not yet
diff --git a/sbin/gpt/add.c b/sbin/gpt/add.c
new file mode 100644
index 000000000000..3423918f9f56
--- /dev/null
+++ b/sbin/gpt/add.c
@@ -0,0 +1,192 @@
+/*
+ * Copyright (c) 2002 Marcel Moolenaar
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/types.h>
+#include <sys/disklabel.h>
+#include <sys/uuid.h>
+#include <sys/gpt.h>
+
+#include <err.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "map.h"
+#include "gpt.h"
+
+off_t block, size;
+uuid_t type;
+
+static void
+usage_add(void)
+{
+
+ fprintf(stderr,
+ "usage: %s [-bst] device\n", getprogname());
+ exit(1);
+}
+
+static void
+add(int fd)
+{
+ map_t *gpt, *tpg;
+ map_t *tbl, *lbt;
+ map_t *map;
+ struct gpt_hdr *hdr;
+ struct gpt_ent *ent;
+ unsigned int i;
+
+ gpt = map_find(MAP_TYPE_PRI_GPT_HDR);
+ if (gpt == NULL) {
+ warnx("%s: error: device does not contain a GPT", device_name);
+ return;
+ }
+
+ tpg = map_find(MAP_TYPE_SEC_GPT_HDR);
+ if (tpg == NULL) {
+ warnx("%s: error: no secundary table; run recover",
+ device_name);
+ return;
+ }
+
+ tbl = map_find(MAP_TYPE_PRI_GPT_TBL);
+ lbt = map_find(MAP_TYPE_SEC_GPT_TBL);
+ if (tbl == NULL || lbt == NULL) {
+ warnx("%s: error: run recover -- trust me", device_name);
+ return;
+ }
+
+ /* Create UFS partitions by default. */
+ if (uuid_is_nil(&type, NULL)) {
+ uuid_t ufs = GPT_ENT_TYPE_FREEBSD_UFS;
+ type = ufs;
+ }
+
+ map = map_alloc(block, size);
+ if (map == NULL) {
+ warnx("%s: error: no space available on device", device_name);
+ return;
+ }
+
+ /* Find empty slot in GPT table. */
+ hdr = gpt->map_data;
+ for (i = 0; i < hdr->hdr_entries; i++) {
+ ent = (void*)((char*)tbl->map_data + i * hdr->hdr_entsz);
+ if (uuid_is_nil(&ent->ent_type, NULL))
+ break;
+ }
+ if (i == hdr->hdr_entries) {
+ warnx("%s: error: no available table entries", device_name);
+ return;
+ }
+
+ ent->ent_type = type;
+ ent->ent_lba_start = map->map_start;
+ ent->ent_lba_end = map->map_start + map->map_size - 1LL;
+
+ hdr->hdr_crc_table = crc32(tbl->map_data,
+ hdr->hdr_entries * hdr->hdr_entsz);
+ hdr->hdr_crc_self = 0;
+ hdr->hdr_crc_self = crc32(hdr, hdr->hdr_size);
+
+ gpt_write(fd, gpt);
+ gpt_write(fd, tbl);
+
+ hdr = tpg->map_data;
+ ent = (void*)((char*)lbt->map_data + i * hdr->hdr_entsz);
+
+ ent->ent_type = type;
+ ent->ent_lba_start = map->map_start;
+ ent->ent_lba_end = map->map_start + map->map_size - 1LL;
+
+ hdr->hdr_crc_table = crc32(lbt->map_data,
+ hdr->hdr_entries * hdr->hdr_entsz);
+ hdr->hdr_crc_self = 0;
+ hdr->hdr_crc_self = crc32(hdr, hdr->hdr_size);
+
+ gpt_write(fd, lbt);
+ gpt_write(fd, tpg);
+}
+
+int
+cmd_add(int argc, char *argv[])
+{
+ char *p;
+ int ch, fd;
+ uint32_t status;
+
+ /* Get the migrate options */
+ while ((ch = getopt(argc, argv, "b:s:t:")) != -1) {
+ switch(ch) {
+ case 'b':
+ if (block > 0)
+ usage_add();
+ block = strtol(optarg, &p, 10);
+ if (*p != 0 || block < 1)
+ usage_add();
+ break;
+ case 's':
+ if (size > 0)
+ usage_add();
+ size = strtol(optarg, &p, 10);
+ if (*p != 0 || size < 1)
+ usage_add();
+ break;
+ case 't':
+ if (!uuid_is_nil(&type, NULL))
+ usage_add();
+ uuid_from_string(optarg, &type, &status);
+ if (status != uuid_s_ok) {
+ /* TODO: accept aliases. */
+ usage_add();
+ }
+ break;
+ default:
+ usage_add();
+ }
+ }
+
+ if (argc == optind)
+ usage_add();
+
+ while (optind < argc) {
+ fd = gpt_open(argv[optind++]);
+ if (fd == -1) {
+ warn("unable to open device '%s'", device_name);
+ continue;
+ }
+
+ add(fd);
+
+ gpt_close(fd);
+ }
+
+ return (0);
+}
diff --git a/sbin/gpt/create.c b/sbin/gpt/create.c
index a82970ddab79..b2904f61e968 100644
--- a/sbin/gpt/create.c
+++ b/sbin/gpt/create.c
@@ -69,7 +69,7 @@ create(int fd)
}
/* Get the amount of free space after the MBR */
- blocks = map_unused(1LL, 0LL);
+ blocks = map_free(1LL, 0LL);
if (blocks == 0LL) {
warnx("%s: error: no room for the GPT header", device_name);
return;
@@ -125,7 +125,7 @@ create(int fd)
hdr->hdr_lba_alt = last;
hdr->hdr_lba_start = tbl->map_start + blocks;
hdr->hdr_lba_end = last - blocks - 1LL;
- uuidgen(&hdr->hdr_uuid, 1);
+ uuid_create(&hdr->hdr_uuid, NULL);
hdr->hdr_lba_table = tbl->map_start;
hdr->hdr_entries = (blocks * secsz) / sizeof(struct gpt_ent);
if (hdr->hdr_entries > parts)
@@ -134,7 +134,7 @@ create(int fd)
ent = tbl->map_data;
for (i = 0; i < hdr->hdr_entries; i++)
- uuidgen(&ent[i].ent_uuid, 1);
+ uuid_create(&ent[i].ent_uuid, NULL);
hdr->hdr_crc_table = crc32(ent, hdr->hdr_entries * hdr->hdr_entsz);
hdr->hdr_crc_self = crc32(hdr, hdr->hdr_size);
diff --git a/sbin/gpt/gpt.c b/sbin/gpt/gpt.c
index e3f1365ebd06..18156e8fff07 100644
--- a/sbin/gpt/gpt.c
+++ b/sbin/gpt/gpt.c
@@ -127,18 +127,62 @@ unicode16(short *dst, const wchar_t *src, size_t len)
*dst = 0;
}
-static char *
-uuid_string(uuid_t *uuid)
+#ifdef NEED_UUID_FUNCTIONS
+void
+uuid_create(uuid_t *u, uint32_t *st __unused)
+{
+ uuidgen(u, 1);
+}
+
+void
+uuid_from_string(const char *s, uuid_t *u, uint32_t *st)
{
- static char buf[48];
+ int n;
+
+ *st = uuid_s_invalid_string_uuid;
+
+ if (strlen(s) != 36 || s[8] != '-')
+ return;
+
+ n = sscanf(s,
+ "%8x-%4hx-%4hx-%2hhx%2hhx-%2hhx%2hhx%2hhx%2hhx%2hhx%2hhx",
+ &u->time_low, &u->time_mid, &u->time_hi_and_version,
+ &u->clock_seq_hi_and_reserved, &u->clock_seq_low, &u->node[0],
+ &u->node[1], &u->node[2], &u->node[3], &u->node[4], &u->node[5]);
+
+ if (n != 11)
+ return;
+
+ n = u->clock_seq_hi_and_reserved;
+ if ((n & 0x80) != 0x00 && /* variant 0? */
+ (n & 0xc0) != 0x80 && /* variant 1? */
+ (n & 0xe0) != 0xc0) /* variant 2? */
+ *st = uuid_s_bad_version;
+ else
+ *st = uuid_s_ok;
+}
+
+int32_t
+uuid_is_nil(uuid_t *u, uint32_t *st __unused)
+{
+ uint32_t *p;
+
+ p = (uint32_t*)u;
+ return ((p[0] == 0 && p[1] == 0 && p[2] == 0 && p[3] == 0) ? 1 : 0);
+}
+
+void
+uuid_to_string(uuid_t *u, char **s, uint32_t *st __unused)
+{
+ char buf[40];
sprintf(buf, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
- uuid->time_low, uuid->time_mid, uuid->time_hi_and_version,
- uuid->clock_seq_hi_and_reserved, uuid->clock_seq_low,
- uuid->node[0], uuid->node[1], uuid->node[2], uuid->node[3],
- uuid->node[4], uuid->node[5]);
- return buf;
+ u->time_low, u->time_mid, u->time_hi_and_version,
+ u->clock_seq_hi_and_reserved, u->clock_seq_low, u->node[0],
+ u->node[1], u->node[2], u->node[3], u->node[4], u->node[5]);
+ *s = strdup(buf);
}
+#endif
void*
gpt_read(int fd, off_t lba, size_t count)
@@ -180,7 +224,7 @@ gpt_gpt(int fd, off_t lba)
off_t size;
struct gpt_ent *ent;
struct gpt_hdr *hdr;
- char *p;
+ char *p, *s;
map_t *m;
size_t blocks, tblsz;
unsigned int i;
@@ -235,20 +279,19 @@ gpt_gpt(int fd, off_t lba)
return (0);
for (i = 0; i < hdr->hdr_entries; i++) {
- uuid_t unused = GPT_ENT_TYPE_UNUSED;
-
ent = (void*)(p + i * hdr->hdr_entsz);
- if (!memcmp(&ent->ent_type, &unused, sizeof(uuid_t)))
+ if (uuid_is_nil(&ent->ent_type, NULL))
continue;
size = ent->ent_lba_end - ent->ent_lba_start + 1LL;
-
- if (verbose > 2)
+ if (verbose > 2) {
+ uuid_to_string(&ent->ent_type, &s, NULL);
warnx(
- "%s: GPT partition: type=%s, start=%llu, size=%llu",
- device_name, uuid_string(&ent->ent_type),
+ "%s: GPT partition: type=%s, start=%llu, size=%llu", device_name, s,
(long long)ent->ent_lba_start, (long long)size);
- m = map_add(ent->ent_lba_start, size, MAP_TYPE_GPT_PART, NULL);
+ free(s);
+ }
+ m = map_add(ent->ent_lba_start, size, MAP_TYPE_GPT_PART, ent);
if (m == NULL)
return (-1);
}
@@ -338,19 +381,18 @@ gpt_open(const char *dev)
start = (start << 16) + mbr->mbr_part[i].part_start_lo;
size = mbr->mbr_part[i].part_size_hi;
size = (size << 16) + mbr->mbr_part[i].part_size_lo;
- if (start != 0 || size != 0) {
- if (verbose > 2)
- warnx(
- "%s: MBR partition: type=%d, start=%llu, size=%llu", device_name,
- mbr->mbr_part[i].part_typ,
- (long long)start, (long long)size);
- if (mbr->mbr_part[i].part_typ != 0xee) {
- m = map_add(start, size,
- MAP_TYPE_MBR_PART, NULL);
- if (m == NULL)
- goto close;
- }
- }
+ if (start == 0 && size == 0)
+ continue;
+ if (verbose > 2)
+ warnx("%s: MBR partition: type=%d, start=%llu, size=%llu",
+ device_name, mbr->mbr_part[i].part_typ,
+ (long long)start, (long long)size);
+ if (mbr->mbr_part[i].part_typ == 0xee)
+ continue;
+ m = map_add(start, size, MAP_TYPE_MBR_PART,
+ mbr->mbr_part + i);
+ if (m == NULL)
+ goto close;
}
} else {
if (verbose)
@@ -384,7 +426,7 @@ static struct {
int (*fptr)(int, char *[]);
const char *name;
} cmdsw[] = {
- { NULL, "add" },
+ { cmd_add, "add" },
{ cmd_create, "create" },
{ NULL, "delete" },
{ cmd_destroy, "destroy" },
diff --git a/sbin/gpt/gpt.h b/sbin/gpt/gpt.h
index 268abe1b4755..a670b32f3790 100644
--- a/sbin/gpt/gpt.h
+++ b/sbin/gpt/gpt.h
@@ -29,26 +29,39 @@
#ifndef _GPT_H_
#define _GPT_H_
+struct mbr_part {
+ uint8_t part_flag; /* bootstrap flags */
+ uint8_t part_shd; /* starting head */
+ uint8_t part_ssect; /* starting sector */
+ uint8_t part_scyl; /* starting cylinder */
+ uint8_t part_typ; /* partition type */
+ uint8_t part_ehd; /* end head */
+ uint8_t part_esect; /* end sector */
+ uint8_t part_ecyl; /* end cylinder */
+ uint16_t part_start_lo; /* absolute starting ... */
+ uint16_t part_start_hi; /* ... sector number */
+ uint16_t part_size_lo; /* partition size ... */
+ uint16_t part_size_hi; /* ... in sectors */
+};
+
struct mbr {
uint16_t mbr_code[223];
- struct {
- uint8_t part_flag; /* bootstrap flags */
- uint8_t part_shd; /* starting head */
- uint8_t part_ssect; /* starting sector */
- uint8_t part_scyl; /* starting cylinder */
- uint8_t part_typ; /* partition type */
- uint8_t part_ehd; /* end head */
- uint8_t part_esect; /* end sector */
- uint8_t part_ecyl; /* end cylinder */
- uint16_t part_start_lo; /* absolute starting ... */
- uint16_t part_start_hi; /* ... sector number */
- uint16_t part_size_lo; /* partition size ... */
- uint16_t part_size_hi; /* ... in sectors */
- } mbr_part[4];
+ struct mbr_part mbr_part[4];
uint16_t mbr_sig;
#define MBR_SIG 0xAA55
};
+#ifndef uuid_s_ok
+#define NEED_UUID_FUNCTIONS
+#define uuid_s_ok 0
+#define uuid_s_bad_version 1
+#define uuid_s_invalid_string_uuid 2
+void uuid_create(uuid_t *, uint32_t *);
+void uuid_from_string(const char *, uuid_t *, uint32_t *);
+int32_t uuid_is_nil(uuid_t *, uint32_t *);
+void uuid_to_string(uuid_t *, char **, uint32_t *);
+#endif
+
extern char device_name[];
extern off_t mediasz;
extern u_int parts;
@@ -62,6 +75,7 @@ void* gpt_read(int, off_t, size_t);
int gpt_write(int, map_t *);
void unicode16(short *, const wchar_t *, size_t);
+int cmd_add(int, char *[]);
int cmd_create(int, char *[]);
int cmd_destroy(int, char *[]);
int cmd_migrate(int, char *[]);
diff --git a/sbin/gpt/map.c b/sbin/gpt/map.c
index 5aba63cd66c9..fbce87fd9732 100644
--- a/sbin/gpt/map.c
+++ b/sbin/gpt/map.c
@@ -33,7 +33,8 @@
#include "map.h"
-static int lbawidth;
+int lbawidth;
+
static map_t *mediamap;
static map_t *
@@ -133,6 +134,31 @@ map_add(off_t start, off_t size, int type, void *data)
}
map_t *
+map_alloc(off_t start, off_t size)
+{
+ off_t delta;
+ map_t *m;
+
+ for (m = mediamap; m != NULL; m = m->map_next) {
+ if (m->map_type != MAP_TYPE_UNUSED || m->map_start < 2)
+ continue;
+ if (start != 0 && m->map_start > start)
+ return (NULL);
+ delta = (start != 0) ? start - m->map_start : 0;
+ if (size == 0 || m->map_size - delta >= size) {
+ if (m->map_size - delta <= 0)
+ continue;
+ if (size == 0)
+ size = m->map_size - delta;
+ return (map_add(m->map_start + delta, size,
+ MAP_TYPE_GPT_PART, NULL));
+ }
+ }
+
+ return (NULL);
+}
+
+map_t *
map_find(int type)
{
map_t *m;
@@ -161,7 +187,7 @@ map_last(void)
}
off_t
-map_unused(off_t start, off_t size)
+map_free(off_t start, off_t size)
{
map_t *m;
@@ -177,53 +203,6 @@ map_unused(off_t start, off_t size)
}
void
-map_dump(void)
-{
- off_t end;
- map_t *m;
-
- printf(" %*s", lbawidth, "start");
- printf(" %*s", lbawidth, "end");
- printf(" %*s", lbawidth, "size");
- printf(" %s\n", "contents");
-
- m = mediamap;
- while (m != NULL) {
- end = m->map_start + m->map_size - 1;
- printf(" %*llu", lbawidth, (long long)m->map_start);
- printf(" %*llu", lbawidth, (long long)end);
- printf(" %*llu", lbawidth, (long long)m->map_size);
-
- putchar(' '); putchar(' ');
- switch (m->map_type) {
- case MAP_TYPE_MBR:
- printf("MBR");
- break;
- case MAP_TYPE_PRI_GPT_HDR:
- printf("Pri GPT header");
- break;
- case MAP_TYPE_SEC_GPT_HDR:
- printf("Sec GPT header");
- break;
- case MAP_TYPE_PRI_GPT_TBL:
- printf("Pri GPT table");
- break;
- case MAP_TYPE_SEC_GPT_TBL:
- printf("Sec GPT table");
- break;
- case MAP_TYPE_MBR_PART:
- printf("MBR partition");
- break;
- case MAP_TYPE_GPT_PART:
- printf("GPT partition");
- break;
- }
- putchar('\n');
- m = m->map_next;
- }
-}
-
-void
map_init(off_t size)
{
char buf[32];
diff --git a/sbin/gpt/map.h b/sbin/gpt/map.h
index ac726e1de973..4bdc94a72e04 100644
--- a/sbin/gpt/map.h
+++ b/sbin/gpt/map.h
@@ -46,14 +46,16 @@ typedef struct map {
void *map_data;
} map_t;
+extern int lbawidth;
+
map_t *map_add(off_t, off_t, int, void*);
+map_t *map_alloc(off_t, off_t);
map_t *map_find(int);
map_t *map_first(void);
map_t *map_last(void);
-off_t map_unused(off_t, off_t);
+off_t map_free(off_t, off_t);
-void map_dump(void);
void map_init(off_t);
#endif /* _MAP_H_ */
diff --git a/sbin/gpt/migrate.c b/sbin/gpt/migrate.c
index c27bff66e967..97e1f6a281fc 100644
--- a/sbin/gpt/migrate.c
+++ b/sbin/gpt/migrate.c
@@ -135,7 +135,7 @@ migrate(int fd)
}
/* Get the amount of free space after the MBR */
- blocks = map_unused(1LL, 0LL);
+ blocks = map_free(1LL, 0LL);
if (blocks == 0LL) {
warnx("%s: error: no room for the GPT header", device_name);
return;
@@ -193,7 +193,7 @@ migrate(int fd)
hdr->hdr_lba_alt = tpg->map_start;
hdr->hdr_lba_start = tbl->map_start + blocks;
hdr->hdr_lba_end = lbt->map_start - 1LL;
- uuidgen(&hdr->hdr_uuid, 1);
+ uuid_create(&hdr->hdr_uuid, NULL);
hdr->hdr_lba_table = tbl->map_start;
hdr->hdr_entries = (blocks * secsz) / sizeof(struct gpt_ent);
if (hdr->hdr_entries > parts)
@@ -202,7 +202,7 @@ migrate(int fd)
ent = tbl->map_data;
for (i = 0; i < hdr->hdr_entries; i++)
- uuidgen(&ent[i].ent_uuid, 1);
+ uuid_create(&ent[i].ent_uuid, NULL);
/* Mirror partitions. */
for (i = 0; i < 4; i++) {
diff --git a/sbin/gpt/show.c b/sbin/gpt/show.c
index 0eff2d3b6bda..8b651b7e0d40 100644
--- a/sbin/gpt/show.c
+++ b/sbin/gpt/show.c
@@ -49,6 +49,62 @@ usage_show(void)
exit(1);
}
+static void
+show(int fd __unused)
+{
+ off_t end;
+ map_t *m;
+ struct mbr_part *part;
+ struct gpt_ent *ent;
+ char *s;
+
+ printf(" %*s", lbawidth, "start");
+ printf(" %*s", lbawidth, "end");
+ printf(" %*s", lbawidth, "size");
+ printf(" %s\n", "contents");
+
+ m = map_first();
+ while (m != NULL) {
+ end = m->map_start + m->map_size - 1;
+ printf(" %*llu", lbawidth, (long long)m->map_start);
+ printf(" %*llu", lbawidth, (long long)end);
+ printf(" %*llu", lbawidth, (long long)m->map_size);
+
+ putchar(' '); putchar(' ');
+ switch (m->map_type) {
+ case MAP_TYPE_MBR:
+ printf("MBR");
+ break;
+ case MAP_TYPE_PRI_GPT_HDR:
+ printf("Pri GPT header");
+ break;
+ case MAP_TYPE_SEC_GPT_HDR:
+ printf("Sec GPT header");
+ break;
+ case MAP_TYPE_PRI_GPT_TBL:
+ printf("Pri GPT table");
+ break;
+ case MAP_TYPE_SEC_GPT_TBL:
+ printf("Sec GPT table");
+ break;
+ case MAP_TYPE_MBR_PART:
+ printf("MBR partition: ");
+ part = m->map_data;
+ printf("type=%d", part->part_typ);
+ break;
+ case MAP_TYPE_GPT_PART:
+ printf("GPT partition: ");
+ ent = m->map_data;
+ uuid_to_string(&ent->ent_type, &s, NULL);
+ printf("type=%s", s);
+ free(s);
+ break;
+ }
+ putchar('\n');
+ m = m->map_next;
+ }
+}
+
int
cmd_show(int argc, char *argv[])
{
@@ -71,7 +127,7 @@ cmd_show(int argc, char *argv[])
continue;
}
- map_dump();
+ show(fd);
gpt_close(fd);
}