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.
This commit is contained in:
parent
27e701229c
commit
06185c565b
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=149656
111
sbin/gpt/gpt.c
111
sbin/gpt/gpt.c
@ -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
|
||||
|
@ -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 *[]);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user