diff options
author | marcel <marcel@FreeBSD.org> | 2005-08-31 05:40:41 +0000 |
---|---|---|
committer | marcel <marcel@FreeBSD.org> | 2005-08-31 05:40:41 +0000 |
commit | 982ab454f00893994acf43df8fc83d4afbe08883 (patch) | |
tree | 485d373820a5bf5c83b186654ad37c05e9d40130 /sbin | |
parent | 5fa2cd3d841be4d686d029a18660f1b7b55c69a0 (diff) | |
download | FreeBSD-src-982ab454f00893994acf43df8fc83d4afbe08883.zip FreeBSD-src-982ab454f00893994acf43df8fc83d4afbe08883.tar.gz |
o Replace unicode16() by utf8_to_utf16().
o Introduce utf16_to_utf8().
o Add option -l to the show command to display the GPT label instead
of the friendly partition type.
o Add option -u to the show command to suppress the friendly output
and print th raw UUIDs instead.
Diffstat (limited to 'sbin')
-rw-r--r-- | sbin/gpt/gpt.c | 109 | ||||
-rw-r--r-- | sbin/gpt/gpt.h | 4 | ||||
-rw-r--r-- | sbin/gpt/migrate.c | 19 | ||||
-rw-r--r-- | sbin/gpt/show.c | 26 |
4 files changed, 139 insertions, 19 deletions
diff --git a/sbin/gpt/gpt.c b/sbin/gpt/gpt.c index 3a114c1..29a1983 100644 --- a/sbin/gpt/gpt.c +++ b/sbin/gpt/gpt.c @@ -118,13 +118,112 @@ crc32(const void *buf, size_t size) return crc ^ ~0U; } +uint8_t * +utf16_to_utf8(uint16_t *s16) +{ + 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 -unicode16(short *dst, const wchar_t *src, size_t len) +utf8_to_utf16(const uint8_t *s8, uint16_t *s16, size_t s16len) { - while (len-- && *src != 0) - *dst++ = *src++; - if (len) - *dst = 0; + 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 diff --git a/sbin/gpt/gpt.h b/sbin/gpt/gpt.h index baa651f..596a68c 100644 --- a/sbin/gpt/gpt.h +++ b/sbin/gpt/gpt.h @@ -70,7 +70,9 @@ 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 *[]); diff --git a/sbin/gpt/migrate.c b/sbin/gpt/migrate.c index 5322792..fb36d7a 100644 --- a/sbin/gpt/migrate.c +++ b/sbin/gpt/migrate.c @@ -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/show.c b/sbin/gpt/show.c index f2c94e1..4df3be1 100644 --- a/sbin/gpt/show.c +++ b/sbin/gpt/show.c @@ -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(); } |