fdisk: eliminate static variables, fix GPT disk size (32x32->32 overflow)
No binary (build failed)
gcc -Wp,-MD,applets/.usage.d -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -Iinclude -Iinclude -o applets/usage applets/usage.c
(log yok)
| @@ -170,8 +170,10 @@ typedef unsigned long long ullong; | |
| typedef uint32_t sector_t; | |
| #if UINT_MAX == 0xffffffff | |
| # define SECT_FMT "" | |
| + | # define SECT_TYPE unsigned |
| #elif ULONG_MAX == 0xffffffff | |
| # define SECT_FMT "l" | |
| + | # define SECT_TYPE unsigned long |
| #else | |
| # error Cant detect sizeof(uint32_t) | |
| #endif | |
| @@ -412,6 +414,10 @@ enum { | |
| dev_fd = 3 /* the disk */ | |
| }; | |
| + | #if ENABLE_FEATURE_GPT_LABEL |
| + | struct gpt_header; |
| + | #endif |
| + | |
| /* Globals */ | |
| struct globals { | |
| char *line_ptr; | |
| @@ -434,6 +440,18 @@ struct globals { | |
| #if ENABLE_FEATURE_FDISK_WRITABLE | |
| //int dos_changed; | |
| smallint nowarn; /* no warnings for fdisk -l/-s */ | |
| + | #endif |
| + | #if ENABLE_FEATURE_SUN_LABEL |
| + | smallint sun_other_endian; |
| + | smallint sun_scsi_disk; |
| + | smallint sun_floppy; |
| + | unsigned *verify_sun_starts; |
| + | #endif |
| + | #if ENABLE_FEATURE_OSF_LABEL |
| + | # if !defined(__alpha__) |
| + | struct partition *xbsd_part; |
| + | unsigned xbsd_part_index; |
| + | # endif |
| #endif | |
| int ext_index; /* the prime extended partition */ | |
| unsigned user_cylinders, user_heads, user_sectors; | |
| @@ -442,6 +460,13 @@ struct globals { | |
| sector_t extended_offset; /* offset of link pointers */ | |
| sector_t total_number_of_sectors; | |
| + | #if ENABLE_FEATURE_GPT_LABEL |
| + | struct gpt_header *gpt_hdr; |
| + | char *gpt_part_array; |
| + | unsigned gpt_n_parts; |
| + | unsigned gpt_part_entry_len; |
| + | #endif |
| + | |
| jmp_buf listingbuf; | |
| char line_buffer[80]; | |
| /* Raw disk label. For DOS-type partition tables the MBR, | |
| @@ -1391,7 +1416,7 @@ get_geometry(void) | |
| get_sectorsize(); | |
| sec_fac = sector_size / 512; | |
| #if ENABLE_FEATURE_SUN_LABEL | |
| - | guess_device_type(); |
| + | sun_guess_device_type(); |
| #endif | |
| g_heads = g_cylinders = g_sectors = 0; | |
| kern_heads = kern_sectors = 0; | |
| @@ -13,7 +13,7 @@ enum { | |
| GUID_LEN = 16, | |
| }; | |
| - | typedef struct { |
| + | typedef struct gpt_header { |
| uint64_t magic; | |
| uint32_t revision; | |
| uint32_t hdr_size; | |
| @@ -30,7 +30,7 @@ typedef struct { | |
| uint32_t part_array_crc32; | |
| } gpt_header; | |
| - | typedef struct { |
| + | typedef struct gpt_partition { |
| uint8_t type_guid[GUID_LEN]; | |
| uint8_t part_guid[GUID_LEN]; | |
| uint64_t lba_start; | |
| @@ -39,19 +39,13 @@ typedef struct { | |
| uint16_t name36[36]; | |
| } gpt_partition; | |
| - | static gpt_header *gpt_hdr; |
| - | |
| - | static char *part_array; |
| - | static unsigned int n_parts; |
| - | static unsigned int part_entry_len; |
| - | |
| - | static inline gpt_partition * |
| + | static gpt_partition * |
| gpt_part(int i) | |
| { | |
| - | if (i >= n_parts) { |
| + | if (i >= G.gpt_n_parts) { |
| return NULL; | |
| } | |
| - | return (gpt_partition *)&part_array[i * part_entry_len]; |
| + | return (gpt_partition *)&G.gpt_part_array[i * G.gpt_part_entry_len]; |
| } | |
| static uint32_t | |
| @@ -107,19 +101,27 @@ gpt_list_table(int xtra UNUSED_PARAM) | |
| { | |
| int i; | |
| char numstr6[6]; | |
| + | unsigned long long total_bytes; |
| + | |
| + | total_bytes = (unsigned long long)total_number_of_sectors * sector_size; |
| + | smart_ulltoa5(total_bytes, numstr6, " KMGTPEZY")[0] = '\0'; |
| - | 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); |
| + | printf("Disk %s: %s, %llu bytes, %"SECT_FMT"u sectors\n", disk_device, |
| + | skip_whitespace(numstr6), |
| + | total_bytes, |
| + | (SECT_TYPE)total_number_of_sectors |
| + | ); |
| printf("Logical sector size: %u\n", sector_size); | |
| printf("Disk identifier (GUID): "); | |
| - | gpt_print_guid(gpt_hdr->disk_guid); |
| + | //util-linux 2.41.1 does not print " (GUID)" in above line, |
| + | //we do: keep users less confused what kind of identifier is meant. |
| + | gpt_print_guid(G.gpt_hdr->disk_guid); |
| printf("\nPartition table holds up to %u entries\n", | |
| - | (int)SWAP_LE32(gpt_hdr->n_parts)); |
| + | (int)SWAP_LE32(G.gpt_hdr->n_parts)); |
| printf("First usable sector is %llu, last usable sector is %llu\n\n", | |
| - | (unsigned long long)SWAP_LE64(gpt_hdr->first_usable_lba), |
| - | (unsigned long long)SWAP_LE64(gpt_hdr->last_usable_lba)); |
| + | (unsigned long long)SWAP_LE64(G.gpt_hdr->first_usable_lba), |
| + | (unsigned long long)SWAP_LE64(G.gpt_hdr->last_usable_lba) |
| + | ); |
| /* "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 | |
| @@ -131,7 +133,7 @@ gpt_list_table(int xtra UNUSED_PARAM) | |
| */ | |
| puts("Number Start (sector) End (sector) Size Name"); | |
| // 123456 123456789012345 123456789012345 12345 abc | |
| - | for (i = 0; i < n_parts; i++) { |
| + | for (i = 0; i < G.gpt_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, | |
| @@ -168,9 +170,9 @@ check_gpt_label(void) | |
| /* LBA 1 contains the GPT header */ | |
| read_pte(&pe, 1); | |
| - | gpt_hdr = (void *)pe.sectorbuffer; |
| + | G.gpt_hdr = (void *)pe.sectorbuffer; |
| - | if (gpt_hdr->magic != SWAP_LE64(GPT_MAGIC)) { |
| + | if (G.gpt_hdr->magic != SWAP_LE64(GPT_MAGIC)) { |
| current_label_type = LABEL_DOS; | |
| return 0; | |
| } | |
| @@ -180,32 +182,32 @@ check_gpt_label(void) | |
| global_crc32_new_table_le(); | |
| } | |
| - | crc = SWAP_LE32(gpt_hdr->hdr_crc32); |
| - | gpt_hdr->hdr_crc32 = 0; |
| - | if (gpt_crc32(gpt_hdr, SWAP_LE32(gpt_hdr->hdr_size)) != crc) { |
| + | crc = SWAP_LE32(G.gpt_hdr->hdr_crc32); |
| + | G.gpt_hdr->hdr_crc32 = 0; |
| + | if (gpt_crc32(G.gpt_hdr, SWAP_LE32(G.gpt_hdr->hdr_size)) != crc) { |
| /* FIXME: read the backup table */ | |
| puts("\nwarning: GPT header CRC is invalid\n"); | |
| } | |
| - | n_parts = SWAP_LE32(gpt_hdr->n_parts); |
| - | part_entry_len = SWAP_LE32(gpt_hdr->part_entry_len); |
| - | if (n_parts > GPT_MAX_PARTS |
| - | || part_entry_len > GPT_MAX_PART_ENTRY_LEN |
| - | || SWAP_LE32(gpt_hdr->hdr_size) > sector_size |
| + | G.gpt_n_parts = SWAP_LE32(G.gpt_hdr->n_parts); |
| + | G.gpt_part_entry_len = SWAP_LE32(G.gpt_hdr->part_entry_len); |
| + | if (G.gpt_n_parts > GPT_MAX_PARTS |
| + | || G.gpt_part_entry_len > GPT_MAX_PART_ENTRY_LEN |
| + | || SWAP_LE32(G.gpt_hdr->hdr_size) > sector_size |
| ) { | |
| - | puts("\nwarning: unable to parse GPT disklabel\n"); |
| + | puts("\nwarning: can't parse GPT disklabel\n"); |
| current_label_type = LABEL_DOS; | |
| return 0; | |
| } | |
| - | part_array_len = n_parts * part_entry_len; |
| - | part_array = xmalloc(part_array_len); |
| - | seek_sector(SWAP_LE64(gpt_hdr->first_part_lba)); |
| - | if (full_read(dev_fd, part_array, part_array_len) != part_array_len) { |
| + | part_array_len = G.gpt_n_parts * G.gpt_part_entry_len; |
| + | G.gpt_part_array = xmalloc(part_array_len); |
| + | seek_sector(SWAP_LE64(G.gpt_hdr->first_part_lba)); |
| + | if (full_read(dev_fd, G.gpt_part_array, part_array_len) != part_array_len) { |
| fdisk_fatal(unable_to_read); | |
| } | |
| - | if (gpt_crc32(part_array, part_array_len) != gpt_hdr->part_array_crc32) { |
| + | if (gpt_crc32(G.gpt_part_array, part_array_len) != G.gpt_hdr->part_array_crc32) { |
| /* FIXME: read the backup table */ | |
| puts("\nwarning: GPT array CRC is invalid\n"); | |
| } | |
| @@ -260,8 +260,6 @@ static void alpha_bootblock_checksum(char *boot); | |
| #if !defined(__alpha__) | |
| static int xbsd_translate_fstype(int linux_type); | |
| static void xbsd_link_part(void); | |
| - | static struct partition *xbsd_part; |
| - | static int xbsd_part_index; |
| #endif | |
| @@ -356,9 +354,9 @@ bsd_select(void) | |
| for (t = 0; t < 4; t++) { | |
| p = get_part_table(t); | |
| if (p && is_bsd_partition_type(p->sys_ind)) { | |
| - | xbsd_part = p; |
| - | xbsd_part_index = t; |
| - | ss = get_start_sect(xbsd_part); |
| + | G.xbsd_part = p; |
| + | G.xbsd_part_index = t; |
| + | ss = get_start_sect(G.xbsd_part); |
| if (ss == 0) { | |
| printf("Partition %s has invalid starting sector 0\n", | |
| partname(disk_device, t+1, 0)); | |
| @@ -366,7 +364,7 @@ bsd_select(void) | |
| } | |
| printf("Reading disklabel of %s at sector %u\n", | |
| partname(disk_device, t+1, 0), ss + BSD_LABELSECTOR); | |
| - | if (xbsd_readlabel(xbsd_part) == 0) { |
| + | if (xbsd_readlabel(G.xbsd_part) == 0) { |
| if (xbsd_create_disklabel() == 0) | |
| return; | |
| break; | |
| @@ -463,8 +461,8 @@ xbsd_new_part(void) | |
| return; | |
| #if !defined(__alpha__) && !defined(__powerpc__) && !defined(__hppa__) | |
| - | begin = get_start_sect(xbsd_part); |
| - | end = begin + get_nr_sects(xbsd_part) - 1; |
| + | begin = get_start_sect(G.xbsd_part); |
| + | end = begin + get_nr_sects(G.xbsd_part) - 1; |
| #else | |
| begin = 0; | |
| end = xbsd_dlabel.d_secperunit - 1; | |
| @@ -503,7 +501,7 @@ xbsd_print_disklabel(int show_all) | |
| #if defined(__alpha__) | |
| printf("# %s:\n", disk_device); | |
| #else | |
| - | printf("# %s:\n", partname(disk_device, xbsd_part_index+1, 0)); |
| + | printf("# %s:\n", partname(disk_device, G.xbsd_part_index + 1, 0)); |
| #endif | |
| if ((unsigned) lp->d_type < ARRAY_SIZE(xbsd_dktypenames)-1) | |
| printf("type: %s\n", xbsd_dktypenames[lp->d_type]); | |
| @@ -593,8 +591,8 @@ xbsd_write_disklabel(void) | |
| xbsd_writelabel(NULL); | |
| #else | |
| printf("Writing disklabel to %s\n", | |
| - | partname(disk_device, xbsd_part_index + 1, 0)); |
| - | xbsd_writelabel(xbsd_part); |
| + | partname(disk_device, G.xbsd_part_index + 1, 0)); |
| + | xbsd_writelabel(G.xbsd_part); |
| #endif | |
| reread_partition_table(0); /* no exit yet */ | |
| } | |
| @@ -608,7 +606,7 @@ xbsd_create_disklabel(void) | |
| printf("%s contains no disklabel\n", disk_device); | |
| #else | |
| printf("%s contains no disklabel\n", | |
| - | partname(disk_device, xbsd_part_index + 1, 0)); |
| + | partname(disk_device, G.xbsd_part_index + 1, 0)); |
| #endif | |
| while (1) { | |
| @@ -619,7 +617,7 @@ xbsd_create_disklabel(void) | |
| defined(__s390__) || defined(__s390x__) | |
| NULL | |
| #else | |
| - | xbsd_part |
| + | G.xbsd_part |
| #endif | |
| ) == 1) { | |
| xbsd_print_disklabel(1); | |
| @@ -761,7 +759,7 @@ xbsd_write_bootstrap(void) | |
| sector = 0; | |
| alpha_bootblock_checksum(disklabelbuffer); | |
| #else | |
| - | sector = get_start_sect(xbsd_part); |
| + | sector = get_start_sect(G.xbsd_part); |
| #endif | |
| seek_sector(sector); | |
| @@ -771,7 +769,7 @@ xbsd_write_bootstrap(void) | |
| printf("Bootstrap installed on %s\n", disk_device); | |
| #else | |
| printf("Bootstrap installed on %s\n", | |
| - | partname(disk_device, xbsd_part_index+1, 0)); |
| + | partname(disk_device, G.xbsd_part_index + 1, 0)); |
| #endif | |
| sync_disks(); | |
| @@ -19,18 +19,14 @@ | |
| #define SUN_LABEL_MAGIC 0xDABE | |
| #define SUN_LABEL_MAGIC_SWAPPED 0xBEDA | |
| - | #define SUN_SSWAP16(x) (sun_other_endian ? fdisk_swap16(x) : (uint16_t)(x)) |
| - | #define SUN_SSWAP32(x) (sun_other_endian ? fdisk_swap32(x) : (uint32_t)(x)) |
| + | #define SUN_SSWAP16(x) (G.sun_other_endian ? fdisk_swap16(x) : (uint16_t)(x)) |
| + | #define SUN_SSWAP32(x) (G.sun_other_endian ? fdisk_swap32(x) : (uint32_t)(x)) |
| /* Copied from linux/major.h */ | |
| #define FLOPPY_MAJOR 2 | |
| #define SCSI_IOCTL_GET_IDLUN 0x5382 | |
| - | static smallint sun_other_endian; |
| - | static smallint scsi_disk; |
| - | static smallint floppy; |
| - | |
| #ifndef IDE0_MAJOR | |
| #define IDE0_MAJOR 3 | |
| #endif | |
| @@ -39,25 +35,28 @@ static smallint floppy; | |
| #endif | |
| static void | |
| - | guess_device_type(void) |
| + | sun_guess_device_type(void) |
| { | |
| struct stat bootstat; | |
| - | if (fstat(dev_fd, &bootstat) < 0) { |
| - | scsi_disk = 0; |
| - | floppy = 0; |
| - | } else if (S_ISBLK(bootstat.st_mode) |
| - | && (major(bootstat.st_rdev) == IDE0_MAJOR || |
| - | major(bootstat.st_rdev) == IDE1_MAJOR)) { |
| - | scsi_disk = 0; |
| - | floppy = 0; |
| - | } else if (S_ISBLK(bootstat.st_mode) |
| - | && major(bootstat.st_rdev) == FLOPPY_MAJOR) { |
| - | scsi_disk = 0; |
| - | floppy = 1; |
| + | G.sun_scsi_disk = 0; |
| + | G.sun_floppy = 0; |
| + | if (fstat(dev_fd, &bootstat) < 0) |
| + | return; |
| + | if (S_ISBLK(bootstat.st_mode)) { |
| + | //if (major(bootstat.st_rdev) == IDE0_MAJOR |
| + | // || major(bootstat.st_rdev) == IDE1_MAJOR |
| + | //) { |
| + | // G.sun_scsi_disk = 0; |
| + | // G.sun_floppy = 0; |
| + | //} |
| + | if (major(bootstat.st_rdev) == FLOPPY_MAJOR) { |
| + | //G.sun_scsi_disk = 0; |
| + | G.sun_floppy = 1; |
| + | } |
| } else { | |
| - | scsi_disk = 1; |
| - | floppy = 0; |
| + | G.sun_scsi_disk = 1; |
| + | //G.sun_floppy = 0; |
| } | |
| } | |
| @@ -101,10 +100,10 @@ check_sun_label(void) | |
| && sunlabel->magic != SUN_LABEL_MAGIC_SWAPPED | |
| ) { | |
| current_label_type = LABEL_DOS; | |
| - | sun_other_endian = 0; |
| + | G.sun_other_endian = 0; |
| return 0; | |
| } | |
| - | sun_other_endian = (sunlabel->magic == SUN_LABEL_MAGIC_SWAPPED); |
| + | G.sun_other_endian = (sunlabel->magic == SUN_LABEL_MAGIC_SWAPPED); |
| ush = ((unsigned short *) (sunlabel + 1)) - 1; | |
| for (csum = 0; ush >= (unsigned short *)sunlabel;) csum ^= *ush--; | |
| if (csum) { | |
| @@ -238,10 +237,10 @@ create_sunlabel(void) | |
| printf(msg_building_new_label, "sun disklabel"); | |
| - | sun_other_endian = BB_LITTLE_ENDIAN; |
| + | G.sun_other_endian = BB_LITTLE_ENDIAN; |
| memset(MBRbuffer, 0, sizeof(MBRbuffer)); | |
| sunlabel->magic = SUN_SSWAP16(SUN_LABEL_MAGIC); | |
| - | if (!floppy) { |
| + | if (!G.sun_floppy) { |
| unsigned i; | |
| puts("Drive type\n" | |
| " ? auto configure\n" | |
| @@ -265,7 +264,7 @@ create_sunlabel(void) | |
| p = sun_drives + c - 'A'; | |
| break; | |
| } | |
| - | if (c == '?' && scsi_disk) { |
| + | if (c == '?' && G.sun_scsi_disk) { |
| p = sun_autoconfigure_scsi(); | |
| if (p) | |
| break; | |
| @@ -273,7 +272,7 @@ create_sunlabel(void) | |
| } | |
| } | |
| } | |
| - | if (!p || floppy) { |
| + | if (!p || G.sun_floppy) { |
| if (!ioctl(dev_fd, HDIO_GETGEO, &geometry)) { | |
| g_heads = geometry.heads; | |
| g_sectors = geometry.sectors; | |
| @@ -283,7 +282,7 @@ create_sunlabel(void) | |
| g_sectors = 0; | |
| g_cylinders = 0; | |
| } | |
| - | if (floppy) { |
| + | if (G.sun_floppy) { |
| sunlabel->nacyl = 0; | |
| sunlabel->pcylcount = SUN_SSWAP16(g_cylinders); | |
| sunlabel->rspeed = SUN_SSWAP16(300); | |
| @@ -320,13 +319,13 @@ create_sunlabel(void) | |
| snprintf((char *)(sunlabel->info), sizeof(sunlabel->info), | |
| "%s%s%s cyl %u alt %u hd %u sec %u", | |
| p ? p->vendor : "", (p && *p->vendor) ? " " : "", | |
| - | p ? p->model : (floppy ? "3,5\" floppy" : "Linux custom"), |
| + | p ? p->model : (G.sun_floppy ? "3,5\" floppy" : "Linux custom"), |
| g_cylinders, SUN_SSWAP16(sunlabel->nacyl), g_heads, g_sectors); | |
| sunlabel->ntrks = SUN_SSWAP16(g_heads); | |
| sunlabel->nsect = SUN_SSWAP16(g_sectors); | |
| sunlabel->ncyl = SUN_SSWAP16(g_cylinders); | |
| - | if (floppy) |
| + | if (G.sun_floppy) |
| set_sun_partition(0, 0, g_cylinders * g_heads * g_sectors, LINUX_NATIVE); | |
| else { | |
| if (g_cylinders * g_heads * g_sectors >= 150 * 2048) { | |
| @@ -392,14 +391,15 @@ fetch_sun(unsigned *starts, unsigned *lens, unsigned *start, unsigned *stop) | |
| } | |
| } | |
| - | static unsigned *verify_sun_starts; |
| - | |
| static int | |
| - | verify_sun_cmp(int *a, int *b) |
| + | verify_sun_cmp(const void *aa, const void *bb) |
| { | |
| + | const int *a = aa; |
| + | const int *b = bb; |
| if (*a == -1) return 1; | |
| if (*b == -1) return -1; | |
| - | if (verify_sun_starts[*a] > verify_sun_starts[*b]) return 1; |
| + | if (G.verify_sun_starts[*a] > G.verify_sun_starts[*b]) |
| + | return 1; |
| return -1; | |
| } | |
| @@ -410,7 +410,6 @@ verify_sun(void) | |
| int i,j,k,starto,endo; | |
| int array[8]; | |
| - | verify_sun_starts = starts; |
| fetch_sun(starts, lens, &start, &stop); | |
| for (k = 0; k < 7; k++) { | |
| for (i = 0; i < 8; i++) { | |
| @@ -449,8 +448,11 @@ verify_sun(void) | |
| else | |
| array[i] = -1; | |
| } | |
| - | qsort(array, ARRAY_SIZE(array), sizeof(array[0]), |
| - | (int (*)(const void *,const void *)) verify_sun_cmp); |
| + | //TODO: probably can eliminate the need in G.verify_sun_starts |
| + | //if merge starts[] and lens[] in a single array? |
| + | G.verify_sun_starts = starts; |
| + | qsort(array, ARRAY_SIZE(array), sizeof(array[0]), verify_sun_cmp); |
| + | |
| if (array[0] == -1) { | |
| printf("No partitions defined\n"); | |
| return; | |