fdisk: sanitize partition name printing; drop "Code" column; get rid of one static var
authorDenys Vlasenko <vda.linux@googlemail.com>
Sun, 27 Nov 2016 05:13:43 +0000 (06:13 +0100)
committerDenys Vlasenko <vda.linux@googlemail.com>
Sun, 27 Nov 2016 05:13:43 +0000 (06:13 +0100)
function                                             old     new   delta
list_table                                          2335    2373     +38
fill_bounds                                          131     128      -3
part_array_len                                         4       -      -4
get_boot                                            1584    1574     -10
------------------------------------------------------------------------------
(add/remove: 0/1 grow/shrink: 1/2 up/down: 38/-17)             Total: 21 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
util-linux/fdisk.c
util-linux/fdisk_gpt.c

index af80735321db3f88db3b8dc32a489b0a938a230e..b988e65a981cb2c057fbd2cae28f0b16d0a4c1eb 100644 (file)
 # define BLKGETSIZE64 _IOR(0x12,114,size_t)
 #endif
 #include "libbb.h"
+#include "unicode.h"
 
 #if BB_LITTLE_ENDIAN
 # define inline_if_little_endian ALWAYS_INLINE
index 715e227ca2ad350dd5db16fabd48ceb2638c9f45..9b17b4a57440073c5caa02cf5656a57f3d8ab98e 100644 (file)
@@ -36,14 +36,13 @@ 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 inline gpt_partition *
@@ -73,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(NULL, buf), stdout);
+#else
+       char buf[37];
+       int i = 0;
+       while (i < ARRAY_SIZE(buf)-1) {
+               if (s[i] == 0)
+                       break;
+               buf[i] = (s[i] < 0x7f) ? s[i] : '?';
+               i++;
        }
+       buf[i] = '\0';
+       fputs(printable_string(NULL, buf), stdout);
+#endif
 }
 
 static void
@@ -106,19 +121,28 @@ 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));
 
-       puts("Number  Start (sector)    End (sector)  Size       Code  Name");
+/* "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)) * sector_size,
                                numstr6, " KMGTPEZY")[0] = '\0';
-                       printf("%4u %15llu %15llu %11s   %04x  ",
+                       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);
+                               numstr6
+                       );
+                       gpt_print_wide36(p->name36);
                        bb_putchar('\n');
                }
        }
@@ -127,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;
@@ -150,6 +175,7 @@ check_gpt_label(void)
                return 0;
        }
 
+       init_unicode();
        if (!global_crc32_table) {
                global_crc32_table = crc32_filltable(NULL, 0);
        }