mdev: add support to run as daemon
[oweals/busybox.git] / util-linux / fdisk_gpt.c
index 98803ec88cf5898c3d30c95b05321b712b9899ab..dbe889f7c32681ef5efa7de0cf342df637661d17 100644 (file)
@@ -7,7 +7,7 @@
 
 #define GPT_MAGIC 0x5452415020494645ULL
 enum {
-       LEGACY_GPT_TYPE = 0xee,
+       LEGACY_GPT_TYPE = 0xee,
        GPT_MAX_PARTS   = 256,
        GPT_MAX_PART_ENTRY_LEN = 4096,
        GUID_LEN        = 16,
@@ -36,18 +36,15 @@ typedef struct {
        uint64_t lba_start;
        uint64_t lba_end;
        uint64_t flags;
-       uint16_t name[36];
+       uint16_t name36[36];
 } gpt_partition;
 
 static gpt_header *gpt_hdr;
 
 static char *part_array;
 static unsigned int n_parts;
-static unsigned int part_array_len;
 static unsigned int part_entry_len;
 
-static uint32_t *crc32_table;
-
 static inline gpt_partition *
 gpt_part(int i)
 {
@@ -57,16 +54,10 @@ gpt_part(int i)
        return (gpt_partition *)&part_array[i * part_entry_len];
 }
 
-/* TODO: move to libbb */
 static uint32_t
 gpt_crc32(void *buf, int len)
 {
-       uint32_t crc = 0xffffffff;
-
-       for (; len > 0; len--, buf++) {
-               crc = crc32_table[(crc ^ *((char *)buf)) & 0xff] ^ (crc >> 8);
-       }
-       return crc ^ 0xffffffff;
+       return ~crc32_block_endian0(0xffffffff, buf, len, global_crc32_table);
 }
 
 static void
@@ -81,18 +72,34 @@ gpt_print_guid(uint8_t *buf)
                buf[10], buf[11], buf[12], buf[13], buf[14], buf[15]);
 }
 
-/* TODO: real unicode support */
 static void
-gpt_print_wide(uint16_t *s, int max_len)
+gpt_print_wide36(uint16_t *s)
 {
+#if ENABLE_UNICODE_SUPPORT
+       char buf[37 * 4];
+       wchar_t wc[37];
        int i = 0;
-
-       while (i < max_len) {
-               if (*s == 0)
-                       return;
-               fputc(*s, stdout);
-               s++;
+       while (i < ARRAY_SIZE(wc)-1) {
+               if (s[i] == 0)
+                       break;
+               wc[i] = s[i];
+               i++;
        }
+       wc[i] = 0;
+       if (wcstombs(buf, wc, sizeof(buf)) <= sizeof(buf)-1)
+               fputs(printable_string(buf), stdout);
+#else
+       char buf[37];
+       int i = 0;
+       while (i < ARRAY_SIZE(buf)-1) {
+               if (s[i] == 0)
+                       break;
+               buf[i] = (0x20 <= s[i] && s[i] < 0x7f) ? s[i] : '?';
+               i++;
+       }
+       buf[i] = '\0';
+       fputs(buf, stdout);
+#endif
 }
 
 static void
@@ -101,9 +108,7 @@ gpt_list_table(int xtra UNUSED_PARAM)
        int i;
        char numstr6[6];
 
-       numstr6[5] = '\0';
-
-       smart_ulltoa5(total_number_of_sectors, numstr6, " KMGTPEZY");
+       smart_ulltoa5(total_number_of_sectors * sector_size, numstr6, " KMGTPEZY")[0] = '\0';
        printf("Disk %s: %llu sectors, %s\n", disk_device,
                (unsigned long long)total_number_of_sectors,
                numstr6);
@@ -116,20 +121,29 @@ gpt_list_table(int xtra UNUSED_PARAM)
                (unsigned long long)SWAP_LE64(gpt_hdr->first_usable_lba),
                (unsigned long long)SWAP_LE64(gpt_hdr->last_usable_lba));
 
-       printf("Number  Start (sector)    End (sector)  Size       Code  Name\n");
+/* "GPT fdisk" has a concept of 16-bit extension of the original MBR 8-bit type codes,
+ * which it displays here: its output columns are ... Size Code Name
+ * They are their own invention and are not stored on disk.
+ * Looks like they use them to support "hybrid" GPT: for example, they have
+ *   AddType(0x8307, "69DAD710-2CE4-4E3C-B16C-21A1D49ABED3", "Linux ARM32 root (/)");
+ * and then (code>>8) matches what you need to put into MBR's type field for such a partition.
+ * To print those codes, we'd need a GUID lookup table. Lets just drop the "Code" column instead:
+ */
+       puts("Number  Start (sector)    End (sector)  Size Name");
+       //    123456 123456789012345 123456789012345 12345 abc
        for (i = 0; i < n_parts; i++) {
                gpt_partition *p = gpt_part(i);
                if (p->lba_start) {
-                       smart_ulltoa5(1 + SWAP_LE64(p->lba_end) - SWAP_LE64(p->lba_start),
-                               numstr6, " KMGTPEZY");
-                       printf("%4u %15llu %15llu %11s   %04x  ",
+                       smart_ulltoa5((1 + SWAP_LE64(p->lba_end) - SWAP_LE64(p->lba_start)) * sector_size,
+                               numstr6, " KMGTPEZY")[0] = '\0';
+                       printf("%6u %15llu %15llu %s ",
                                i + 1,
                                (unsigned long long)SWAP_LE64(p->lba_start),
                                (unsigned long long)SWAP_LE64(p->lba_end),
-                               numstr6,
-                               0x0700 /* FIXME */);
-                       gpt_print_wide(p->name, 18);
-                       printf("\n");
+                               numstr6
+                       );
+                       gpt_print_wide36(p->name36);
+                       bb_putchar('\n');
                }
        }
 }
@@ -137,6 +151,7 @@ gpt_list_table(int xtra UNUSED_PARAM)
 static int
 check_gpt_label(void)
 {
+       unsigned part_array_len;
        struct partition *first = pt_offset(MBRbuffer, 0);
        struct pte pe;
        uint32_t crc;
@@ -160,8 +175,9 @@ check_gpt_label(void)
                return 0;
        }
 
-       if (!crc32_table) {
-               crc32_table = crc32_filltable(NULL, 0);
+       init_unicode();
+       if (!global_crc32_table) {
+               global_crc32_new_table_le();
        }
 
        crc = SWAP_LE32(gpt_hdr->hdr_crc32);