Changeset 2725 in MondoRescue for branches/2.2.9/mindi-busybox/util-linux/fdisk.c
- Timestamp:
- Feb 25, 2011, 9:26:54 PM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/2.2.9/mindi-busybox/util-linux/fdisk.c
r1765 r2725 5 5 * Copyright (C) 2001,2002 Vladimir Oleynik <dzo@simtreas.ru> (initial bb port) 6 6 * 7 * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.7 * Licensed under GPLv2 or later, see file LICENSE in this source tree. 8 8 */ 9 9 10 10 #ifndef _LARGEFILE64_SOURCE 11 11 /* For lseek64 */ 12 # define _LARGEFILE64_SOURCE12 # define _LARGEFILE64_SOURCE 13 13 #endif 14 14 #include <assert.h> /* assert */ 15 #include <sys/mount.h> 16 #if !defined(BLKSSZGET) 17 # define BLKSSZGET _IO(0x12, 104) 18 #endif 19 #if !defined(BLKGETSIZE64) 20 # define BLKGETSIZE64 _IOR(0x12,114,size_t) 21 #endif 15 22 #include "libbb.h" 23 24 #if BB_LITTLE_ENDIAN 25 # define inline_if_little_endian ALWAYS_INLINE 26 #else 27 # define inline_if_little_endian /* nothing */ 28 #endif 29 16 30 17 31 /* Looks like someone forgot to add this to config system */ 18 32 #ifndef ENABLE_FEATURE_FDISK_BLKSIZE 19 33 # define ENABLE_FEATURE_FDISK_BLKSIZE 0 20 # define USE_FEATURE_FDISK_BLKSIZE(a) 21 #endif 22 23 #define DEFAULT_SECTOR_SIZE 512 24 #define MAX_SECTOR_SIZE 2048 25 #define SECTOR_SIZE 512 /* still used in osf/sgi/sun code */ 26 #define MAXIMUM_PARTS 60 27 28 #define ACTIVE_FLAG 0x80 29 30 #define EXTENDED 0x05 31 #define WIN98_EXTENDED 0x0f 32 #define LINUX_PARTITION 0x81 33 #define LINUX_SWAP 0x82 34 #define LINUX_NATIVE 0x83 35 #define LINUX_EXTENDED 0x85 36 #define LINUX_LVM 0x8e 37 #define LINUX_RAID 0xfd 38 39 /* Used for sector numbers. Today's disk sizes make it necessary */ 34 # define IF_FEATURE_FDISK_BLKSIZE(a) 35 #endif 36 37 #define DEFAULT_SECTOR_SIZE 512 38 #define DEFAULT_SECTOR_SIZE_STR "512" 39 #define MAX_SECTOR_SIZE 2048 40 #define SECTOR_SIZE 512 /* still used in osf/sgi/sun code */ 41 #define MAXIMUM_PARTS 60 42 43 #define ACTIVE_FLAG 0x80 44 45 #define EXTENDED 0x05 46 #define WIN98_EXTENDED 0x0f 47 #define LINUX_PARTITION 0x81 48 #define LINUX_SWAP 0x82 49 #define LINUX_NATIVE 0x83 50 #define LINUX_EXTENDED 0x85 51 #define LINUX_LVM 0x8e 52 #define LINUX_RAID 0xfd 53 54 55 enum { 56 OPT_b = 1 << 0, 57 OPT_C = 1 << 1, 58 OPT_H = 1 << 2, 59 OPT_l = 1 << 3, 60 OPT_S = 1 << 4, 61 OPT_u = 1 << 5, 62 OPT_s = (1 << 6) * ENABLE_FEATURE_FDISK_BLKSIZE, 63 }; 64 65 40 66 typedef unsigned long long ullong; 67 /* Used for sector numbers. Partition formats we know 68 * do not support more than 2^32 sectors 69 */ 70 typedef uint32_t sector_t; 71 #if UINT_MAX == 4294967295 72 # define SECT_FMT "" 73 #elif ULONG_MAX == 4294967295 74 # define SECT_FMT "l" 75 #else 76 # error Cant detect sizeof(uint32_t) 77 #endif 41 78 42 79 struct hd_geometry { … … 55 92 56 93 static const char msg_part_already_defined[] ALIGN1 = 57 "Partition %d is already defined, delete it before re-adding\n"; 58 59 60 static unsigned sector_size = DEFAULT_SECTOR_SIZE; 61 static unsigned user_set_sector_size; 62 static unsigned sector_offset = 1; 63 64 #if ENABLE_FEATURE_OSF_LABEL 65 static int possibly_osf_label; 66 #endif 67 68 static unsigned heads, sectors, cylinders; 69 static void update_units(void); 94 "Partition %u is already defined, delete it before re-adding\n"; 70 95 71 96 … … 75 100 unsigned char sector; /* starting sector */ 76 101 unsigned char cyl; /* starting cylinder */ 77 unsigned char sys_ind; /* What partition type */102 unsigned char sys_ind; /* what partition type */ 78 103 unsigned char end_head; /* end head */ 79 104 unsigned char end_sector; /* end sector */ … … 81 106 unsigned char start4[4]; /* starting sector counting from 0 */ 82 107 unsigned char size4[4]; /* nr of sectors in partition */ 83 } ATTRIBUTE_PACKED; 84 85 static const char unable_to_open[] ALIGN1 = "cannot open %s"; 86 static const char unable_to_read[] ALIGN1 = "cannot read from %s"; 87 static const char unable_to_seek[] ALIGN1 = "cannot seek on %s"; 88 static const char unable_to_write[] ALIGN1 = "cannot write to %s"; 89 static const char ioctl_error[] ALIGN1 = "BLKGETSIZE ioctl failed on %s"; 90 static void fdisk_fatal(const char *why) ATTRIBUTE_NORETURN; 91 92 enum label_type { 93 label_dos, label_sun, label_sgi, label_aix, label_osf 94 }; 95 96 #define LABEL_IS_DOS (label_dos == current_label_type) 97 98 #if ENABLE_FEATURE_SUN_LABEL 99 #define LABEL_IS_SUN (label_sun == current_label_type) 100 #define STATIC_SUN static 101 #else 102 #define LABEL_IS_SUN 0 103 #define STATIC_SUN extern 104 #endif 105 106 #if ENABLE_FEATURE_SGI_LABEL 107 #define LABEL_IS_SGI (label_sgi == current_label_type) 108 #define STATIC_SGI static 109 #else 110 #define LABEL_IS_SGI 0 111 #define STATIC_SGI extern 112 #endif 113 114 #if ENABLE_FEATURE_AIX_LABEL 115 #define LABEL_IS_AIX (label_aix == current_label_type) 116 #define STATIC_AIX static 117 #else 118 #define LABEL_IS_AIX 0 119 #define STATIC_AIX extern 120 #endif 121 122 #if ENABLE_FEATURE_OSF_LABEL 123 #define LABEL_IS_OSF (label_osf == current_label_type) 124 #define STATIC_OSF static 125 #else 126 #define LABEL_IS_OSF 0 127 #define STATIC_OSF extern 128 #endif 129 130 enum action { fdisk, require, try_only, create_empty_dos, create_empty_sun }; 131 132 static enum label_type current_label_type; 133 134 static const char *disk_device; 135 static int fd; /* the disk */ 136 static int partitions = 4; /* maximum partition + 1 */ 137 static int display_in_cyl_units = 1; 138 static unsigned units_per_sector = 1; 139 #if ENABLE_FEATURE_FDISK_WRITABLE 140 static void change_units(void); 141 static void reread_partition_table(int leave); 142 static void delete_partition(int i); 143 static int get_partition(int warn, int max); 144 static void list_types(const char *const *sys); 145 static unsigned read_int(unsigned low, unsigned dflt, unsigned high, unsigned base, const char *mesg); 146 #endif 147 static const char *partition_type(unsigned char type); 148 static void get_geometry(void); 149 static int get_boot(enum action what); 150 151 #define PLURAL 0 152 #define SINGULAR 1 153 154 static unsigned get_start_sect(const struct partition *p); 155 static unsigned get_nr_sects(const struct partition *p); 108 } PACKED; 156 109 157 110 /* … … 166 119 struct partition *part_table; /* points into sectorbuffer */ 167 120 struct partition *ext_pointer; /* points into sectorbuffer */ 168 ullong offset;/* disk sector number */169 char *sectorbuffer; /* disk sector contents */121 sector_t offset_from_dev_start; /* disk sector number */ 122 char *sectorbuffer; /* disk sector contents */ 170 123 #if ENABLE_FEATURE_FDISK_WRITABLE 171 char changed; /* boolean */124 char changed; /* boolean */ 172 125 #endif 173 126 }; 127 128 #define unable_to_open "can't open '%s'" 129 #define unable_to_read "can't read from %s" 130 #define unable_to_seek "can't seek on %s" 131 132 enum label_type { 133 LABEL_DOS, LABEL_SUN, LABEL_SGI, LABEL_AIX, LABEL_OSF, LABEL_GPT 134 }; 135 136 #define LABEL_IS_DOS (LABEL_DOS == current_label_type) 137 138 #if ENABLE_FEATURE_SUN_LABEL 139 #define LABEL_IS_SUN (LABEL_SUN == current_label_type) 140 #define STATIC_SUN static 141 #else 142 #define LABEL_IS_SUN 0 143 #define STATIC_SUN extern 144 #endif 145 146 #if ENABLE_FEATURE_SGI_LABEL 147 #define LABEL_IS_SGI (LABEL_SGI == current_label_type) 148 #define STATIC_SGI static 149 #else 150 #define LABEL_IS_SGI 0 151 #define STATIC_SGI extern 152 #endif 153 154 #if ENABLE_FEATURE_AIX_LABEL 155 #define LABEL_IS_AIX (LABEL_AIX == current_label_type) 156 #define STATIC_AIX static 157 #else 158 #define LABEL_IS_AIX 0 159 #define STATIC_AIX extern 160 #endif 161 162 #if ENABLE_FEATURE_OSF_LABEL 163 #define LABEL_IS_OSF (LABEL_OSF == current_label_type) 164 #define STATIC_OSF static 165 #else 166 #define LABEL_IS_OSF 0 167 #define STATIC_OSF extern 168 #endif 169 170 #if ENABLE_FEATURE_GPT_LABEL 171 #define LABEL_IS_GPT (LABEL_GPT == current_label_type) 172 #define STATIC_GPT static 173 #else 174 #define LABEL_IS_GPT 0 175 #define STATIC_GPT extern 176 #endif 177 178 enum action { OPEN_MAIN, TRY_ONLY, CREATE_EMPTY_DOS, CREATE_EMPTY_SUN }; 179 180 static void update_units(void); 181 #if ENABLE_FEATURE_FDISK_WRITABLE 182 static void change_units(void); 183 static void reread_partition_table(int leave); 184 static void delete_partition(int i); 185 static unsigned get_partition(int warn, unsigned max); 186 static void list_types(const char *const *sys); 187 static sector_t read_int(sector_t low, sector_t dflt, sector_t high, sector_t base, const char *mesg); 188 #endif 189 static const char *partition_type(unsigned char type); 190 static void get_geometry(void); 191 static void read_pte(struct pte *pe, sector_t offset); 192 #if ENABLE_FEATURE_SUN_LABEL || ENABLE_FEATURE_FDISK_WRITABLE 193 static int get_boot(enum action what); 194 #else 195 static int get_boot(void); 196 #endif 197 198 #define PLURAL 0 199 #define SINGULAR 1 200 201 static sector_t get_start_sect(const struct partition *p); 202 static sector_t get_nr_sects(const struct partition *p); 174 203 175 204 /* DOS partition types */ … … 278 307 }; 279 308 309 enum { 310 dev_fd = 3 /* the disk */ 311 }; 280 312 281 313 /* Globals */ 282 283 314 struct globals { 284 315 char *line_ptr; 316 317 const char *disk_device; 318 int g_partitions; // = 4; /* maximum partition + 1 */ 319 unsigned units_per_sector; // = 1; 320 unsigned sector_size; // = DEFAULT_SECTOR_SIZE; 321 unsigned user_set_sector_size; 322 unsigned sector_offset; // = 1; 323 unsigned g_heads, g_sectors, g_cylinders; 324 smallint /* enum label_type */ current_label_type; 325 smallint display_in_cyl_units; // = 1; 326 #if ENABLE_FEATURE_OSF_LABEL 327 smallint possibly_osf_label; 328 #endif 329 330 smallint listing; /* no aborts for fdisk -l */ 331 smallint dos_compatible_flag; // = 1; 332 #if ENABLE_FEATURE_FDISK_WRITABLE 333 //int dos_changed; 334 smallint nowarn; /* no warnings for fdisk -l/-s */ 335 #endif 336 int ext_index; /* the prime extended partition */ 337 unsigned user_cylinders, user_heads, user_sectors; 338 unsigned pt_heads, pt_sectors; 339 unsigned kern_heads, kern_sectors; 340 sector_t extended_offset; /* offset of link pointers */ 341 sector_t total_number_of_sectors; 342 343 jmp_buf listingbuf; 285 344 char line_buffer[80]; 286 345 char partname_buffer[80]; 287 jmp_buf listingbuf;288 346 /* Raw disk label. For DOS-type partition tables the MBR, 289 347 * with descriptions of the primary partitions. */ … … 292 350 struct pte ptes[MAXIMUM_PARTS]; 293 351 }; 294 /* bb_common_bufsiz1 is too small for this on 64 bit CPUs */295 352 #define G (*ptr_to_globals) 296 297 #define line_ptr (G.line_ptr) 298 #define listingbuf (G.listingbuf) 299 #define line_buffer (G.line_buffer) 353 #define line_ptr (G.line_ptr ) 354 #define disk_device (G.disk_device ) 355 #define g_partitions (G.g_partitions ) 356 #define units_per_sector (G.units_per_sector ) 357 #define sector_size (G.sector_size ) 358 #define user_set_sector_size (G.user_set_sector_size) 359 #define sector_offset (G.sector_offset ) 360 #define g_heads (G.g_heads ) 361 #define g_sectors (G.g_sectors ) 362 #define g_cylinders (G.g_cylinders ) 363 #define current_label_type (G.current_label_type ) 364 #define display_in_cyl_units (G.display_in_cyl_units) 365 #define possibly_osf_label (G.possibly_osf_label ) 366 #define listing (G.listing ) 367 #define dos_compatible_flag (G.dos_compatible_flag ) 368 #define nowarn (G.nowarn ) 369 #define ext_index (G.ext_index ) 370 #define user_cylinders (G.user_cylinders ) 371 #define user_heads (G.user_heads ) 372 #define user_sectors (G.user_sectors ) 373 #define pt_heads (G.pt_heads ) 374 #define pt_sectors (G.pt_sectors ) 375 #define kern_heads (G.kern_heads ) 376 #define kern_sectors (G.kern_sectors ) 377 #define extended_offset (G.extended_offset ) 378 #define total_number_of_sectors (G.total_number_of_sectors) 379 #define listingbuf (G.listingbuf ) 380 #define line_buffer (G.line_buffer ) 300 381 #define partname_buffer (G.partname_buffer) 301 #define MBRbuffer (G.MBRbuffer) 302 #define ptes (G.ptes) 303 304 305 /* Code */ 382 #define MBRbuffer (G.MBRbuffer ) 383 #define ptes (G.ptes ) 384 #define INIT_G() do { \ 385 SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \ 386 sector_size = DEFAULT_SECTOR_SIZE; \ 387 sector_offset = 1; \ 388 g_partitions = 4; \ 389 display_in_cyl_units = 1; \ 390 units_per_sector = 1; \ 391 dos_compatible_flag = 1; \ 392 } while (0) 393 394 395 /* TODO: move to libbb? */ 396 /* TODO: return unsigned long long, FEATURE_FDISK_BLKSIZE _can_ handle 397 * disks > 2^32 sectors 398 */ 399 static sector_t bb_BLKGETSIZE_sectors(int fd) 400 { 401 uint64_t v64; 402 unsigned long longsectors; 403 404 if (ioctl(fd, BLKGETSIZE64, &v64) == 0) { 405 /* Got bytes, convert to 512 byte sectors */ 406 v64 >>= 9; 407 if (v64 != (sector_t)v64) { 408 ret_trunc: 409 /* Not only DOS, but all other partition tables 410 * we support can't record more than 32 bit 411 * sector counts or offsets 412 */ 413 bb_error_msg("device has more than 2^32 sectors, can't use all of them"); 414 v64 = (uint32_t)-1L; 415 } 416 return v64; 417 } 418 /* Needs temp of type long */ 419 if (ioctl(fd, BLKGETSIZE, &longsectors)) { 420 /* Perhaps this is a disk image */ 421 off_t sz = lseek(fd, 0, SEEK_END); 422 longsectors = 0; 423 if (sz > 0) 424 longsectors = (uoff_t)sz / sector_size; 425 lseek(fd, 0, SEEK_SET); 426 } 427 if (sizeof(long) > sizeof(sector_t) 428 && longsectors != (sector_t)longsectors 429 ) { 430 goto ret_trunc; 431 } 432 return longsectors; 433 } 434 306 435 307 436 #define IS_EXTENDED(i) \ … … 322 451 (sector(s) - 1 + sectors * ((h) + heads * cylinder(s,c))) 323 452 324 #define set_hsc(h,s,c,sector) \ 325 do { \ 326 s = sector % sectors + 1; \ 327 sector /= sectors; \ 328 h = sector % heads; \ 329 sector /= heads; \ 330 c = sector & 0xff; \ 331 s |= (sector >> 2) & 0xc0; \ 332 } while (0) 333 334 #if ENABLE_FEATURE_FDISK_WRITABLE 335 /* read line; return 0 or first printable char */ 336 static int 337 read_line(const char *prompt) 338 { 339 int sz; 340 341 sz = read_line_input(prompt, line_buffer, sizeof(line_buffer), NULL); 342 if (sz <= 0) 343 exit(0); /* Ctrl-D or Ctrl-C */ 344 345 if (line_buffer[sz-1] == '\n') 346 line_buffer[--sz] = '\0'; 347 348 line_ptr = line_buffer; 349 while (*line_ptr && !isgraph(*line_ptr)) 350 line_ptr++; 351 return *line_ptr; 352 } 353 #endif 453 static void 454 close_dev_fd(void) 455 { 456 /* Not really closing, but making sure it is open, and to harmless place */ 457 xmove_fd(xopen(bb_dev_null, O_RDONLY), dev_fd); 458 } 354 459 355 460 /* 356 * return partition name - uses static storage461 * Return partition name - uses static storage 357 462 */ 358 463 static const char * … … 384 489 if (lth) { 385 490 snprintf(bufp, bufsiz, "%*.*s%s%-2u", 386 491 lth-wp-2, w, dev, p, pno); 387 492 } else { 388 493 snprintf(bufp, bufsiz, "%.*s%s%-2u", w, dev, p, pno); … … 390 495 return bufp; 391 496 } 392 393 #if ENABLE_FEATURE_FDISK_WRITABLE394 static void395 set_all_unchanged(void)396 {397 int i;398 399 for (i = 0; i < MAXIMUM_PARTS; i++)400 ptes[i].changed = 0;401 }402 403 static ALWAYS_INLINE void404 set_changed(int i)405 {406 ptes[i].changed = 1;407 }408 #endif /* FEATURE_FDISK_WRITABLE */409 497 410 498 static ALWAYS_INLINE struct partition * … … 428 516 } 429 517 518 static void fdisk_fatal(const char *why) 519 { 520 if (listing) { 521 close_dev_fd(); 522 longjmp(listingbuf, 1); 523 } 524 bb_error_msg_and_die(why, disk_device); 525 } 526 527 static void 528 seek_sector(sector_t secno) 529 { 530 #if ENABLE_FDISK_SUPPORT_LARGE_DISKS 531 off64_t off = (off64_t)secno * sector_size; 532 if (lseek64(dev_fd, off, SEEK_SET) == (off64_t) -1) 533 fdisk_fatal(unable_to_seek); 534 #else 535 uint64_t off = (uint64_t)secno * sector_size; 536 if (off > MAXINT(off_t) 537 || lseek(dev_fd, (off_t)off, SEEK_SET) == (off_t) -1 538 ) { 539 fdisk_fatal(unable_to_seek); 540 } 541 #endif 542 } 543 430 544 #if ENABLE_FEATURE_FDISK_WRITABLE 545 /* Read line; return 0 or first printable char */ 546 static int 547 read_line(const char *prompt) 548 { 549 int sz; 550 551 sz = read_line_input(prompt, line_buffer, sizeof(line_buffer), NULL); 552 if (sz <= 0) 553 exit(EXIT_SUCCESS); /* Ctrl-D or Ctrl-C */ 554 555 if (line_buffer[sz-1] == '\n') 556 line_buffer[--sz] = '\0'; 557 558 line_ptr = line_buffer; 559 while (*line_ptr != '\0' && (unsigned char)*line_ptr <= ' ') 560 line_ptr++; 561 return *line_ptr; 562 } 563 564 static void 565 set_all_unchanged(void) 566 { 567 int i; 568 569 for (i = 0; i < MAXIMUM_PARTS; i++) 570 ptes[i].changed = 0; 571 } 572 573 static ALWAYS_INLINE void 574 set_changed(int i) 575 { 576 ptes[i].changed = 1; 577 } 578 431 579 static ALWAYS_INLINE void 432 580 write_part_table_flag(char *b) … … 439 587 read_nonempty(const char *mesg) 440 588 { 441 while (!read_line(mesg)) /* repeat */; 589 while (!read_line(mesg)) 590 continue; 442 591 return *line_ptr; 443 592 } … … 460 609 while (1) { 461 610 read_nonempty("Hex code (type L to list codes): "); 462 if ( *line_ptr == 'l' || *line_ptr == 'L') {611 if ((line_ptr[0] | 0x20) == 'l') { 463 612 list_types(sys); 464 613 continue; 465 614 } 466 615 v = bb_strtoul(line_ptr, NULL, 16); 467 if (v > 0xff) 468 /* Bad input also triggers this */ 469 continue; 470 return v; 471 } 616 if (v <= 0xff) 617 return v; 618 } 619 } 620 621 static void 622 write_sector(sector_t secno, const void *buf) 623 { 624 seek_sector(secno); 625 xwrite(dev_fd, buf, sector_size); 472 626 } 473 627 #endif /* FEATURE_FDISK_WRITABLE */ 474 628 629 475 630 #include "fdisk_aix.c" 476 631 477 typedef struct{632 struct sun_partition { 478 633 unsigned char info[128]; /* Informative text string */ 479 634 unsigned char spare0[14]; … … 501 656 unsigned short magic; /* Magic number */ 502 657 unsigned short csum; /* Label xor'd checksum */ 503 } sun_partition; 658 } FIX_ALIASING; 659 typedef struct sun_partition sun_partition; 504 660 #define sunlabel ((sun_partition *)MBRbuffer) 505 661 STATIC_OSF void bsd_select(void); 506 662 STATIC_OSF void xbsd_print_disklabel(int); 507 663 #include "fdisk_osf.c" 664 665 STATIC_GPT void gpt_list_table(int xtra); 666 #include "fdisk_gpt.c" 508 667 509 668 #if ENABLE_FEATURE_SGI_LABEL || ENABLE_FEATURE_SUN_LABEL … … 561 720 #include "fdisk_sun.c" 562 721 722 723 static inline_if_little_endian unsigned 724 read4_little_endian(const unsigned char *cp) 725 { 726 uint32_t v; 727 move_from_unaligned32(v, cp); 728 return SWAP_LE32(v); 729 } 730 731 static sector_t 732 get_start_sect(const struct partition *p) 733 { 734 return read4_little_endian(p->start4); 735 } 736 737 static sector_t 738 get_nr_sects(const struct partition *p) 739 { 740 return read4_little_endian(p->size4); 741 } 742 563 743 #if ENABLE_FEATURE_FDISK_WRITABLE 564 744 /* start_sect and nr_sects are stored little endian on all machines */ 565 745 /* moreover, they are not aligned correctly */ 566 static void746 static inline_if_little_endian void 567 747 store4_little_endian(unsigned char *cp, unsigned val) 568 748 { 569 cp[0] = val; 570 cp[1] = val >> 8; 571 cp[2] = val >> 16; 572 cp[3] = val >> 24; 573 } 574 #endif /* FEATURE_FDISK_WRITABLE */ 575 576 static unsigned 577 read4_little_endian(const unsigned char *cp) 578 { 579 return cp[0] + (cp[1] << 8) + (cp[2] << 16) + (cp[3] << 24); 580 } 581 582 #if ENABLE_FEATURE_FDISK_WRITABLE 749 uint32_t v = SWAP_LE32(val); 750 move_to_unaligned32(cp, v); 751 } 752 583 753 static void 584 754 set_start_sect(struct partition *p, unsigned start_sect) … … 586 756 store4_little_endian(p->start4, start_sect); 587 757 } 588 #endif 589 590 static unsigned 591 get_start_sect(const struct partition *p) 592 { 593 return read4_little_endian(p->start4); 594 } 595 596 #if ENABLE_FEATURE_FDISK_WRITABLE 758 597 759 static void 598 760 set_nr_sects(struct partition *p, unsigned nr_sects) … … 602 764 #endif 603 765 604 static unsigned605 get_nr_sects(const struct partition *p)606 {607 return read4_little_endian(p->size4);608 }609 610 /* normally O_RDWR, -l option gives O_RDONLY */611 static int type_open = O_RDWR;612 613 static int ext_index; /* the prime extended partition */614 static int listing; /* no aborts for fdisk -l */615 static int dos_compatible_flag = ~0;616 #if ENABLE_FEATURE_FDISK_WRITABLE617 static int dos_changed;618 static int nowarn; /* no warnings for fdisk -l/-s */619 #endif620 621 static unsigned user_cylinders, user_heads, user_sectors;622 static unsigned pt_heads, pt_sectors;623 static unsigned kern_heads, kern_sectors;624 625 static ullong extended_offset; /* offset of link pointers */626 static ullong total_number_of_sectors;627 628 static void fdisk_fatal(const char *why)629 {630 if (listing) {631 close(fd);632 longjmp(listingbuf, 1);633 }634 bb_error_msg_and_die(why, disk_device);635 }636 637 static void638 seek_sector(ullong secno)639 {640 secno *= sector_size;641 #if ENABLE_FDISK_SUPPORT_LARGE_DISKS642 if (lseek64(fd, (off64_t)secno, SEEK_SET) == (off64_t) -1)643 fdisk_fatal(unable_to_seek);644 #else645 if (secno > MAXINT(off_t)646 || lseek(fd, (off_t)secno, SEEK_SET) == (off_t) -1647 ) {648 fdisk_fatal(unable_to_seek);649 }650 #endif651 }652 653 #if ENABLE_FEATURE_FDISK_WRITABLE654 static void655 write_sector(ullong secno, char *buf)656 {657 seek_sector(secno);658 if (write(fd, buf, sector_size) != sector_size)659 fdisk_fatal(unable_to_write);660 }661 #endif662 663 766 /* Allocate a buffer and read a partition table sector */ 664 767 static void 665 read_pte(struct pte *pe, ullongoffset)666 { 667 pe->offset = offset;668 pe->sectorbuffer = x malloc(sector_size);768 read_pte(struct pte *pe, sector_t offset) 769 { 770 pe->offset_from_dev_start = offset; 771 pe->sectorbuffer = xzalloc(sector_size); 669 772 seek_sector(offset); 670 if (read(fd, pe->sectorbuffer, sector_size) != sector_size) 773 /* xread would make us abort - bad for fdisk -l */ 774 if (full_read(dev_fd, pe->sectorbuffer, sector_size) != sector_size) 671 775 fdisk_fatal(unable_to_read); 672 776 #if ENABLE_FEATURE_FDISK_WRITABLE … … 676 780 } 677 781 678 static unsigned679 get_partition_start (const struct pte *pe)680 { 681 return pe->offset + get_start_sect(pe->part_table);782 static sector_t 783 get_partition_start_from_dev_start(const struct pte *pe) 784 { 785 return pe->offset_from_dev_start + get_start_sect(pe->part_table); 682 786 } 683 787 … … 689 793 * for "is probably nondos partition". 690 794 */ 795 #ifdef UNUSED 691 796 static int 692 797 is_dos_partition(int t) … … 698 803 t == 0xc1 || t == 0xc4 || t == 0xc6); 699 804 } 805 #endif 700 806 701 807 static void … … 738 844 } else if (LABEL_IS_AIX) { 739 845 puts("o\tcreate a new empty DOS partition table"); 846 puts("q\tquit without saving changes"); 847 puts("s\tcreate a new empty Sun disklabel"); /* sun */ 848 } else if (LABEL_IS_GPT) { 849 puts("o\tcreate a new empty DOS partition table"); 850 puts("p\tprint the partition table"); 740 851 puts("q\tquit without saving changes"); 741 852 puts("s\tcreate a new empty Sun disklabel"); /* sun */ … … 840 951 #else 841 952 #define get_sys_types() i386_sys_types 842 #endif /* FEATURE_FDISK_WRITABLE */953 #endif 843 954 844 955 static const char * … … 855 966 } 856 967 968 static int 969 is_cleared_partition(const struct partition *p) 970 { 971 /* We consider partition "cleared" only if it has only zeros */ 972 const char *cp = (const char *)p; 973 int cnt = sizeof(*p); 974 char bits = 0; 975 while (--cnt >= 0) 976 bits |= *cp++; 977 return (bits == 0); 978 } 979 980 static void 981 clear_partition(struct partition *p) 982 { 983 if (p) 984 memset(p, 0, sizeof(*p)); 985 } 857 986 858 987 #if ENABLE_FEATURE_FDISK_WRITABLE … … 874 1003 int i; 875 1004 876 for (size = 0; sys[size]; size++) /* */; 1005 for (size = 0; sys[size]; size++) 1006 continue; 877 1007 878 1008 done = 0; … … 893 1023 } 894 1024 } while (done < last[0]); 895 putchar('\n'); 896 } 897 #endif /* FEATURE_FDISK_WRITABLE */ 898 899 static int 900 is_cleared_partition(const struct partition *p) 901 { 902 return !(!p || p->boot_ind || p->head || p->sector || p->cyl || 903 p->sys_ind || p->end_head || p->end_sector || p->end_cyl || 904 get_start_sect(p) || get_nr_sects(p)); 905 } 906 907 static void 908 clear_partition(struct partition *p) 909 { 910 if (!p) 911 return; 912 memset(p, 0, sizeof(struct partition)); 913 } 914 915 #if ENABLE_FEATURE_FDISK_WRITABLE 916 static void 917 set_partition(int i, int doext, ullong start, ullong stop, int sysid) 1025 bb_putchar('\n'); 1026 } 1027 1028 #define set_hsc(h, s, c, sector) do \ 1029 { \ 1030 s = sector % g_sectors + 1; \ 1031 sector /= g_sectors; \ 1032 h = sector % g_heads; \ 1033 sector /= g_heads; \ 1034 c = sector & 0xff; \ 1035 s |= (sector >> 2) & 0xc0; \ 1036 } while (0) 1037 1038 static void set_hsc_start_end(struct partition *p, sector_t start, sector_t stop) 1039 { 1040 if (dos_compatible_flag && (start / (g_sectors * g_heads) > 1023)) 1041 start = g_heads * g_sectors * 1024 - 1; 1042 set_hsc(p->head, p->sector, p->cyl, start); 1043 1044 if (dos_compatible_flag && (stop / (g_sectors * g_heads) > 1023)) 1045 stop = g_heads * g_sectors * 1024 - 1; 1046 set_hsc(p->end_head, p->end_sector, p->end_cyl, stop); 1047 } 1048 1049 static void 1050 set_partition(int i, int doext, sector_t start, sector_t stop, int sysid) 918 1051 { 919 1052 struct partition *p; 920 ullongoffset;1053 sector_t offset; 921 1054 922 1055 if (doext) { … … 925 1058 } else { 926 1059 p = ptes[i].part_table; 927 offset = ptes[i].offset ;1060 offset = ptes[i].offset_from_dev_start; 928 1061 } 929 1062 p->boot_ind = 0; … … 931 1064 set_start_sect(p, start - offset); 932 1065 set_nr_sects(p, stop - start + 1); 933 if (dos_compatible_flag && (start/(sectors*heads) > 1023)) 934 start = heads*sectors*1024 - 1; 935 set_hsc(p->head, p->sector, p->cyl, start); 936 if (dos_compatible_flag && (stop/(sectors*heads) > 1023)) 937 stop = heads*sectors*1024 - 1; 938 set_hsc(p->end_head, p->end_sector, p->end_cyl, stop); 1066 set_hsc_start_end(p, start, stop); 939 1067 ptes[i].changed = 1; 940 1068 } … … 944 1072 warn_geometry(void) 945 1073 { 946 if ( heads && sectors &&cylinders)1074 if (g_heads && g_sectors && g_cylinders) 947 1075 return 0; 948 1076 949 1077 printf("Unknown value(s) for:"); 950 if (! heads)1078 if (!g_heads) 951 1079 printf(" heads"); 952 if (! sectors)1080 if (!g_sectors) 953 1081 printf(" sectors"); 954 if (! cylinders)1082 if (!g_cylinders) 955 1083 printf(" cylinders"); 956 1084 printf( … … 965 1093 update_units(void) 966 1094 { 967 int cyl_units = heads *sectors;1095 int cyl_units = g_heads * g_sectors; 968 1096 969 1097 if (display_in_cyl_units && cyl_units) … … 977 1105 warn_cylinders(void) 978 1106 { 979 if (LABEL_IS_DOS && cylinders > 1024 && !nowarn)1107 if (LABEL_IS_DOS && g_cylinders > 1024 && !nowarn) 980 1108 printf("\n" 981 "The number of cylinders for this disk is set to % d.\n"1109 "The number of cylinders for this disk is set to %u.\n" 982 1110 "There is nothing wrong with that, but this is larger than 1024,\n" 983 1111 "and could in certain setups cause problems with:\n" … … 985 1113 "2) booting and partitioning software from other OSs\n" 986 1114 " (e.g., DOS FDISK, OS/2 FDISK)\n", 987 cylinders);1115 g_cylinders); 988 1116 } 989 1117 #endif … … 1007 1135 1008 1136 while (IS_EXTENDED(p->sys_ind)) { 1009 struct pte *pe = &ptes[ partitions];1010 1011 if ( partitions >= MAXIMUM_PARTS) {1137 struct pte *pe = &ptes[g_partitions]; 1138 1139 if (g_partitions >= MAXIMUM_PARTS) { 1012 1140 /* This is not a Linux restriction, but 1013 1141 this program uses arrays of size MAXIMUM_PARTS. 1014 1142 Do not try to 'improve' this test. */ 1015 struct pte *pre = &ptes[ partitions-1];1143 struct pte *pre = &ptes[g_partitions - 1]; 1016 1144 #if ENABLE_FEATURE_FDISK_WRITABLE 1017 printf("Warning: deleting partitions after % d\n",1018 partitions);1145 printf("Warning: deleting partitions after %u\n", 1146 g_partitions); 1019 1147 pre->changed = 1; 1020 1148 #endif … … 1034 1162 printf("Warning: extra link " 1035 1163 "pointer in partition table" 1036 " % d\n",partitions + 1);1164 " %u\n", g_partitions + 1); 1037 1165 else 1038 1166 pe->ext_pointer = p; … … 1041 1169 printf("Warning: ignoring extra " 1042 1170 "data in partition table" 1043 " % d\n",partitions + 1);1171 " %u\n", g_partitions + 1); 1044 1172 else 1045 1173 pe->part_table = p; … … 1062 1190 1063 1191 p = pe->ext_pointer; 1064 partitions++;1192 g_partitions++; 1065 1193 } 1066 1194 … … 1068 1196 /* remove empty links */ 1069 1197 remove: 1070 for (i = 4; i < partitions; i++) {1198 for (i = 4; i < g_partitions; i++) { 1071 1199 struct pte *pe = &ptes[i]; 1072 1200 1073 1201 if (!get_nr_sects(pe->part_table) 1074 && ( partitions > 5 || ptes[4].part_table->sys_ind)1202 && (g_partitions > 5 || ptes[4].part_table->sys_ind) 1075 1203 ) { 1076 printf("Omitting empty partition (% d)\n", i+1);1204 printf("Omitting empty partition (%u)\n", i+1); 1077 1205 delete_partition(i); 1078 1206 goto remove; /* numbering changed */ … … 1086 1214 create_doslabel(void) 1087 1215 { 1088 int i;1089 1090 1216 printf(msg_building_new_label, "DOS disklabel"); 1091 1217 1092 current_label_type = label_dos; 1093 1218 current_label_type = LABEL_DOS; 1094 1219 #if ENABLE_FEATURE_OSF_LABEL 1095 1220 possibly_osf_label = 0; 1096 1221 #endif 1097 partitions = 4; 1098 1099 for (i = 510-64; i < 510; i++) 1100 MBRbuffer[i] = 0; 1222 g_partitions = 4; 1223 1224 memset(&MBRbuffer[510 - 4*16], 0, 4*16); 1101 1225 write_part_table_flag(MBRbuffer); 1102 1226 extended_offset = 0; 1103 1227 set_all_unchanged(); 1104 1228 set_changed(0); 1105 get_boot( create_empty_dos);1106 } 1107 #endif /* FEATURE_FDISK_WRITABLE */1229 get_boot(CREATE_EMPTY_DOS); 1230 } 1231 #endif 1108 1232 1109 1233 static void … … 1112 1236 if (!user_set_sector_size) { 1113 1237 int arg; 1114 if (ioctl( fd, BLKSSZGET, &arg) == 0)1238 if (ioctl(dev_fd, BLKSSZGET, &arg) == 0) 1115 1239 sector_size = arg; 1116 1240 if (sector_size != DEFAULT_SECTOR_SIZE) 1117 printf("Note: sector size is %d (not %d)\n", 1118 sector_size, DEFAULT_SECTOR_SIZE); 1241 printf("Note: sector size is %u " 1242 "(not " DEFAULT_SECTOR_SIZE_STR ")\n", 1243 sector_size); 1119 1244 } 1120 1245 } … … 1125 1250 struct hd_geometry geometry; 1126 1251 1127 if (!ioctl( fd, HDIO_GETGEO, &geometry)) {1252 if (!ioctl(dev_fd, HDIO_GETGEO, &geometry)) { 1128 1253 kern_heads = geometry.heads; 1129 1254 kern_sectors = geometry.sectors; … … 1169 1294 { 1170 1295 int sec_fac; 1171 uint64_t v64;1172 1296 1173 1297 get_sectorsize(); … … 1176 1300 guess_device_type(); 1177 1301 #endif 1178 heads = cylinders =sectors = 0;1302 g_heads = g_cylinders = g_sectors = 0; 1179 1303 kern_heads = kern_sectors = 0; 1180 1304 pt_heads = pt_sectors = 0; … … 1183 1307 get_partition_table_geometry(); 1184 1308 1185 heads = user_heads ? user_heads :1309 g_heads = user_heads ? user_heads : 1186 1310 pt_heads ? pt_heads : 1187 1311 kern_heads ? kern_heads : 255; 1188 sectors = user_sectors ? user_sectors :1312 g_sectors = user_sectors ? user_sectors : 1189 1313 pt_sectors ? pt_sectors : 1190 1314 kern_sectors ? kern_sectors : 63; 1191 if (ioctl(fd, BLKGETSIZE64, &v64) == 0) { 1192 /* got bytes, convert to 512 byte sectors */ 1193 total_number_of_sectors = (v64 >> 9); 1194 } else { 1195 unsigned long longsectors; /* need temp of type long */ 1196 if (ioctl(fd, BLKGETSIZE, &longsectors)) 1197 longsectors = 0; 1198 total_number_of_sectors = longsectors; 1199 } 1315 total_number_of_sectors = bb_BLKGETSIZE_sectors(dev_fd); 1200 1316 1201 1317 sector_offset = 1; 1202 1318 if (dos_compatible_flag) 1203 sector_offset = sectors;1204 1205 cylinders = total_number_of_sectors / (heads *sectors * sec_fac);1206 if (! cylinders)1207 cylinders = user_cylinders;1319 sector_offset = g_sectors; 1320 1321 g_cylinders = total_number_of_sectors / (g_heads * g_sectors * sec_fac); 1322 if (!g_cylinders) 1323 g_cylinders = user_cylinders; 1208 1324 } 1209 1325 1210 1326 /* 1211 * Read MBR. Returns: 1327 * Opens disk_device and optionally reads MBR. 1328 * If what == OPEN_MAIN: 1329 * Open device, read MBR. Abort program on short read. Create empty 1330 * disklabel if the on-disk structure is invalid (WRITABLE mode). 1331 * If what == TRY_ONLY: 1332 * Open device, read MBR. Return an error if anything is out of place. 1333 * Do not create an empty disklabel. This is used for the "list" 1334 * operations: "fdisk -l /dev/sda" and "fdisk -l" (all devices). 1335 * If what == CREATE_EMPTY_*: 1336 * This means that get_boot() was called recursively from create_*label(). 1337 * Do not re-open the device; just set up the ptes array and print 1338 * geometry warnings. 1339 * 1340 * Returns: 1212 1341 * -1: no 0xaa55 flag present (possibly entire disk BSD) 1213 1342 * 0: found or created label 1214 1343 * 1: I/O error 1215 1344 */ 1216 static int 1217 get_boot(enum action what) 1218 { 1219 int i; 1220 1221 partitions = 4; 1222 1345 #if ENABLE_FEATURE_SUN_LABEL || ENABLE_FEATURE_FDISK_WRITABLE 1346 static int get_boot(enum action what) 1347 #else 1348 static int get_boot(void) 1349 #define get_boot(what) get_boot() 1350 #endif 1351 { 1352 int i, fd; 1353 1354 g_partitions = 4; 1223 1355 for (i = 0; i < 4; i++) { 1224 1356 struct pte *pe = &ptes[i]; 1225 1226 1357 pe->part_table = pt_offset(MBRbuffer, i); 1227 1358 pe->ext_pointer = NULL; 1228 pe->offset = 0;1359 pe->offset_from_dev_start = 0; 1229 1360 pe->sectorbuffer = MBRbuffer; 1230 1361 #if ENABLE_FEATURE_FDISK_WRITABLE 1231 pe->changed = (what == create_empty_dos); 1232 #endif 1233 } 1234 1235 #if ENABLE_FEATURE_SUN_LABEL 1236 if (what == create_empty_sun && check_sun_label()) 1237 return 0; 1238 #endif 1239 1240 memset(MBRbuffer, 0, 512); 1362 pe->changed = (what == CREATE_EMPTY_DOS); 1363 #endif 1364 } 1241 1365 1242 1366 #if ENABLE_FEATURE_FDISK_WRITABLE 1243 if (what == create_empty_dos) 1244 goto got_dos_table; /* skip reading disk */ 1245 1246 fd = open(disk_device, type_open); 1367 // ALERT! highly idiotic design! 1368 // We end up here when we call get_boot() recursively 1369 // via get_boot() [table is bad] -> create_doslabel() -> get_boot(CREATE_EMPTY_DOS). 1370 // or get_boot() [table is bad] -> create_sunlabel() -> get_boot(CREATE_EMPTY_SUN). 1371 // (just factor out re-init of ptes[0,1,2,3] in a separate fn instead?) 1372 // So skip opening device _again_... 1373 if (what == CREATE_EMPTY_DOS IF_FEATURE_SUN_LABEL(|| what == CREATE_EMPTY_SUN)) 1374 goto created_table; 1375 1376 fd = open(disk_device, (option_mask32 & OPT_l) ? O_RDONLY : O_RDWR); 1377 1247 1378 if (fd < 0) { 1248 1379 fd = open(disk_device, O_RDONLY); 1249 1380 if (fd < 0) { 1250 if (what == try_only)1381 if (what == TRY_ONLY) 1251 1382 return 1; 1252 1383 fdisk_fatal(unable_to_open); 1253 } else1254 printf("You will not be able to write "1255 "the partition table\n");1256 }1257 1258 if (512 != read(fd, MBRbuffer, 512)) {1259 if (what == try_only)1384 } 1385 printf("'%s' is opened for read only\n", disk_device); 1386 } 1387 xmove_fd(fd, dev_fd); 1388 if (512 != full_read(dev_fd, MBRbuffer, 512)) { 1389 if (what == TRY_ONLY) { 1390 close_dev_fd(); 1260 1391 return 1; 1392 } 1261 1393 fdisk_fatal(unable_to_read); 1262 1394 } … … 1265 1397 if (fd < 0) 1266 1398 return 1; 1267 if (512 != read(fd, MBRbuffer, 512)) 1399 if (512 != full_read(fd, MBRbuffer, 512)) { 1400 close(fd); 1268 1401 return 1; 1402 } 1403 xmove_fd(fd, dev_fd); 1269 1404 #endif 1270 1405 1271 1406 get_geometry(); 1272 1273 1407 update_units(); 1274 1408 … … 1277 1411 return 0; 1278 1412 #endif 1279 1280 1413 #if ENABLE_FEATURE_SGI_LABEL 1281 1414 if (check_sgi_label()) 1282 1415 return 0; 1283 1416 #endif 1284 1285 1417 #if ENABLE_FEATURE_AIX_LABEL 1286 1418 if (check_aix_label()) 1287 1419 return 0; 1288 1420 #endif 1289 1421 #if ENABLE_FEATURE_GPT_LABEL 1422 if (check_gpt_label()) 1423 return 0; 1424 #endif 1290 1425 #if ENABLE_FEATURE_OSF_LABEL 1291 1426 if (check_osf_label()) { 1292 1427 possibly_osf_label = 1; 1293 1428 if (!valid_part_table_flag(MBRbuffer)) { 1294 current_label_type = label_osf;1429 current_label_type = LABEL_OSF; 1295 1430 return 0; 1296 1431 } … … 1300 1435 #endif 1301 1436 1302 #if ENABLE_FEATURE_FDISK_WRITABLE1303 got_dos_table:1304 #endif1305 1306 if (!valid_part_table_flag(MBRbuffer)) {1307 1437 #if !ENABLE_FEATURE_FDISK_WRITABLE 1438 if (!valid_part_table_flag(MBRbuffer)) 1308 1439 return -1; 1309 1440 #else 1310 switch (what) {1311 case fdisk:1441 if (!valid_part_table_flag(MBRbuffer)) { 1442 if (what == OPEN_MAIN) { 1312 1443 printf("Device contains neither a valid DOS " 1313 "partition table, nor Sun, SGI or OSF"1444 "partition table, nor Sun, SGI, OSF or GPT " 1314 1445 "disklabel\n"); 1315 1446 #ifdef __sparc__ 1316 #if ENABLE_FEATURE_SUN_LABEL 1317 create_sunlabel(); 1318 #endif 1447 IF_FEATURE_SUN_LABEL(create_sunlabel();) 1319 1448 #else 1320 1449 create_doslabel(); 1321 1450 #endif 1322 1451 return 0; 1323 case try_only: 1324 return -1; 1325 case create_empty_dos: 1326 #if ENABLE_FEATURE_SUN_LABEL 1327 case create_empty_sun: 1328 #endif 1329 break; 1330 default: 1331 bb_error_msg_and_die("internal error"); 1332 } 1452 } 1453 /* TRY_ONLY: */ 1454 return -1; 1455 } 1456 created_table: 1333 1457 #endif /* FEATURE_FDISK_WRITABLE */ 1334 } 1335 1336 #if ENABLE_FEATURE_FDISK_WRITABLE 1337 warn_cylinders(); 1338 #endif 1458 1459 1460 IF_FEATURE_FDISK_WRITABLE(warn_cylinders();) 1339 1461 warn_geometry(); 1340 1462 1341 1463 for (i = 0; i < 4; i++) { 1342 struct pte *pe = &ptes[i]; 1343 1344 if (IS_EXTENDED(pe->part_table->sys_ind)) { 1345 if (partitions != 4) 1464 if (IS_EXTENDED(ptes[i].part_table->sys_ind)) { 1465 if (g_partitions != 4) 1346 1466 printf("Ignoring extra extended " 1347 "partition % d\n", i + 1);1467 "partition %u\n", i + 1); 1348 1468 else 1349 1469 read_extended(i); … … 1351 1471 } 1352 1472 1353 for (i = 3; i < partitions; i++) {1473 for (i = 3; i < g_partitions; i++) { 1354 1474 struct pte *pe = &ptes[i]; 1355 1356 1475 if (!valid_part_table_flag(pe->sectorbuffer)) { 1357 1476 printf("Warning: invalid flag 0x%02x,0x%02x of partition " 1358 "table % dwill be corrected by w(rite)\n",1477 "table %u will be corrected by w(rite)\n", 1359 1478 pe->sectorbuffer[510], 1360 1479 pe->sectorbuffer[511], 1361 1480 i + 1); 1362 #if ENABLE_FEATURE_FDISK_WRITABLE 1363 pe->changed = 1; 1364 #endif 1481 IF_FEATURE_FDISK_WRITABLE(pe->changed = 1;) 1365 1482 } 1366 1483 } … … 1377 1494 * There is no default if DFLT is not between LOW and HIGH. 1378 1495 */ 1379 static unsigned1380 read_int( unsigned low, unsigned dflt, unsigned high, unsignedbase, const char *mesg)1381 { 1382 unsigned i;1496 static sector_t 1497 read_int(sector_t low, sector_t dflt, sector_t high, sector_t base, const char *mesg) 1498 { 1499 sector_t value; 1383 1500 int default_ok = 1; 1384 1501 const char *fmt = "%s (%u-%u, default %u): "; … … 1403 1520 int absolute = 0; 1404 1521 1405 i = atoi(line_ptr + 1); 1406 1522 value = atoi(line_ptr + 1); 1523 1524 /* (1) if 2nd char is digit, use_default = 0. 1525 * (2) move line_ptr to first non-digit. */ 1407 1526 while (isdigit(*++line_ptr)) 1408 1527 use_default = 0; … … 1412 1531 case 'C': 1413 1532 if (!display_in_cyl_units) 1414 i *= heads *sectors;1533 value *= g_heads * g_sectors; 1415 1534 break; 1416 1535 case 'K': … … 1435 1554 unsigned long unit; 1436 1555 1437 bytes = (ullong) i* absolute;1556 bytes = (ullong) value * absolute; 1438 1557 unit = sector_size * units_per_sector; 1439 1558 bytes += unit/2; /* round */ 1440 1559 bytes /= unit; 1441 i= bytes;1560 value = bytes; 1442 1561 } 1443 1562 if (minus) 1444 i = -i;1445 i+= base;1563 value = -value; 1564 value += base; 1446 1565 } else { 1447 i= atoi(line_ptr);1566 value = atoi(line_ptr); 1448 1567 while (isdigit(*line_ptr)) { 1449 1568 line_ptr++; … … 1452 1571 } 1453 1572 if (use_default) { 1454 i= dflt;1455 printf("Using default value %u\n", i);1456 } 1457 if ( i >= low && i<= high)1573 value = dflt; 1574 printf("Using default value %u\n", value); 1575 } 1576 if (value >= low && value <= high) 1458 1577 break; 1459 1578 printf("Value is out of range\n"); 1460 1579 } 1461 return i;1462 } 1463 1464 static int1465 get_partition(int warn, intmax)1580 return value; 1581 } 1582 1583 static unsigned 1584 get_partition(int warn, unsigned max) 1466 1585 { 1467 1586 struct pte *pe; 1468 inti;1587 unsigned i; 1469 1588 1470 1589 i = read_int(1, 0, max, 0, "Partition number") - 1; … … 1476 1595 || (LABEL_IS_SGI && !sgi_get_num_sectors(i)) 1477 1596 ) { 1478 printf("Warning: partition % dhas empty type\n", i+1);1597 printf("Warning: partition %u has empty type\n", i+1); 1479 1598 } 1480 1599 } … … 1483 1602 1484 1603 static int 1485 get_existing_partition(int warn, intmax)1604 get_existing_partition(int warn, unsigned max) 1486 1605 { 1487 1606 int pno = -1; 1488 inti;1607 unsigned i; 1489 1608 1490 1609 for (i = 0; i < max; i++) { … … 1499 1618 } 1500 1619 if (pno >= 0) { 1501 printf("Selected partition % d\n", pno+1);1620 printf("Selected partition %u\n", pno+1); 1502 1621 return pno; 1503 1622 } … … 1510 1629 1511 1630 static int 1512 get_nonexisting_partition(int warn, intmax)1631 get_nonexisting_partition(int warn, unsigned max) 1513 1632 { 1514 1633 int pno = -1; 1515 inti;1634 unsigned i; 1516 1635 1517 1636 for (i = 0; i < max; i++) { … … 1526 1645 } 1527 1646 if (pno >= 0) { 1528 printf("Selected partition % d\n", pno+1);1647 printf("Selected partition %u\n", pno+1); 1529 1648 return pno; 1530 1649 } … … 1553 1672 1554 1673 if (IS_EXTENDED(p->sys_ind) && !p->boot_ind) 1555 printf("WARNING: Partition % dis an extended partition\n", i + 1);1674 printf("WARNING: Partition %u is an extended partition\n", i + 1); 1556 1675 p->boot_ind = (p->boot_ind ? 0 : ACTIVE_FLAG); 1557 1676 pe->changed = 1; … … 1561 1680 toggle_dos_compatibility_flag(void) 1562 1681 { 1563 dos_compatible_flag = ~dos_compatible_flag;1682 dos_compatible_flag = 1 - dos_compatible_flag; 1564 1683 if (dos_compatible_flag) { 1565 sector_offset = sectors;1684 sector_offset = g_sectors; 1566 1685 printf("DOS Compatibility flag is set\n"); 1567 1686 } else { … … 1597 1716 if (i < 4) { 1598 1717 if (IS_EXTENDED(p->sys_ind) && i == ext_index) { 1599 partitions = 4;1718 g_partitions = 4; 1600 1719 ptes[ext_index].ext_pointer = NULL; 1601 1720 extended_offset = 0; … … 1607 1726 if (!q->sys_ind && i > 4) { 1608 1727 /* the last one in the chain - just delete */ 1609 -- partitions;1728 --g_partitions; 1610 1729 --i; 1611 1730 clear_partition(ptes[i].ext_pointer); … … 1620 1739 set_nr_sects(p, get_nr_sects(q)); 1621 1740 ptes[i-1].changed = 1; 1622 } else if ( partitions > 5) { /* 5 will be moved to 4 */1741 } else if (g_partitions > 5) { /* 5 will be moved to 4 */ 1623 1742 /* the first logical in a longer chain */ 1624 1743 pe = &ptes[5]; … … 1626 1745 if (pe->part_table) /* prevent SEGFAULT */ 1627 1746 set_start_sect(pe->part_table, 1628 get_partition_start(pe) -1629 1630 pe->offset = extended_offset;1747 get_partition_start_from_dev_start(pe) - 1748 extended_offset); 1749 pe->offset_from_dev_start = extended_offset; 1631 1750 pe->changed = 1; 1632 1751 } 1633 1752 1634 if ( partitions > 5) {1635 partitions--;1636 while (i < partitions) {1753 if (g_partitions > 5) { 1754 g_partitions--; 1755 while (i < g_partitions) { 1637 1756 ptes[i] = ptes[i+1]; 1638 1757 i++; 1639 1758 } 1640 } else 1759 } else { 1641 1760 /* the only logical: clear only */ 1642 1761 clear_partition(ptes[i].part_table); 1762 } 1643 1763 } 1644 1764 } … … 1654 1774 only works for Linux like partition tables. */ 1655 1775 if (!LABEL_IS_SGI) { 1656 i = get_existing_partition(0, partitions);1776 i = get_existing_partition(0, g_partitions); 1657 1777 } else { 1658 i = get_partition(0, partitions);1778 i = get_partition(0, g_partitions); 1659 1779 } 1660 1780 if (i == -1) … … 1666 1786 the reverse change must be allowed, too */ 1667 1787 if (!sys && !LABEL_IS_SGI && !LABEL_IS_SUN && !get_nr_sects(p)) { 1668 printf("Partition % ddoes not exist yet!\n", i + 1);1788 printf("Partition %u does not exist yet!\n", i + 1); 1669 1789 return; 1670 1790 } … … 1717 1837 p->sys_ind = sys; 1718 1838 1719 printf("Changed system type of partition % d"1839 printf("Changed system type of partition %u " 1720 1840 "to %x (%s)\n", i + 1, sys, 1721 1841 partition_type(sys)); 1722 1842 ptes[i].changed = 1; 1723 if (is_dos_partition(origsys) || 1724 is_dos_partition(sys)) 1725 dos_changed = 1; 1843 //if (is_dos_partition(origsys) || is_dos_partition(sys)) 1844 // dos_changed = 1; 1726 1845 break; 1727 1846 } … … 1739 1858 linear2chs(unsigned ls, unsigned *c, unsigned *h, unsigned *s) 1740 1859 { 1741 int spc = heads *sectors;1860 int spc = g_heads * g_sectors; 1742 1861 1743 1862 *c = ls / spc; 1744 1863 ls = ls % spc; 1745 *h = ls / sectors;1746 *s = ls % sectors + 1; /* sectors count from 1 */1864 *h = ls / g_sectors; 1865 *s = ls % g_sectors + 1; /* sectors count from 1 */ 1747 1866 } 1748 1867 … … 1755 1874 unsigned lec, leh, les; /* logical ending c, h, s */ 1756 1875 1757 if (! heads || !sectors || (partition >= 4))1876 if (!g_heads || !g_sectors || (partition >= 4)) 1758 1877 return; /* do not check extended partitions */ 1759 1878 … … 1775 1894 1776 1895 /* Same physical / logical beginning? */ 1777 if ( cylinders <= 1024 && (pbc != lbc || pbh != lbh || pbs != lbs)) {1778 printf("Partition % dhas different physical/logical "1896 if (g_cylinders <= 1024 && (pbc != lbc || pbh != lbh || pbs != lbs)) { 1897 printf("Partition %u has different physical/logical " 1779 1898 "beginnings (non-Linux?):\n", partition + 1); 1780 printf(" phys=(% d, %d, %d) ", pbc, pbh, pbs);1781 printf("logical=(% d, %d, %d)\n",lbc, lbh, lbs);1899 printf(" phys=(%u, %u, %u) ", pbc, pbh, pbs); 1900 printf("logical=(%u, %u, %u)\n", lbc, lbh, lbs); 1782 1901 } 1783 1902 1784 1903 /* Same physical / logical ending? */ 1785 if ( cylinders <= 1024 && (pec != lec || peh != leh || pes != les)) {1786 printf("Partition % dhas different physical/logical "1904 if (g_cylinders <= 1024 && (pec != lec || peh != leh || pes != les)) { 1905 printf("Partition %u has different physical/logical " 1787 1906 "endings:\n", partition + 1); 1788 printf(" phys=(% d, %d, %d) ", pec, peh, pes);1789 printf("logical=(% d, %d, %d)\n", lec, leh, les);1907 printf(" phys=(%u, %u, %u) ", pec, peh, pes); 1908 printf("logical=(%u, %u, %u)\n", lec, leh, les); 1790 1909 } 1791 1910 1792 1911 /* Ending on cylinder boundary? */ 1793 if (peh != ( heads - 1) || pes !=sectors) {1794 printf("Partition % idoes not end on cylinder boundary\n",1912 if (peh != (g_heads - 1) || pes != g_sectors) { 1913 printf("Partition %u does not end on cylinder boundary\n", 1795 1914 partition + 1); 1796 1915 } … … 1800 1919 list_disk_geometry(void) 1801 1920 { 1802 long long bytes = (total_number_of_sectors << 9);1803 long megabytes = bytes /1000000;1921 ullong bytes = ((ullong)total_number_of_sectors << 9); 1922 long megabytes = bytes / 1000000; 1804 1923 1805 1924 if (megabytes < 10000) 1806 printf("\nDisk %s: %l d MB, %lldbytes\n",1807 1925 printf("\nDisk %s: %lu MB, %llu bytes\n", 1926 disk_device, megabytes, bytes); 1808 1927 else 1809 printf("\nDisk %s: %l d.%ld GB, %lldbytes\n",1810 1811 printf("% d heads, %d sectors/track, %dcylinders",1812 heads, sectors,cylinders);1928 printf("\nDisk %s: %lu.%lu GB, %llu bytes\n", 1929 disk_device, megabytes/1000, (megabytes/100)%10, bytes); 1930 printf("%u heads, %u sectors/track, %u cylinders", 1931 g_heads, g_sectors, g_cylinders); 1813 1932 if (units_per_sector == 1) 1814 printf(", total % llu sectors",1815 1816 printf("\nUnits = %s of % d * %d = %dbytes\n\n",1817 1818 1933 printf(", total %"SECT_FMT"u sectors", 1934 total_number_of_sectors / (sector_size/512)); 1935 printf("\nUnits = %s of %u * %u = %u bytes\n\n", 1936 str_units(PLURAL), 1937 units_per_sector, sector_size, units_per_sector * sector_size); 1819 1938 } 1820 1939 … … 1829 1948 const struct pte *pe; 1830 1949 const struct partition *p; 1831 ullonglast_p_start_pos = 0, p_start_pos;1832 inti, last_i = 0;1833 1834 for (i = 0; i < partitions; i++) {1950 sector_t last_p_start_pos = 0, p_start_pos; 1951 unsigned i, last_i = 0; 1952 1953 for (i = 0; i < g_partitions; i++) { 1835 1954 if (i == 4) { 1836 1955 last_i = 4; … … 1838 1957 } 1839 1958 pe = &ptes[i]; 1840 if ((p = pe->part_table)->sys_ind) { 1841 p_start_pos = get_partition_start(pe); 1959 p = pe->part_table; 1960 if (p->sys_ind) { 1961 p_start_pos = get_partition_start_from_dev_start(pe); 1842 1962 1843 1963 if (last_p_start_pos > p_start_pos) { … … 1877 1997 /* (Its sector is the global extended_offset.) */ 1878 1998 stage1: 1879 for (j = 5; j < partitions-1; j++) {1880 oj = ptes[j].offset ;1881 ojj = ptes[j+1].offset ;1999 for (j = 5; j < g_partitions - 1; j++) { 2000 oj = ptes[j].offset_from_dev_start; 2001 ojj = ptes[j+1].offset_from_dev_start; 1882 2002 if (oj > ojj) { 1883 ptes[j].offset = ojj;1884 ptes[j+1].offset = oj;2003 ptes[j].offset_from_dev_start = ojj; 2004 ptes[j+1].offset_from_dev_start = oj; 1885 2005 pj = ptes[j].part_table; 1886 2006 set_start_sect(pj, get_start_sect(pj)+oj-ojj); … … 1897 2017 /* Stage 2: sort starting sectors */ 1898 2018 stage2: 1899 for (j = 4; j < partitions-1; j++) {2019 for (j = 4; j < g_partitions - 1; j++) { 1900 2020 pj = ptes[j].part_table; 1901 2021 pjj = ptes[j+1].part_table; 1902 2022 sj = get_start_sect(pj); 1903 2023 sjj = get_start_sect(pjj); 1904 oj = ptes[j].offset ;1905 ojj = ptes[j+1].offset ;2024 oj = ptes[j].offset_from_dev_start; 2025 ojj = ptes[j+1].offset_from_dev_start; 1906 2026 if (oj+sj > ojj+sjj) { 1907 2027 tmp = *pj; … … 1915 2035 1916 2036 /* Probably something was changed */ 1917 for (j = 4; j < partitions; j++)2037 for (j = 4; j < g_partitions; j++) 1918 2038 ptes[j].changed = 1; 1919 2039 } … … 1956 2076 1957 2077 printf("Done.\n"); 1958 1959 2078 } 1960 2079 #endif … … 1970 2089 return; 1971 2090 } 1972 if (LABEL_IS_S UN) {2091 if (LABEL_IS_SGI) { 1973 2092 sgi_list_table(xtra); 2093 return; 2094 } 2095 if (LABEL_IS_GPT) { 2096 gpt_list_table(xtra); 1974 2097 return; 1975 2098 } … … 1995 2118 w+1, "Device"); 1996 2119 1997 for (i = 0; i < partitions; i++) {2120 for (i = 0; i < g_partitions; i++) { 1998 2121 const struct pte *pe = &ptes[i]; 1999 ullongpsects;2000 ullongpblocks;2122 sector_t psects; 2123 sector_t pblocks; 2001 2124 unsigned podd; 2002 2125 … … 2016 2139 pblocks *= (sector_size / 1024); 2017 2140 2018 printf("%s %c %11 llu %11llu %11llu%c %2x %s\n",2141 printf("%s %c %11"SECT_FMT"u %11"SECT_FMT"u %11"SECT_FMT"u%c %2x %s\n", 2019 2142 partname(disk_device, i+1, w+2), 2020 2143 !p->boot_ind ? ' ' : p->boot_ind == ACTIVE_FLAG /* boot flag */ 2021 2144 ? '*' : '?', 2022 (ullong) cround(get_partition_start(pe)), /* start */2023 (ullong) cround(get_partition_start(pe) + psects /* end */2145 cround(get_partition_start_from_dev_start(pe)), /* start */ 2146 cround(get_partition_start_from_dev_start(pe) + psects /* end */ 2024 2147 - (psects ? 1 : 0)), 2025 (ullong)pblocks, podd ? '+' : ' ', /* odd flag on end */2148 pblocks, podd ? '+' : ' ', /* odd flag on end */ 2026 2149 p->sys_ind, /* type id */ 2027 2150 partition_type(p->sys_ind)); /* type name */ … … 2031 2154 2032 2155 /* Is partition table in disk order? It need not be, but... */ 2033 /* partition table entries are not checked for correct order if this2034 2156 /* partition table entries are not checked for correct order 2157 * if this is a sgi, sun or aix labeled disk... */ 2035 2158 if (LABEL_IS_DOS && wrong_p_order(NULL)) { 2036 2159 /* FIXME */ … … 2047 2170 int i; 2048 2171 2049 printf("\nDisk %s: % d heads, %d sectors, %dcylinders\n\n",2050 disk_device, heads, sectors,cylinders);2172 printf("\nDisk %s: %u heads, %u sectors, %u cylinders\n\n", 2173 disk_device, g_heads, g_sectors, g_cylinders); 2051 2174 printf("Nr AF Hd Sec Cyl Hd Sec Cyl Start Size ID\n"); 2052 for (i = 0; i < partitions; i++) {2175 for (i = 0; i < g_partitions; i++) { 2053 2176 pe = &ptes[i]; 2054 2177 p = (extend ? pe->ext_pointer : pe->part_table); 2055 2178 if (p != NULL) { 2056 printf("%2 d %02x%4d%4d%5d%4d%4d%5d%11u%11u %02x\n",2179 printf("%2u %02x%4u%4u%5u%4u%4u%5u%11"SECT_FMT"u%11"SECT_FMT"u %02x\n", 2057 2180 i + 1, p->boot_ind, p->head, 2058 2181 sector(p->sector), … … 2060 2183 sector(p->end_sector), 2061 2184 cylinder(p->end_sector, p->end_cyl), 2062 get_start_sect(p), get_nr_sects(p), p->sys_ind); 2185 get_start_sect(p), get_nr_sects(p), 2186 p->sys_ind); 2063 2187 if (p->sys_ind) 2064 2188 check_consistency(p, i); … … 2070 2194 #if ENABLE_FEATURE_FDISK_WRITABLE 2071 2195 static void 2072 fill_bounds( ullong *first, ullong*last)2073 { 2074 inti;2196 fill_bounds(sector_t *first, sector_t *last) 2197 { 2198 unsigned i; 2075 2199 const struct pte *pe = &ptes[0]; 2076 2200 const struct partition *p; 2077 2201 2078 for (i = 0; i < partitions; pe++,i++) {2202 for (i = 0; i < g_partitions; pe++,i++) { 2079 2203 p = pe->part_table; 2080 2204 if (!p->sys_ind || IS_EXTENDED(p->sys_ind)) { … … 2082 2206 last[i] = 0; 2083 2207 } else { 2084 first[i] = get_partition_start (pe);2208 first[i] = get_partition_start_from_dev_start(pe); 2085 2209 last[i] = first[i] + get_nr_sects(p) - 1; 2086 2210 } … … 2089 2213 2090 2214 static void 2091 check(int n, unsigned h, unsigned s, unsigned c, ullongstart)2092 { 2093 ullongtotal, real_s, real_c;2215 check(int n, unsigned h, unsigned s, unsigned c, sector_t start) 2216 { 2217 sector_t total, real_s, real_c; 2094 2218 2095 2219 real_s = sector(s) - 1; 2096 2220 real_c = cylinder(s, c); 2097 total = (real_c * sectors + real_s) *heads + h;2221 total = (real_c * g_sectors + real_s) * g_heads + h; 2098 2222 if (!total) 2099 printf("Partition % dcontains sector 0\n", n);2100 if (h >= heads)2101 printf("Partition % d: head %d greater than maximum %d\n",2102 n, h + 1, heads);2103 if (real_s >= sectors)2104 printf("Partition % d: sector %dgreater than "2105 "maximum % d\n", n, s,sectors);2106 if (real_c >= cylinders)2107 printf("Partition % d: cylinder %llu greater than "2108 "maximum % d\n", n, real_c + 1,cylinders);2109 if ( cylinders <= 1024 && start != total)2110 printf("Partition % d: previous sectors %llu disagrees with "2111 "total % llu\n", n, start, total);2223 printf("Partition %u contains sector 0\n", n); 2224 if (h >= g_heads) 2225 printf("Partition %u: head %u greater than maximum %u\n", 2226 n, h + 1, g_heads); 2227 if (real_s >= g_sectors) 2228 printf("Partition %u: sector %u greater than " 2229 "maximum %u\n", n, s, g_sectors); 2230 if (real_c >= g_cylinders) 2231 printf("Partition %u: cylinder %"SECT_FMT"u greater than " 2232 "maximum %u\n", n, real_c + 1, g_cylinders); 2233 if (g_cylinders <= 1024 && start != total) 2234 printf("Partition %u: previous sectors %"SECT_FMT"u disagrees with " 2235 "total %"SECT_FMT"u\n", n, start, total); 2112 2236 } 2113 2237 … … 2116 2240 { 2117 2241 int i, j; 2118 unsignedtotal = 1;2119 ullong first[partitions], last[partitions];2242 sector_t total = 1; 2243 sector_t first[g_partitions], last[g_partitions]; 2120 2244 struct partition *p; 2121 2245 … … 2133 2257 2134 2258 fill_bounds(first, last); 2135 for (i = 0; i < partitions; i++) {2259 for (i = 0; i < g_partitions; i++) { 2136 2260 struct pte *pe = &ptes[i]; 2137 2261 … … 2139 2263 if (p->sys_ind && !IS_EXTENDED(p->sys_ind)) { 2140 2264 check_consistency(p, i); 2141 if (get_partition_start (pe) < first[i])2265 if (get_partition_start_from_dev_start(pe) < first[i]) 2142 2266 printf("Warning: bad start-of-data in " 2143 "partition % d\n", i + 1);2267 "partition %u\n", i + 1); 2144 2268 check(i + 1, p->end_head, p->end_sector, p->end_cyl, 2145 2269 last[i]); … … 2148 2272 if ((first[i] >= first[j] && first[i] <= last[j]) 2149 2273 || ((last[i] <= last[j] && last[i] >= first[j]))) { 2150 printf("Warning: partition % doverlaps "2151 "partition % d\n", j + 1, i + 1);2274 printf("Warning: partition %u overlaps " 2275 "partition %u\n", j + 1, i + 1); 2152 2276 total += first[i] >= first[j] ? 2153 2277 first[i] : first[j]; … … 2161 2285 if (extended_offset) { 2162 2286 struct pte *pex = &ptes[ext_index]; 2163 ullonge_last = get_start_sect(pex->part_table) +2287 sector_t e_last = get_start_sect(pex->part_table) + 2164 2288 get_nr_sects(pex->part_table) - 1; 2165 2289 2166 for (i = 4; i < partitions; i++) {2290 for (i = 4; i < g_partitions; i++) { 2167 2291 total++; 2168 2292 p = ptes[i].part_table; 2169 2293 if (!p->sys_ind) { 2170 if (i != 4 || i + 1 < partitions)2171 printf("Warning: partition % d"2294 if (i != 4 || i + 1 < g_partitions) 2295 printf("Warning: partition %u " 2172 2296 "is empty\n", i + 1); 2173 2297 } else if (first[i] < extended_offset || last[i] > e_last) { 2174 printf("Logical partition % dnot entirely in "2175 "partition % d\n", i + 1, ext_index + 1);2298 printf("Logical partition %u not entirely in " 2299 "partition %u\n", i + 1, ext_index + 1); 2176 2300 } 2177 2301 } 2178 2302 } 2179 2303 2180 if (total > heads * sectors *cylinders)2181 printf("Total allocated sectors % dgreater than the maximum "2182 "% d\n", total, heads * sectors *cylinders);2304 if (total > g_heads * g_sectors * g_cylinders) 2305 printf("Total allocated sectors %u greater than the maximum " 2306 "%u\n", total, g_heads * g_sectors * g_cylinders); 2183 2307 else { 2184 total = heads * sectors *cylinders - total;2308 total = g_heads * g_sectors * g_cylinders - total; 2185 2309 if (total != 0) 2186 printf("% dunallocated sectors\n", total);2310 printf("%"SECT_FMT"u unallocated sectors\n", total); 2187 2311 } 2188 2312 } … … 2195 2319 struct partition *p = ptes[n].part_table; 2196 2320 struct partition *q = ptes[ext_index].part_table; 2197 ullonglimit, temp;2198 ullongstart, stop = 0;2199 ullong first[partitions], last[partitions];2321 sector_t limit, temp; 2322 sector_t start, stop = 0; 2323 sector_t first[g_partitions], last[g_partitions]; 2200 2324 2201 2325 if (p && p->sys_ind) { … … 2207 2331 start = sector_offset; 2208 2332 if (display_in_cyl_units || !total_number_of_sectors) 2209 limit = ( ullong) heads * sectors *cylinders - 1;2333 limit = (sector_t) g_heads * g_sectors * g_cylinders - 1; 2210 2334 else 2211 2335 limit = total_number_of_sectors - 1; … … 2220 2344 } 2221 2345 if (display_in_cyl_units) 2222 for (i = 0; i < partitions; i++)2346 for (i = 0; i < g_partitions; i++) 2223 2347 first[i] = (cround(first[i]) - 1) * units_per_sector; 2224 2348 … … 2226 2350 do { 2227 2351 temp = start; 2228 for (i = 0; i < partitions; i++) {2352 for (i = 0; i < g_partitions; i++) { 2229 2353 int lastplusoff; 2230 2354 2231 if (start == ptes[i].offset )2355 if (start == ptes[i].offset_from_dev_start) 2232 2356 start += sector_offset; 2233 2357 lastplusoff = last[i] + ((n < 4) ? 0 : sector_offset); … … 2238 2362 break; 2239 2363 if (start >= temp+units_per_sector && num_read) { 2240 printf("Sector % lldis already allocated\n", temp);2364 printf("Sector %"SECT_FMT"u is already allocated\n", temp); 2241 2365 temp = start; 2242 2366 num_read = 0; 2243 2367 } 2244 2368 if (!num_read && start == temp) { 2245 ullongsaved_start;2369 sector_t saved_start; 2246 2370 2247 2371 saved_start = start; 2248 start = read_int(cround(saved_start), cround(saved_start), cround(limit), 2249 0, mesg); 2372 start = read_int(cround(saved_start), cround(saved_start), cround(limit), 0, mesg); 2250 2373 if (display_in_cyl_units) { 2251 2374 start = (start - 1) * units_per_sector; 2252 if (start < saved_start) start = saved_start; 2375 if (start < saved_start) 2376 start = saved_start; 2253 2377 } 2254 2378 num_read = 1; … … 2258 2382 struct pte *pe = &ptes[n]; 2259 2383 2260 pe->offset = start - sector_offset;2261 if (pe->offset == extended_offset) { /* must be corrected */2262 pe->offset ++;2384 pe->offset_from_dev_start = start - sector_offset; 2385 if (pe->offset_from_dev_start == extended_offset) { /* must be corrected */ 2386 pe->offset_from_dev_start++; 2263 2387 if (sector_offset == 1) 2264 2388 start++; … … 2266 2390 } 2267 2391 2268 for (i = 0; i < partitions; i++) {2392 for (i = 0; i < g_partitions; i++) { 2269 2393 struct pte *pe = &ptes[i]; 2270 2394 2271 if (start < pe->offset && limit >= pe->offset)2272 limit = pe->offset - 1;2395 if (start < pe->offset_from_dev_start && limit >= pe->offset_from_dev_start) 2396 limit = pe->offset_from_dev_start - 1; 2273 2397 if (start < first[i] && limit >= first[i]) 2274 2398 limit = first[i] - 1; … … 2277 2401 printf("No free sectors available\n"); 2278 2402 if (n > 4) 2279 partitions--;2403 g_partitions--; 2280 2404 return; 2281 2405 } … … 2286 2410 "Last %s or +size or +sizeM or +sizeK", 2287 2411 str_units(SINGULAR)); 2288 stop = read_int(cround(start), cround(limit), cround(limit), 2289 cround(start), mesg); 2412 stop = read_int(cround(start), cround(limit), cround(limit), cround(start), mesg); 2290 2413 if (display_in_cyl_units) { 2291 2414 stop = stop * units_per_sector - 1; … … 2297 2420 set_partition(n, 0, start, stop, sys); 2298 2421 if (n > 4) 2299 set_partition(n - 1, 1, ptes[n].offset , stop, EXTENDED);2422 set_partition(n - 1, 1, ptes[n].offset_from_dev_start, stop, EXTENDED); 2300 2423 2301 2424 if (IS_EXTENDED(sys)) { … … 2305 2428 ext_index = n; 2306 2429 pen->ext_pointer = p; 2307 pe4->offset = extended_offset = start;2430 pe4->offset_from_dev_start = extended_offset = start; 2308 2431 pe4->sectorbuffer = xzalloc(sector_size); 2309 2432 pe4->part_table = pt_offset(pe4->sectorbuffer, 0); 2310 2433 pe4->ext_pointer = pe4->part_table + 1; 2311 2434 pe4->changed = 1; 2312 partitions = 5;2435 g_partitions = 5; 2313 2436 } 2314 2437 } … … 2317 2440 add_logical(void) 2318 2441 { 2319 if ( partitions > 5 || ptes[4].part_table->sys_ind) {2320 struct pte *pe = &ptes[ partitions];2442 if (g_partitions > 5 || ptes[4].part_table->sys_ind) { 2443 struct pte *pe = &ptes[g_partitions]; 2321 2444 2322 2445 pe->sectorbuffer = xzalloc(sector_size); 2323 2446 pe->part_table = pt_offset(pe->sectorbuffer, 0); 2324 2447 pe->ext_pointer = pe->part_table + 1; 2325 pe->offset = 0;2448 pe->offset_from_dev_start = 0; 2326 2449 pe->changed = 1; 2327 partitions++;2328 } 2329 add_partition( partitions - 1, LINUX_NATIVE);2450 g_partitions++; 2451 } 2452 add_partition(g_partitions - 1, LINUX_NATIVE); 2330 2453 } 2331 2454 … … 2339 2462 2340 2463 if (LABEL_IS_SUN) { 2341 add_sun_partition(get_partition(0, partitions), LINUX_NATIVE);2464 add_sun_partition(get_partition(0, g_partitions), LINUX_NATIVE); 2342 2465 return; 2343 2466 } 2344 2467 if (LABEL_IS_SGI) { 2345 sgi_add_partition(get_partition(0, partitions), LINUX_NATIVE);2468 sgi_add_partition(get_partition(0, g_partitions), LINUX_NATIVE); 2346 2469 return; 2347 2470 } … … 2356 2479 free_primary += !ptes[i].part_table->sys_ind; 2357 2480 2358 if (!free_primary && partitions >= MAXIMUM_PARTS) {2481 if (!free_primary && g_partitions >= MAXIMUM_PARTS) { 2359 2482 printf("The maximum number of partitions has been created\n"); 2360 2483 return; … … 2377 2500 while (1) { 2378 2501 c = read_nonempty(line); 2379 if ( c == 'p' || c == 'P') {2502 if ((c | 0x20) == 'p') { 2380 2503 i = get_nonexisting_partition(0, 4); 2381 2504 if (i >= 0) … … 2408 2531 if (ptes[i].changed) 2409 2532 ptes[3].changed = 1; 2410 for (i = 3; i < partitions; i++) {2533 for (i = 3; i < g_partitions; i++) { 2411 2534 struct pte *pe = &ptes[i]; 2412 2535 2413 2536 if (pe->changed) { 2414 2537 write_part_table_flag(pe->sectorbuffer); 2415 write_sector(pe->offset , pe->sectorbuffer);2538 write_sector(pe->offset_from_dev_start, pe->sectorbuffer); 2416 2539 } 2417 2540 } … … 2443 2566 sync(); 2444 2567 /* sleep(2); Huh? */ 2445 i = ioctl_or_perror( fd, BLKRRPART, NULL,2568 i = ioctl_or_perror(dev_fd, BLKRRPART, NULL, 2446 2569 "WARNING: rereading partition table " 2447 2570 "failed, kernel still uses old table"); … … 2456 2579 if (leave) { 2457 2580 if (ENABLE_FEATURE_CLEAN_UP) 2458 close (fd);2581 close_dev_fd(); 2459 2582 exit(i != 0); 2460 2583 } … … 2474 2597 printf(" %02X", (unsigned char) pbuffer[i]); 2475 2598 if (l == MAX_PER_LINE - 1) { 2476 puts("");2599 bb_putchar('\n'); 2477 2600 l = -1; 2478 2601 } 2479 2602 } 2480 2603 if (l > 0) 2481 puts("");2482 puts("");2604 bb_putchar('\n'); 2605 bb_putchar('\n'); 2483 2606 } 2484 2607 … … 2492 2615 print_buffer(MBRbuffer); 2493 2616 else { 2494 for (i = 3; i < partitions; i++)2617 for (i = 3; i < g_partitions; i++) 2495 2618 print_buffer(ptes[i].sectorbuffer); 2496 2619 } … … 2498 2621 2499 2622 static void 2500 move_begin( inti)2623 move_begin(unsigned i) 2501 2624 { 2502 2625 struct pte *pe = &ptes[i]; 2503 2626 struct partition *p = pe->part_table; 2504 ullong new, first;2627 sector_t new, first, nr_sects; 2505 2628 2506 2629 if (warn_geometry()) 2507 2630 return; 2508 if (!p->sys_ind || !get_nr_sects(p) || IS_EXTENDED(p->sys_ind)) { 2509 printf("Partition %d has no data area\n", i + 1); 2631 nr_sects = get_nr_sects(p); 2632 if (!p->sys_ind || !nr_sects || IS_EXTENDED(p->sys_ind)) { 2633 printf("Partition %u has no data area\n", i + 1); 2510 2634 return; 2511 2635 } 2512 first = get_partition_start(pe); 2513 new = read_int(first, first, first + get_nr_sects(p) - 1, first, 2514 "New beginning of data") - pe->offset; 2515 2516 if (new != get_nr_sects(p)) { 2517 first = get_nr_sects(p) + get_start_sect(p) - new; 2518 set_nr_sects(p, first); 2519 set_start_sect(p, new); 2636 first = get_partition_start_from_dev_start(pe); /* == pe->offset_from_dev_start + get_start_sect(p) */ 2637 new = read_int(0 /*was:first*/, first, first + nr_sects - 1, first, "New beginning of data"); 2638 if (new != first) { 2639 sector_t new_relative = new - pe->offset_from_dev_start; 2640 nr_sects += (get_start_sect(p) - new_relative); 2641 set_start_sect(p, new_relative); 2642 set_nr_sects(p, nr_sects); 2643 read_nonempty("Recalculate C/H/S values? (Y/N): "); 2644 if ((line_ptr[0] | 0x20) == 'y') 2645 set_hsc_start_end(p, new, new + nr_sects - 1); 2520 2646 pe->changed = 1; 2521 2647 } … … 2528 2654 2529 2655 while (1) { 2530 putchar('\n');2531 c = tolower(read_nonempty("Expert command (m for help): "));2656 bb_putchar('\n'); 2657 c = 0x20 | read_nonempty("Expert command (m for help): "); 2532 2658 switch (c) { 2533 2659 case 'a': … … 2537 2663 case 'b': 2538 2664 if (LABEL_IS_DOS) 2539 move_begin(get_partition(0, partitions));2665 move_begin(get_partition(0, g_partitions)); 2540 2666 break; 2541 2667 case 'c': 2542 user_cylinders = cylinders =2543 read_int(1, cylinders, 1048576, 0,2668 user_cylinders = g_cylinders = 2669 read_int(1, g_cylinders, 1048576, 0, 2544 2670 "Number of cylinders"); 2545 2671 if (LABEL_IS_SUN) 2546 sun_set_ncyl( cylinders);2672 sun_set_ncyl(g_cylinders); 2547 2673 if (LABEL_IS_DOS) 2548 2674 warn_cylinders(); … … 2569 2695 break; 2570 2696 case 'h': 2571 user_heads = heads = read_int(1, heads, 256, 0, 2572 "Number of heads"); 2697 user_heads = g_heads = read_int(1, g_heads, 256, 0, "Number of heads"); 2573 2698 update_units(); 2574 2699 break; … … 2588 2713 break; 2589 2714 case 'q': 2590 close(fd); 2591 puts(""); 2592 exit(0); 2715 if (ENABLE_FEATURE_CLEAN_UP) 2716 close_dev_fd(); 2717 bb_putchar('\n'); 2718 exit(EXIT_SUCCESS); 2593 2719 case 'r': 2594 2720 return; 2595 2721 case 's': 2596 user_sectors = sectors = read_int(1, sectors, 63, 0, 2597 "Number of sectors"); 2722 user_sectors = g_sectors = read_int(1, g_sectors, 63, 0, "Number of sectors"); 2598 2723 if (dos_compatible_flag) { 2599 sector_offset = sectors;2724 sector_offset = g_sectors; 2600 2725 printf("Warning: setting sector offset for DOS " 2601 2726 "compatiblity\n"); … … 2639 2764 2640 2765 snprintf(buf, sizeof(buf), "/proc/ide/%s/media", device+5); 2641 procf = fopen (buf, "r");2766 procf = fopen_for_read(buf); 2642 2767 if (procf != NULL && fgets(buf, sizeof(buf), procf)) 2643 2768 is_ide = (!strncmp(buf, "cdrom", 5) || … … 2656 2781 2657 2782 static void 2658 trydev(const char *device, int user_specified)2783 open_list_and_close(const char *device, int user_specified) 2659 2784 { 2660 2785 int gb; … … 2666 2791 if (is_ide_cdrom_or_tape(device)) 2667 2792 return; 2668 fd = open(disk_device, type_open); 2669 if (fd >= 0) { 2670 gb = get_boot(try_only); 2671 if (gb > 0) { /* I/O error */ 2672 close(fd); 2673 } else if (gb < 0) { /* no DOS signature */ 2674 list_disk_geometry(); 2675 if (LABEL_IS_AIX) { 2676 return; 2677 } 2678 #if ENABLE_FEATURE_OSF_LABEL 2679 if (bsd_trydev(device) < 0) 2680 #endif 2681 printf("Disk %s doesn't contain a valid " 2682 "partition table\n", device); 2683 close(fd); 2684 } else { 2685 close(fd); 2686 list_table(0); 2687 #if ENABLE_FEATURE_FDISK_WRITABLE 2688 if (!LABEL_IS_SUN && partitions > 4){ 2689 delete_partition(ext_index); 2690 } 2691 #endif 2692 } 2693 } else { 2793 2794 /* Open disk_device, save file descriptor to dev_fd */ 2795 errno = 0; 2796 gb = get_boot(TRY_ONLY); 2797 if (gb > 0) { /* I/O error */ 2694 2798 /* Ignore other errors, since we try IDE 2695 2799 and SCSI hard disks which may not be 2696 2800 installed on the system. */ 2697 if (errno == EACCES) { 2698 printf("Cannot open %s\n", device); 2699 return; 2700 } 2701 } 2801 if (user_specified || errno == EACCES) 2802 bb_perror_msg("can't open '%s'", device); 2803 return; 2804 } 2805 2806 if (gb < 0) { /* no DOS signature */ 2807 list_disk_geometry(); 2808 if (LABEL_IS_AIX) 2809 goto ret; 2810 #if ENABLE_FEATURE_OSF_LABEL 2811 if (bsd_trydev(device) < 0) 2812 #endif 2813 printf("Disk %s doesn't contain a valid " 2814 "partition table\n", device); 2815 } else { 2816 list_table(0); 2817 #if ENABLE_FEATURE_FDISK_WRITABLE 2818 if (!LABEL_IS_SUN && g_partitions > 4) { 2819 delete_partition(ext_index); 2820 } 2821 #endif 2822 } 2823 ret: 2824 close_dev_fd(); 2702 2825 } 2703 2826 … … 2705 2828 that look like a partition name (do not end in a digit) */ 2706 2829 static void 2707 tryprocpt(void)2830 list_devs_in_proc_partititons(void) 2708 2831 { 2709 2832 FILE *procpt; … … 2714 2837 2715 2838 while (fgets(line, sizeof(line), procpt)) { 2716 if (sscanf(line, " % d %d %d%[^\n ]",2839 if (sscanf(line, " %u %u %u %[^\n ]", 2717 2840 &ma, &mi, &sz, ptname) != 4) 2718 2841 continue; 2719 for (s = ptname; *s; s++); 2720 if (isdigit(s[-1])) 2842 for (s = ptname; *s; s++) 2843 continue; 2844 /* note: excluding '0': e.g. mmcblk0 is not a partition name! */ 2845 if (s[-1] >= '1' && s[-1] <= '9') 2721 2846 continue; 2722 2847 sprintf(devname, "/dev/%s", ptname); 2723 trydev(devname, 0);2848 open_list_and_close(devname, 0); 2724 2849 } 2725 2850 #if ENABLE_FEATURE_CLEAN_UP … … 2736 2861 #endif 2737 2862 2738 int fdisk_main(int argc, char **argv); 2739 int fdisk_main(int argc, char **argv) 2740 { 2741 char *str_b, *str_C, *str_H, *str_S; 2863 int fdisk_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 2864 int fdisk_main(int argc UNUSED_PARAM, char **argv) 2865 { 2742 2866 unsigned opt; 2743 2867 /* … … 2749 2873 * Options -C, -H, -S set the geometry. 2750 2874 */ 2751 enum { 2752 OPT_b = 1 << 0, 2753 OPT_C = 1 << 1, 2754 OPT_H = 1 << 2, 2755 OPT_l = 1 << 3, 2756 OPT_S = 1 << 4, 2757 OPT_u = 1 << 5, 2758 OPT_s = (1 << 6) * ENABLE_FEATURE_FDISK_BLKSIZE, 2759 }; 2760 2761 PTR_TO_GLOBALS = xzalloc(sizeof(G)); 2762 2763 opt = getopt32(argv, "b:C:H:lS:u" USE_FEATURE_FDISK_BLKSIZE("s"), 2764 &str_b, &str_C, &str_H, &str_S); 2765 argc -= optind; 2875 INIT_G(); 2876 2877 close_dev_fd(); /* needed: fd 3 must not stay closed */ 2878 2879 opt_complementary = "b+:C+:H+:S+"; /* numeric params */ 2880 opt = getopt32(argv, "b:C:H:lS:u" IF_FEATURE_FDISK_BLKSIZE("s"), 2881 §or_size, &user_cylinders, &user_heads, &user_sectors); 2766 2882 argv += optind; 2767 if (opt & OPT_b) { // -b2883 if (opt & OPT_b) { 2768 2884 /* Ugly: this sector size is really per device, 2769 so cannot be combined with multiple disks, 2770 and the same goes for the C/H/S options. 2771 */ 2772 sector_size = xatoi_u(str_b); 2773 if (sector_size != 512 && sector_size != 1024 && 2774 sector_size != 2048) 2885 * so cannot be combined with multiple disks, 2886 * and the same goes for the C/H/S options. 2887 */ 2888 if (sector_size < 512 2889 || sector_size > 0x10000 2890 || (sector_size & (sector_size-1)) /* not power of 2 */ 2891 ) { 2775 2892 bb_show_usage(); 2893 } 2776 2894 sector_offset = 2; 2777 2895 user_set_sector_size = 1; 2778 2896 } 2779 if (opt & OPT_C) user_cylinders = xatoi_u(str_C); // -C 2780 if (opt & OPT_H) { // -H 2781 user_heads = xatoi_u(str_H); 2782 if (user_heads <= 0 || user_heads >= 256) 2783 user_heads = 0; 2784 } 2785 //if (opt & OPT_l) // -l 2786 if (opt & OPT_S) { // -S 2787 user_sectors = xatoi_u(str_S); 2788 if (user_sectors <= 0 || user_sectors >= 64) 2789 user_sectors = 0; 2790 } 2791 if (opt & OPT_u) display_in_cyl_units = 0; // -u 2792 //if (opt & OPT_s) // -s 2793 2794 if (user_set_sector_size && argc != 1) 2795 printf("Warning: the -b (set sector size) option should" 2796 " be used with one specified device\n"); 2897 if (user_heads <= 0 || user_heads >= 256) 2898 user_heads = 0; 2899 if (user_sectors <= 0 || user_sectors >= 64) 2900 user_sectors = 0; 2901 if (opt & OPT_u) 2902 display_in_cyl_units = 0; // -u 2797 2903 2798 2904 #if ENABLE_FEATURE_FDISK_WRITABLE … … 2800 2906 nowarn = 1; 2801 2907 #endif 2802 type_open = O_RDONLY; 2803 if (argc > 0) { 2804 int k; 2805 #if defined(__GNUC__) 2806 /* avoid gcc warning: 2807 variable `k' might be clobbered by `longjmp' */ 2808 (void)&k; 2809 #endif 2908 if (*argv) { 2810 2909 listing = 1; 2811 for (k = 0; k < argc; k++) 2812 trydev(argv[k], 1); 2910 do { 2911 open_list_and_close(*argv, 1); 2912 } while (*++argv); 2813 2913 } else { 2814 /* we no longer have default device names*/2815 /* but, we canuse /proc/partitions instead */2816 tryprocpt();2914 /* we don't have device names, */ 2915 /* use /proc/partitions instead */ 2916 list_devs_in_proc_partititons(); 2817 2917 } 2818 2918 return 0; … … 2823 2923 #if ENABLE_FEATURE_FDISK_BLKSIZE 2824 2924 if (opt & OPT_s) { 2825 long size;2826 2925 int j; 2827 2926 2828 2927 nowarn = 1; 2829 type_open = O_RDONLY; 2830 2831 if (argc <= 0) 2928 if (!argv[0]) 2832 2929 bb_show_usage(); 2833 2834 for (j = 0; j < argc; j++) { 2835 disk_device = argv[j]; 2836 fd = open(disk_device, type_open); 2837 if (fd < 0) 2838 fdisk_fatal(unable_to_open); 2839 if (ioctl(fd, BLKGETSIZE, &size)) 2840 fdisk_fatal(ioctl_error); 2930 for (j = 0; argv[j]; j++) { 2931 unsigned long long size; 2932 fd = xopen(argv[j], O_RDONLY); 2933 size = bb_BLKGETSIZE_sectors(fd) / 2; 2841 2934 close(fd); 2842 if (arg c == 1)2843 printf("%l d\n", size/2);2935 if (argv[1]) 2936 printf("%llu\n", size); 2844 2937 else 2845 printf("%s: %l d\n", argv[j], size/2);2938 printf("%s: %llu\n", argv[j], size); 2846 2939 } 2847 2940 return 0; … … 2850 2943 2851 2944 #if ENABLE_FEATURE_FDISK_WRITABLE 2852 if ( argc != 1)2945 if (!argv[0] || argv[1]) 2853 2946 bb_show_usage(); 2854 2947 2855 2948 disk_device = argv[0]; 2856 get_boot( fdisk);2949 get_boot(OPEN_MAIN); 2857 2950 2858 2951 if (LABEL_IS_OSF) { … … 2862 2955 bsd_select(); 2863 2956 /*Why do we do this? It seems to be counter-intuitive*/ 2864 current_label_type = label_dos;2957 current_label_type = LABEL_DOS; 2865 2958 /* If we return we may want to make an empty DOS label? */ 2866 2959 } … … 2868 2961 while (1) { 2869 2962 int c; 2870 putchar('\n');2871 c = tolower(read_nonempty("Command (m for help): "));2963 bb_putchar('\n'); 2964 c = 0x20 | read_nonempty("Command (m for help): "); 2872 2965 switch (c) { 2873 2966 case 'a': 2874 2967 if (LABEL_IS_DOS) 2875 toggle_active(get_partition(1, partitions));2968 toggle_active(get_partition(1, g_partitions)); 2876 2969 else if (LABEL_IS_SUN) 2877 toggle_sunflags(get_partition(1, partitions),2970 toggle_sunflags(get_partition(1, g_partitions), 2878 2971 0x01); 2879 2972 else if (LABEL_IS_SGI) 2880 2973 sgi_set_bootpartition( 2881 get_partition(1, partitions));2974 get_partition(1, g_partitions)); 2882 2975 else 2883 2976 unknown_command(c); … … 2902 2995 toggle_dos_compatibility_flag(); 2903 2996 else if (LABEL_IS_SUN) 2904 toggle_sunflags(get_partition(1, partitions),2997 toggle_sunflags(get_partition(1, g_partitions), 2905 2998 0x10); 2906 2999 else if (LABEL_IS_SGI) 2907 3000 sgi_set_swappartition( 2908 get_partition(1, partitions));3001 get_partition(1, g_partitions)); 2909 3002 else 2910 3003 unknown_command(c); … … 2918 3011 partition tables */ 2919 3012 if (!LABEL_IS_SGI) { 2920 j = get_existing_partition(1, partitions);3013 j = get_existing_partition(1, g_partitions); 2921 3014 } else { 2922 j = get_partition(1, partitions);3015 j = get_partition(1, g_partitions); 2923 3016 } 2924 3017 if (j >= 0) … … 2947 3040 break; 2948 3041 case 'q': 2949 close(fd); 2950 puts(""); 3042 if (ENABLE_FEATURE_CLEAN_UP) 3043 close_dev_fd(); 3044 bb_putchar('\n'); 2951 3045 return 0; 2952 3046 case 's':
Note:
See TracChangeset
for help on using the changeset viewer.