From fe61c1161841d240deadfd28156f5637b9709fa6 Mon Sep 17 00:00:00 2001 From: marcel Date: Tue, 6 Sep 2005 23:59:01 +0000 Subject: [PATCH] Sync with HEAD: Makefile: 1.7 add.c: 1.12, 1.23 create.c: 1.11 destroy.c: 1.6 gpt.8: 1.14, 1.15 gpt.c: 1.11, 1.12, 1.13 gpt.h: 1.8, 1.9, 1.10 label.c: 1.1 map.c: 1.6 map.h: 1.6 migrate.c: 1.14, 1.15, 1.16 recover.c: 1.8 remove.c: 1.5, 1.6, 1.7, 1.8 show.c: 1.12, 1.13 o New -l and -u options to the show command, o New label command to support GPT labels, o The remove command doesn't print the total partitions removed, as it prints each partition it removes by name already, o Added ellipsis to most usage messages. PR: ia64/83124 Approved by: re (scottl) --- sbin/gpt/Makefile | 4 +- sbin/gpt/add.c | 4 +- sbin/gpt/create.c | 2 +- sbin/gpt/destroy.c | 2 +- sbin/gpt/gpt.8 | 121 +++++++++++++++++++++++++++++++++------------ sbin/gpt/gpt.c | 116 ++++++++++++++++++++++++++++++++++++++++--- sbin/gpt/gpt.h | 7 ++- sbin/gpt/map.c | 2 +- sbin/gpt/map.h | 2 +- sbin/gpt/migrate.c | 23 ++++----- sbin/gpt/mkdisk.sh | 11 ----- sbin/gpt/recover.c | 2 +- sbin/gpt/remove.c | 18 +++---- sbin/gpt/show.c | 28 +++++++++-- 14 files changed, 255 insertions(+), 87 deletions(-) delete mode 100644 sbin/gpt/mkdisk.sh diff --git a/sbin/gpt/Makefile b/sbin/gpt/Makefile index 8e85b91eb1fa..cfae78d03cf2 100644 --- a/sbin/gpt/Makefile +++ b/sbin/gpt/Makefile @@ -1,8 +1,8 @@ # $FreeBSD$ PROG= gpt -SRCS= add.c create.c destroy.c gpt.c map.c migrate.c recover.c remove.c \ - show.c +SRCS= add.c create.c destroy.c gpt.c label.c map.c migrate.c recover.c \ + remove.c show.c WARNS?= 4 MAN= gpt.8 diff --git a/sbin/gpt/add.c b/sbin/gpt/add.c index 0bba7f9d860b..3b60720092b4 100644 --- a/sbin/gpt/add.c +++ b/sbin/gpt/add.c @@ -1,4 +1,4 @@ -/* +/*- * Copyright (c) 2002 Marcel Moolenaar * All rights reserved. * @@ -48,7 +48,7 @@ usage_add(void) { fprintf(stderr, - "usage: %s [-b lba] [-i index] [-s lba] [-t uuid] device\n", + "usage: %s [-b lba] [-i index] [-s lba] [-t uuid] device ...\n", getprogname()); exit(1); } diff --git a/sbin/gpt/create.c b/sbin/gpt/create.c index 54084c2a05b4..24a6a6d014fb 100644 --- a/sbin/gpt/create.c +++ b/sbin/gpt/create.c @@ -1,4 +1,4 @@ -/* +/*- * Copyright (c) 2002 Marcel Moolenaar * All rights reserved. * diff --git a/sbin/gpt/destroy.c b/sbin/gpt/destroy.c index 97cb21735336..7c2c198608bc 100644 --- a/sbin/gpt/destroy.c +++ b/sbin/gpt/destroy.c @@ -1,4 +1,4 @@ -/* +/*- * Copyright (c) 2002 Marcel Moolenaar * All rights reserved. * diff --git a/sbin/gpt/gpt.8 b/sbin/gpt/gpt.8 index c4eeb15a72f1..419ec9a00f78 100644 --- a/sbin/gpt/gpt.8 +++ b/sbin/gpt/gpt.8 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd November 12, 2004 +.Dd August 31, 2005 .Os .Dt GPT 8 .Sh NAME @@ -165,6 +165,71 @@ The option instructs .Nm to destroy the table in a way that it can be recovered. +.\" ==== label ==== +.It Xo +.Nm +.Ic label +.Op Fl a +.Aq Fl f Ar file | Fl l Ar label +.Ar device ... +.Xc +.It Xo +.Nm +.Ic label +.Op Fl b Ar number +.Op Fl i Ar index +.Op Fl s Ar count +.Op Fl t Ar type +.Aq Fl f Ar file | Fl l Ar label +.Ar device ... +.Xc +The +.Ic label +command allows the user to label any partitions that match the selection. +At least one of the following selection options must be specified. +.Pp +The +.Fl a +option specifies that all partitions should be labeled. +It is mutually exclusive with all other selection options. +.Pp +The +.Fl b Ar number +option selects the partition that starts at the given block number. +.Pp +The +.Fl i Ar index +option selects the partition with the given partition number. +.Pp +The +.Fl s Ar count +option selects all partitions that have the given size. +This can cause multiple partitions to be removed. +.Pp +The +.Fl t Ar type +option selects all partitions that have the given type. +The type is given as an UUID or by the aliases that the +.Ic add +command accepts. +This can cause multiple partitions to be removed. +.Pp +The +.Fl f Ar file +or +.Fl l Ar label +options specify the new label to be assigned to the selected partitions. +The +.Fl f Ar file +option is used to read the label from the specified file. +Only the first line is read from the file and the trailing newline +character is stripped. +If the file name is the dash or minus sign (-), the label is read from +the standard input. +The +.Fl l Ar label +option is used to specify the label in the command line. +The label is assumed to be encoded in UTF-8. .\" ==== migrate ==== .It Nm Ic migrate Oo Fl fs Oc Ar device ... The @@ -188,7 +253,7 @@ option prevents migrating disk labels into GPT partitions by creating the GPT equivalent of a slice. .\" ==== remove ==== -.It Nm Ic remove Oo Fl a Oc +.It Nm Ic remove Oo Fl a Oc Ar device ... .It Xo .Nm .Ic remove @@ -200,40 +265,34 @@ the GPT equivalent of a slice. .Xc The .Ic remove -command allows the user to remove any partitions that match the selection. -At least one option must be specified. -.Pp -The -.Fl a -option specifies that all partitions should be removed. -It is mutually exclusive with all other options. -.Pp -The -.Fl b Ar number -option selects the partitions that starts at the given number. -.Pp -The -.Fl i Ar index -option selects the partition with the given partition number. -.Pp -The -.Fl s Ar count -option selects all partitions that have the given size. -This can cause multiple partitions to be removed. -.Pp -The -.Fl t Ar type -option selects all partitions that have the given type. -The type is given as an UUID or by the aliases that the -.Ic add -command accepts. -This can cause multiple partitions to be removed. +command allows the user to remove any and all partitions that match the +selection. +It uses the same selection options as the +.Ic label +command. +See above for a description of these options. +Partitions are removed by clearing the partition type. +No other information is changed. .\" ==== show ==== -.It Nm Ic show Ar device ... +.It Nm Ic show Oo Fl lu Oc Ar device ... The .Ic show command displays the current partitioning on the listed devices and gives an overall view of the disk contents. +With the +.Fl l +option the GPT partition label will be displayed instead of the GPT partition +type. +The option has no effect on non-GPT partitions. +With the +.Fl u +option the GPT partition type is displayed as an UUID instead of in an +user friendly form. +The +.Fl l +option takes precedence over the +.Fl u +option. .El .Sh SEE ALSO .Xr fdisk 8 , diff --git a/sbin/gpt/gpt.c b/sbin/gpt/gpt.c index 23a36be687cc..79b2893761fa 100644 --- a/sbin/gpt/gpt.c +++ b/sbin/gpt/gpt.c @@ -1,4 +1,4 @@ -/* +/*- * Copyright (c) 2002 Marcel Moolenaar * All rights reserved. * @@ -118,13 +118,112 @@ crc32(const void *buf, size_t size) return crc ^ ~0U; } -void -unicode16(short *dst, const wchar_t *src, size_t len) +uint8_t * +utf16_to_utf8(uint16_t *s16) { - while (len-- && *src != 0) - *dst++ = *src++; - if (len) - *dst = 0; + static uint8_t *s8 = NULL; + static size_t s8len = 0; + size_t s8idx, s16idx, s16len; + uint32_t utfchar; + unsigned int c; + + s16len = 0; + while (s16[s16len++] != 0) + ; + if (s8len < s16len * 3) { + if (s8 != NULL) + free(s8); + s8len = s16len * 3; + s8 = calloc(s16len, 3); + } + s8idx = s16idx = 0; + while (s16idx < s16len) { + utfchar = le16toh(s16[s16idx++]); + if ((utfchar & 0xf800) == 0xd800) { + c = le16toh(s16[s16idx]); + if ((utfchar & 0x400) != 0 || (c & 0xfc00) != 0xdc00) + utfchar = 0xfffd; + else + s16idx++; + } + if (utfchar < 0x80) { + s8[s8idx++] = utfchar; + } else if (utfchar < 0x800) { + s8[s8idx++] = 0xc0 | (utfchar >> 6); + s8[s8idx++] = 0x80 | (utfchar & 0x3f); + } else if (utfchar < 0x10000) { + s8[s8idx++] = 0xe0 | (utfchar >> 12); + s8[s8idx++] = 0x80 | ((utfchar >> 6) & 0x3f); + s8[s8idx++] = 0x80 | (utfchar & 0x3f); + } else if (utfchar < 0x200000) { + s8[s8idx++] = 0xf0 | (utfchar >> 18); + s8[s8idx++] = 0x80 | ((utfchar >> 12) & 0x3f); + s8[s8idx++] = 0x80 | ((utfchar >> 6) & 0x3f); + s8[s8idx++] = 0x80 | (utfchar & 0x3f); + } + } + return (s8); +} + +void +utf8_to_utf16(const uint8_t *s8, uint16_t *s16, size_t s16len) +{ + size_t s16idx, s8idx, s8len; + uint32_t utfchar; + unsigned int c, utfbytes; + + s8len = 0; + while (s8[s8len++] != 0) + ; + s8idx = s16idx = 0; + utfbytes = 0; + do { + c = s8[s8idx++]; + if ((c & 0xc0) != 0x80) { + /* Initial characters. */ + if (utfbytes != 0) { + /* Incomplete encoding. */ + s16[s16idx++] = 0xfffd; + if (s16idx == s16len) { + s16[--s16idx] = 0; + return; + } + } + if ((c & 0xf8) == 0xf0) { + utfchar = c & 0x07; + utfbytes = 3; + } else if ((c & 0xf0) == 0xe0) { + utfchar = c & 0x0f; + utfbytes = 2; + } else if ((c & 0xe0) == 0xc0) { + utfchar = c & 0x1f; + utfbytes = 1; + } else { + utfchar = c & 0x7f; + utfbytes = 0; + } + } else { + /* Followup characters. */ + if (utfbytes > 0) { + utfchar = (utfchar << 6) + (c & 0x3f); + utfbytes--; + } else if (utfbytes == 0) + utfbytes = -1; + } + if (utfbytes == 0) { + if (utfchar >= 0x10000 && s16idx + 2 >= s16len) + utfchar = 0xfffd; + if (utfchar >= 0x10000) { + s16[s16idx++] = 0xd800 | ((utfchar>>10)-0x40); + s16[s16idx++] = 0xdc00 | (utfchar & 0x3ff); + } else + s16[s16idx++] = utfchar; + if (s16idx == s16len) { + s16[--s16idx] = 0; + return; + } + } + } while (c != 0); } void @@ -457,6 +556,7 @@ static struct { { cmd_create, "create" }, { cmd_destroy, "destroy" }, { NULL, "help" }, + { cmd_label, "label" }, { cmd_migrate, "migrate" }, { cmd_recover, "recover" }, { cmd_remove, "remove" }, @@ -471,7 +571,7 @@ usage(void) { fprintf(stderr, - "usage: %s [-rv] [-p nparts] command [options] device\n", + "usage: %s [-rv] [-p nparts] command [options] device ...\n", getprogname()); exit(1); } diff --git a/sbin/gpt/gpt.h b/sbin/gpt/gpt.h index b6a4c8081f5a..fc9e2d5843e7 100644 --- a/sbin/gpt/gpt.h +++ b/sbin/gpt/gpt.h @@ -1,4 +1,4 @@ -/* +/*- * Copyright (c) 2002 Marcel Moolenaar * All rights reserved. * @@ -70,11 +70,14 @@ void gpt_close(int); int gpt_open(const char *); void* gpt_read(int, off_t, size_t); int gpt_write(int, map_t *); -void unicode16(short *, const wchar_t *, size_t); + +uint8_t *utf16_to_utf8(uint16_t *); +void utf8_to_utf16(const uint8_t *, uint16_t *, size_t); int cmd_add(int, char *[]); int cmd_create(int, char *[]); int cmd_destroy(int, char *[]); +int cmd_label(int, char *[]); int cmd_migrate(int, char *[]); int cmd_recover(int, char *[]); int cmd_remove(int, char *[]); diff --git a/sbin/gpt/map.c b/sbin/gpt/map.c index f8c433bdd6b0..91b56850b9c4 100644 --- a/sbin/gpt/map.c +++ b/sbin/gpt/map.c @@ -1,4 +1,4 @@ -/* +/*- * Copyright (c) 2002 Marcel Moolenaar * All rights reserved. * diff --git a/sbin/gpt/map.h b/sbin/gpt/map.h index f83824cf951d..4c3f0992d59a 100644 --- a/sbin/gpt/map.h +++ b/sbin/gpt/map.h @@ -1,4 +1,4 @@ -/* +/*- * Copyright (c) 2002 Marcel Moolenaar * All rights reserved. * diff --git a/sbin/gpt/migrate.c b/sbin/gpt/migrate.c index eb89941755ff..8f3b4ecff32c 100644 --- a/sbin/gpt/migrate.c +++ b/sbin/gpt/migrate.c @@ -1,4 +1,4 @@ -/* +/*- * Copyright (c) 2002 Marcel Moolenaar * All rights reserved. * @@ -59,7 +59,7 @@ usage_migrate(void) { fprintf(stderr, - "usage: %s [-fs] device\n", getprogname()); + "usage: %s [-fs] device ...\n", getprogname()); exit(1); } @@ -100,22 +100,22 @@ migrate_disklabel(int fd, off_t start, struct gpt_ent *ent) case FS_SWAP: { uuid_t swap = GPT_ENT_TYPE_FREEBSD_SWAP; le_uuid_enc(&ent->ent_type, &swap); - unicode16(ent->ent_name, - L"FreeBSD swap partition", 36); + utf8_to_utf16("FreeBSD swap partition", + ent->ent_name, 36); break; } case FS_BSDFFS: { uuid_t ufs = GPT_ENT_TYPE_FREEBSD_UFS; le_uuid_enc(&ent->ent_type, &ufs); - unicode16(ent->ent_name, - L"FreeBSD UFS partition", 36); + utf8_to_utf16("FreeBSD UFS partition", + ent->ent_name, 36); break; } case FS_VINUM: { uuid_t vinum = GPT_ENT_TYPE_FREEBSD_VINUM; le_uuid_enc(&ent->ent_type, &vinum); - unicode16(ent->ent_name, - L"FreeBSD vinum partition", 36); + utf8_to_utf16("FreeBSD vinum partition", + ent->ent_name, 36); break; } default: @@ -255,8 +255,8 @@ migrate(int fd) le_uuid_enc(&ent->ent_type, &freebsd); ent->ent_lba_start = htole64((uint64_t)start); ent->ent_lba_end = htole64(start + size - 1LL); - unicode16(ent->ent_name, - L"FreeBSD disklabel partition", 36); + utf8_to_utf16("FreeBSD disklabel partition", + ent->ent_name, 36); ent++; } else ent = migrate_disklabel(fd, start, ent); @@ -267,7 +267,8 @@ migrate(int fd) le_uuid_enc(&ent->ent_type, &efi_slice); ent->ent_lba_start = htole64((uint64_t)start); ent->ent_lba_end = htole64(start + size - 1LL); - unicode16(ent->ent_name, L"EFI system partition", 36); + utf8_to_utf16("EFI system partition", + ent->ent_name, 36); ent++; break; } diff --git a/sbin/gpt/mkdisk.sh b/sbin/gpt/mkdisk.sh deleted file mode 100644 index 6ead1d94af20..000000000000 --- a/sbin/gpt/mkdisk.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/sh -# $FreeBSD$ - -dd if=/dev/zero of=disk count=125307 -sudo mdconfig -a -t vnode -f disk -u 4 -sudo fdisk -f - md4 <map_next) { if (m->map_type != MAP_TYPE_GPT_PART || m->map_index < 1) @@ -109,6 +107,8 @@ rem(int fd) if (!uuid_is_nil(&type, NULL) && !uuid_equal(&type, &uuid, NULL)) continue; + + /* Remove the primary entry by clearing the partition type. */ uuid_create_nil(&ent->ent_type, NULL); hdr->hdr_crc_table = htole32(crc32(tbl->map_data, @@ -122,6 +122,8 @@ rem(int fd) hdr = tpg->map_data; ent = (void*)((char*)lbt->map_data + i * le32toh(hdr->hdr_entsz)); + + /* Remove the secundary entry. */ uuid_create_nil(&ent->ent_type, NULL); hdr->hdr_crc_table = htole32(crc32(lbt->map_data, @@ -133,11 +135,7 @@ rem(int fd) gpt_write(fd, tpg); printf("%sp%u removed\n", device_name, m->map_index); - - removed++; } - - warnx("%s: %d partition(s) removed", device_name, removed); } int diff --git a/sbin/gpt/show.c b/sbin/gpt/show.c index 181027460a88..4df3be1c5e03 100644 --- a/sbin/gpt/show.c +++ b/sbin/gpt/show.c @@ -1,4 +1,4 @@ -/* +/*- * Copyright (c) 2002 Marcel Moolenaar * All rights reserved. * @@ -39,12 +39,15 @@ __FBSDID("$FreeBSD$"); #include "map.h" #include "gpt.h" +static int show_label = 0; +static int show_uuid = 0; + static void usage_show(void) { fprintf(stderr, - "usage: %s device ...\n", getprogname()); + "usage: %s [-lu] device ...\n", getprogname()); exit(1); } @@ -62,6 +65,9 @@ friendly(uuid_t *t) static char buf[80]; char *s; + if (show_uuid) + goto unfriendly; + if (uuid_equal(t, &efi_slice, NULL)) return ("EFI System"); if (uuid_equal(t, &swap, NULL)) @@ -80,6 +86,7 @@ friendly(uuid_t *t) if (uuid_equal(t, &msr, NULL)) return ("Windows reserved"); +unfriendly: uuid_to_string(t, &s, NULL); strlcpy(buf, s, sizeof buf); free(s); @@ -148,8 +155,13 @@ show(int fd __unused) case MAP_TYPE_GPT_PART: printf("GPT part "); ent = m->map_data; - le_uuid_dec(&ent->ent_type, &type); - printf("- %s", friendly(&type)); + if (show_label) { + printf("- \"%s\"", + utf16_to_utf8(ent->ent_name)); + } else { + le_uuid_dec(&ent->ent_type, &type); + printf("- %s", friendly(&type)); + } break; case MAP_TYPE_PMBR: printf("PMBR"); @@ -165,8 +177,14 @@ cmd_show(int argc, char *argv[]) { int ch, fd; - while ((ch = getopt(argc, argv, "")) != -1) { + while ((ch = getopt(argc, argv, "lu")) != -1) { switch(ch) { + case 'l': + show_label = 1; + break; + case 'u': + show_uuid = 1; + break; default: usage_show(); }