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;
|
return crc ^ ~0U;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
uint8_t *
|
||||||
unicode16(short *dst, const wchar_t *src, size_t len)
|
utf16_to_utf8(uint16_t *s16)
|
||||||
{
|
{
|
||||||
while (len-- && *src != 0)
|
static uint8_t *s8 = NULL;
|
||||||
*dst++ = *src++;
|
static size_t s8len = 0;
|
||||||
if (len)
|
size_t s8idx, s16idx, s16len;
|
||||||
*dst = 0;
|
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
|
void
|
||||||
|
@ -70,7 +70,9 @@ void gpt_close(int);
|
|||||||
int gpt_open(const char *);
|
int gpt_open(const char *);
|
||||||
void* gpt_read(int, off_t, size_t);
|
void* gpt_read(int, off_t, size_t);
|
||||||
int gpt_write(int, map_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_add(int, char *[]);
|
||||||
int cmd_create(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: {
|
case FS_SWAP: {
|
||||||
uuid_t swap = GPT_ENT_TYPE_FREEBSD_SWAP;
|
uuid_t swap = GPT_ENT_TYPE_FREEBSD_SWAP;
|
||||||
le_uuid_enc(&ent->ent_type, &swap);
|
le_uuid_enc(&ent->ent_type, &swap);
|
||||||
unicode16(ent->ent_name,
|
utf8_to_utf16("FreeBSD swap partition",
|
||||||
L"FreeBSD swap partition", 36);
|
ent->ent_name, 36);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case FS_BSDFFS: {
|
case FS_BSDFFS: {
|
||||||
uuid_t ufs = GPT_ENT_TYPE_FREEBSD_UFS;
|
uuid_t ufs = GPT_ENT_TYPE_FREEBSD_UFS;
|
||||||
le_uuid_enc(&ent->ent_type, &ufs);
|
le_uuid_enc(&ent->ent_type, &ufs);
|
||||||
unicode16(ent->ent_name,
|
utf8_to_utf16("FreeBSD UFS partition",
|
||||||
L"FreeBSD UFS partition", 36);
|
ent->ent_name, 36);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case FS_VINUM: {
|
case FS_VINUM: {
|
||||||
uuid_t vinum = GPT_ENT_TYPE_FREEBSD_VINUM;
|
uuid_t vinum = GPT_ENT_TYPE_FREEBSD_VINUM;
|
||||||
le_uuid_enc(&ent->ent_type, &vinum);
|
le_uuid_enc(&ent->ent_type, &vinum);
|
||||||
unicode16(ent->ent_name,
|
utf8_to_utf16("FreeBSD vinum partition",
|
||||||
L"FreeBSD vinum partition", 36);
|
ent->ent_name, 36);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@ -255,8 +255,8 @@ migrate(int fd)
|
|||||||
le_uuid_enc(&ent->ent_type, &freebsd);
|
le_uuid_enc(&ent->ent_type, &freebsd);
|
||||||
ent->ent_lba_start = htole64((uint64_t)start);
|
ent->ent_lba_start = htole64((uint64_t)start);
|
||||||
ent->ent_lba_end = htole64(start + size - 1LL);
|
ent->ent_lba_end = htole64(start + size - 1LL);
|
||||||
unicode16(ent->ent_name,
|
utf8_to_utf16("FreeBSD disklabel partition",
|
||||||
L"FreeBSD disklabel partition", 36);
|
ent->ent_name, 36);
|
||||||
ent++;
|
ent++;
|
||||||
} else
|
} else
|
||||||
ent = migrate_disklabel(fd, start, ent);
|
ent = migrate_disklabel(fd, start, ent);
|
||||||
@ -267,7 +267,8 @@ migrate(int fd)
|
|||||||
le_uuid_enc(&ent->ent_type, &efi_slice);
|
le_uuid_enc(&ent->ent_type, &efi_slice);
|
||||||
ent->ent_lba_start = htole64((uint64_t)start);
|
ent->ent_lba_start = htole64((uint64_t)start);
|
||||||
ent->ent_lba_end = htole64(start + size - 1LL);
|
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++;
|
ent++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -39,12 +39,15 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include "map.h"
|
#include "map.h"
|
||||||
#include "gpt.h"
|
#include "gpt.h"
|
||||||
|
|
||||||
|
static int show_label = 0;
|
||||||
|
static int show_uuid = 0;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
usage_show(void)
|
usage_show(void)
|
||||||
{
|
{
|
||||||
|
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"usage: %s device ...\n", getprogname());
|
"usage: %s [-lu] device ...\n", getprogname());
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,6 +65,9 @@ friendly(uuid_t *t)
|
|||||||
static char buf[80];
|
static char buf[80];
|
||||||
char *s;
|
char *s;
|
||||||
|
|
||||||
|
if (show_uuid)
|
||||||
|
goto unfriendly;
|
||||||
|
|
||||||
if (uuid_equal(t, &efi_slice, NULL))
|
if (uuid_equal(t, &efi_slice, NULL))
|
||||||
return ("EFI System");
|
return ("EFI System");
|
||||||
if (uuid_equal(t, &swap, NULL))
|
if (uuid_equal(t, &swap, NULL))
|
||||||
@ -80,6 +86,7 @@ friendly(uuid_t *t)
|
|||||||
if (uuid_equal(t, &msr, NULL))
|
if (uuid_equal(t, &msr, NULL))
|
||||||
return ("Windows reserved");
|
return ("Windows reserved");
|
||||||
|
|
||||||
|
unfriendly:
|
||||||
uuid_to_string(t, &s, NULL);
|
uuid_to_string(t, &s, NULL);
|
||||||
strlcpy(buf, s, sizeof buf);
|
strlcpy(buf, s, sizeof buf);
|
||||||
free(s);
|
free(s);
|
||||||
@ -148,8 +155,13 @@ show(int fd __unused)
|
|||||||
case MAP_TYPE_GPT_PART:
|
case MAP_TYPE_GPT_PART:
|
||||||
printf("GPT part ");
|
printf("GPT part ");
|
||||||
ent = m->map_data;
|
ent = m->map_data;
|
||||||
le_uuid_dec(&ent->ent_type, &type);
|
if (show_label) {
|
||||||
printf("- %s", friendly(&type));
|
printf("- \"%s\"",
|
||||||
|
utf16_to_utf8(ent->ent_name));
|
||||||
|
} else {
|
||||||
|
le_uuid_dec(&ent->ent_type, &type);
|
||||||
|
printf("- %s", friendly(&type));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case MAP_TYPE_PMBR:
|
case MAP_TYPE_PMBR:
|
||||||
printf("PMBR");
|
printf("PMBR");
|
||||||
@ -165,8 +177,14 @@ cmd_show(int argc, char *argv[])
|
|||||||
{
|
{
|
||||||
int ch, fd;
|
int ch, fd;
|
||||||
|
|
||||||
while ((ch = getopt(argc, argv, "")) != -1) {
|
while ((ch = getopt(argc, argv, "lu")) != -1) {
|
||||||
switch(ch) {
|
switch(ch) {
|
||||||
|
case 'l':
|
||||||
|
show_label = 1;
|
||||||
|
break;
|
||||||
|
case 'u':
|
||||||
|
show_uuid = 1;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
usage_show();
|
usage_show();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user