summaryrefslogtreecommitdiffstats
path: root/sbin
diff options
context:
space:
mode:
authormarcel <marcel@FreeBSD.org>2005-08-31 05:40:41 +0000
committermarcel <marcel@FreeBSD.org>2005-08-31 05:40:41 +0000
commit982ab454f00893994acf43df8fc83d4afbe08883 (patch)
tree485d373820a5bf5c83b186654ad37c05e9d40130 /sbin
parent5fa2cd3d841be4d686d029a18660f1b7b55c69a0 (diff)
downloadFreeBSD-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.c109
-rw-r--r--sbin/gpt/gpt.h4
-rw-r--r--sbin/gpt/migrate.c19
-rw-r--r--sbin/gpt/show.c26
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();
}
OpenPOWER on IntegriCloud