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:
Marcel Moolenaar 2005-08-31 05:40:41 +00:00
parent 27e701229c
commit 06185c565b
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=149656
4 changed files with 140 additions and 20 deletions

View file

@ -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

View file

@ -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 *[]);

View file

@ -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;
} }

View file

@ -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();
} }