diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2010-04-06 02:31:43 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2010-04-06 02:31:43 +0200 |
commit | 5ea1de2235e75d8fd4f559c7c6cca9a2d0396094 (patch) | |
tree | 29c746ef85d67a7c9810f28118b9115e3aa615ae | |
parent | 37bc1eb5cdcaec015579241fc1f20fd03bed2d67 (diff) | |
download | busybox-w32-5ea1de2235e75d8fd4f559c7c6cca9a2d0396094.tar.gz busybox-w32-5ea1de2235e75d8fd4f559c7c6cca9a2d0396094.tar.bz2 busybox-w32-5ea1de2235e75d8fd4f559c7c6cca9a2d0396094.zip |
fdisk: code shrink without logic changes
function old new delta
create_doslabel 113 110 -3
set_start_sect 8 4 -4
set_nr_sects 8 4 -4
get_start_sect 8 4 -4
get_nr_sects 8 4 -4
store4_little_endian 21 - -21
read4_little_endian 33 - -33
is_cleared_partition 84 21 -63
------------------------------------------------------------------------------
(add/remove: 0/2 grow/shrink: 0/6 up/down: 0/-136) Total: -136 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | util-linux/fdisk.c | 244 |
1 files changed, 118 insertions, 126 deletions
diff --git a/util-linux/fdisk.c b/util-linux/fdisk.c index 980568bc8..cb15bd267 100644 --- a/util-linux/fdisk.c +++ b/util-linux/fdisk.c | |||
@@ -21,6 +21,13 @@ | |||
21 | #endif | 21 | #endif |
22 | #include "libbb.h" | 22 | #include "libbb.h" |
23 | 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 | |||
30 | |||
24 | /* Looks like someone forgot to add this to config system */ | 31 | /* Looks like someone forgot to add this to config system */ |
25 | #ifndef ENABLE_FEATURE_FDISK_BLKSIZE | 32 | #ifndef ENABLE_FEATURE_FDISK_BLKSIZE |
26 | # define ENABLE_FEATURE_FDISK_BLKSIZE 0 | 33 | # define ENABLE_FEATURE_FDISK_BLKSIZE 0 |
@@ -181,7 +188,7 @@ struct pte { | |||
181 | sector_t offset; /* disk sector number */ | 188 | sector_t offset; /* disk sector number */ |
182 | char *sectorbuffer; /* disk sector contents */ | 189 | char *sectorbuffer; /* disk sector contents */ |
183 | #if ENABLE_FEATURE_FDISK_WRITABLE | 190 | #if ENABLE_FEATURE_FDISK_WRITABLE |
184 | char changed; /* boolean */ | 191 | char changed; /* boolean */ |
185 | #endif | 192 | #endif |
186 | }; | 193 | }; |
187 | 194 | ||
@@ -445,27 +452,6 @@ close_dev_fd(void) | |||
445 | xmove_fd(xopen(bb_dev_null, O_RDONLY), dev_fd); | 452 | xmove_fd(xopen(bb_dev_null, O_RDONLY), dev_fd); |
446 | } | 453 | } |
447 | 454 | ||
448 | #if ENABLE_FEATURE_FDISK_WRITABLE | ||
449 | /* Read line; return 0 or first printable char */ | ||
450 | static int | ||
451 | read_line(const char *prompt) | ||
452 | { | ||
453 | int sz; | ||
454 | |||
455 | sz = read_line_input(prompt, line_buffer, sizeof(line_buffer), NULL); | ||
456 | if (sz <= 0) | ||
457 | exit(EXIT_SUCCESS); /* Ctrl-D or Ctrl-C */ | ||
458 | |||
459 | if (line_buffer[sz-1] == '\n') | ||
460 | line_buffer[--sz] = '\0'; | ||
461 | |||
462 | line_ptr = line_buffer; | ||
463 | while (*line_ptr != '\0' && (unsigned char)*line_ptr <= ' ') | ||
464 | line_ptr++; | ||
465 | return *line_ptr; | ||
466 | } | ||
467 | #endif | ||
468 | |||
469 | /* | 455 | /* |
470 | * Return partition name - uses static storage | 456 | * Return partition name - uses static storage |
471 | */ | 457 | */ |
@@ -497,30 +483,13 @@ partname(const char *dev, int pno, int lth) | |||
497 | 483 | ||
498 | if (lth) { | 484 | if (lth) { |
499 | snprintf(bufp, bufsiz, "%*.*s%s%-2u", | 485 | snprintf(bufp, bufsiz, "%*.*s%s%-2u", |
500 | lth-wp-2, w, dev, p, pno); | 486 | lth-wp-2, w, dev, p, pno); |
501 | } else { | 487 | } else { |
502 | snprintf(bufp, bufsiz, "%.*s%s%-2u", w, dev, p, pno); | 488 | snprintf(bufp, bufsiz, "%.*s%s%-2u", w, dev, p, pno); |
503 | } | 489 | } |
504 | return bufp; | 490 | return bufp; |
505 | } | 491 | } |
506 | 492 | ||
507 | #if ENABLE_FEATURE_FDISK_WRITABLE | ||
508 | static void | ||
509 | set_all_unchanged(void) | ||
510 | { | ||
511 | int i; | ||
512 | |||
513 | for (i = 0; i < MAXIMUM_PARTS; i++) | ||
514 | ptes[i].changed = 0; | ||
515 | } | ||
516 | |||
517 | static ALWAYS_INLINE void | ||
518 | set_changed(int i) | ||
519 | { | ||
520 | ptes[i].changed = 1; | ||
521 | } | ||
522 | #endif /* FEATURE_FDISK_WRITABLE */ | ||
523 | |||
524 | static ALWAYS_INLINE struct partition * | 493 | static ALWAYS_INLINE struct partition * |
525 | get_part_table(int i) | 494 | get_part_table(int i) |
526 | { | 495 | { |
@@ -541,7 +510,67 @@ valid_part_table_flag(const char *mbuffer) | |||
541 | return (mbuffer[510] == 0x55 && (uint8_t)mbuffer[511] == 0xaa); | 510 | return (mbuffer[510] == 0x55 && (uint8_t)mbuffer[511] == 0xaa); |
542 | } | 511 | } |
543 | 512 | ||
513 | static void fdisk_fatal(const char *why) | ||
514 | { | ||
515 | if (listing) { | ||
516 | close_dev_fd(); | ||
517 | longjmp(listingbuf, 1); | ||
518 | } | ||
519 | bb_error_msg_and_die(why, disk_device); | ||
520 | } | ||
521 | |||
522 | static void | ||
523 | seek_sector(sector_t secno) | ||
524 | { | ||
525 | #if ENABLE_FDISK_SUPPORT_LARGE_DISKS | ||
526 | off64_t off = (off64_t)secno * sector_size; | ||
527 | if (lseek64(dev_fd, off, SEEK_SET) == (off64_t) -1) | ||
528 | fdisk_fatal(unable_to_seek); | ||
529 | #else | ||
530 | uint64_t off = (uint64_t)secno * sector_size; | ||
531 | if (off > MAXINT(off_t) | ||
532 | || lseek(dev_fd, (off_t)off, SEEK_SET) == (off_t) -1 | ||
533 | ) { | ||
534 | fdisk_fatal(unable_to_seek); | ||
535 | } | ||
536 | #endif | ||
537 | } | ||
538 | |||
544 | #if ENABLE_FEATURE_FDISK_WRITABLE | 539 | #if ENABLE_FEATURE_FDISK_WRITABLE |
540 | /* Read line; return 0 or first printable char */ | ||
541 | static int | ||
542 | read_line(const char *prompt) | ||
543 | { | ||
544 | int sz; | ||
545 | |||
546 | sz = read_line_input(prompt, line_buffer, sizeof(line_buffer), NULL); | ||
547 | if (sz <= 0) | ||
548 | exit(EXIT_SUCCESS); /* Ctrl-D or Ctrl-C */ | ||
549 | |||
550 | if (line_buffer[sz-1] == '\n') | ||
551 | line_buffer[--sz] = '\0'; | ||
552 | |||
553 | line_ptr = line_buffer; | ||
554 | while (*line_ptr != '\0' && (unsigned char)*line_ptr <= ' ') | ||
555 | line_ptr++; | ||
556 | return *line_ptr; | ||
557 | } | ||
558 | |||
559 | static void | ||
560 | set_all_unchanged(void) | ||
561 | { | ||
562 | int i; | ||
563 | |||
564 | for (i = 0; i < MAXIMUM_PARTS; i++) | ||
565 | ptes[i].changed = 0; | ||
566 | } | ||
567 | |||
568 | static ALWAYS_INLINE void | ||
569 | set_changed(int i) | ||
570 | { | ||
571 | ptes[i].changed = 1; | ||
572 | } | ||
573 | |||
545 | static ALWAYS_INLINE void | 574 | static ALWAYS_INLINE void |
546 | write_part_table_flag(char *b) | 575 | write_part_table_flag(char *b) |
547 | { | 576 | { |
@@ -579,48 +608,18 @@ read_hex(const char *const *sys) | |||
579 | continue; | 608 | continue; |
580 | } | 609 | } |
581 | v = bb_strtoul(line_ptr, NULL, 16); | 610 | v = bb_strtoul(line_ptr, NULL, 16); |
582 | if (v > 0xff) | 611 | if (v <= 0xff) |
583 | /* Bad input also triggers this */ | 612 | return v; |
584 | continue; | ||
585 | return v; | ||
586 | } | 613 | } |
587 | } | 614 | } |
588 | #endif /* FEATURE_FDISK_WRITABLE */ | ||
589 | |||
590 | static void fdisk_fatal(const char *why) | ||
591 | { | ||
592 | if (listing) { | ||
593 | close_dev_fd(); | ||
594 | longjmp(listingbuf, 1); | ||
595 | } | ||
596 | bb_error_msg_and_die(why, disk_device); | ||
597 | } | ||
598 | 615 | ||
599 | static void | 616 | static void |
600 | seek_sector(sector_t secno) | ||
601 | { | ||
602 | #if ENABLE_FDISK_SUPPORT_LARGE_DISKS | ||
603 | off64_t off = (off64_t)secno * sector_size; | ||
604 | if (lseek64(dev_fd, off, SEEK_SET) == (off64_t) -1) | ||
605 | fdisk_fatal(unable_to_seek); | ||
606 | #else | ||
607 | uint64_t off = (uint64_t)secno * sector_size; | ||
608 | if (off > MAXINT(off_t) | ||
609 | || lseek(dev_fd, (off_t)off, SEEK_SET) == (off_t) -1 | ||
610 | ) { | ||
611 | fdisk_fatal(unable_to_seek); | ||
612 | } | ||
613 | #endif | ||
614 | } | ||
615 | |||
616 | #if ENABLE_FEATURE_FDISK_WRITABLE | ||
617 | static void | ||
618 | write_sector(sector_t secno, const void *buf) | 617 | write_sector(sector_t secno, const void *buf) |
619 | { | 618 | { |
620 | seek_sector(secno); | 619 | seek_sector(secno); |
621 | xwrite(dev_fd, buf, sector_size); | 620 | xwrite(dev_fd, buf, sector_size); |
622 | } | 621 | } |
623 | #endif | 622 | #endif /* FEATURE_FDISK_WRITABLE */ |
624 | 623 | ||
625 | 624 | ||
626 | #include "fdisk_aix.c" | 625 | #include "fdisk_aix.c" |
@@ -713,40 +712,42 @@ STATIC_SUN void sun_write_table(void); | |||
713 | #include "fdisk_sun.c" | 712 | #include "fdisk_sun.c" |
714 | 713 | ||
715 | 714 | ||
716 | #if ENABLE_FEATURE_FDISK_WRITABLE | 715 | static inline_if_little_endian unsigned |
717 | /* start_sect and nr_sects are stored little endian on all machines */ | 716 | read4_little_endian(const unsigned char *cp) |
718 | /* moreover, they are not aligned correctly */ | ||
719 | static void | ||
720 | store4_little_endian(unsigned char *cp, unsigned val) | ||
721 | { | 717 | { |
722 | cp[0] = val; | 718 | uint32_t v; |
723 | cp[1] = val >> 8; | 719 | move_from_unaligned32(v, cp); |
724 | cp[2] = val >> 16; | 720 | return SWAP_LE32(v); |
725 | cp[3] = val >> 24; | ||
726 | } | 721 | } |
727 | #endif /* FEATURE_FDISK_WRITABLE */ | ||
728 | 722 | ||
729 | static unsigned | 723 | static sector_t |
730 | read4_little_endian(const unsigned char *cp) | 724 | get_start_sect(const struct partition *p) |
725 | { | ||
726 | return read4_little_endian(p->start4); | ||
727 | } | ||
728 | |||
729 | static sector_t | ||
730 | get_nr_sects(const struct partition *p) | ||
731 | { | 731 | { |
732 | return cp[0] + (cp[1] << 8) + (cp[2] << 16) + (cp[3] << 24); | 732 | return read4_little_endian(p->size4); |
733 | } | 733 | } |
734 | 734 | ||
735 | #if ENABLE_FEATURE_FDISK_WRITABLE | 735 | #if ENABLE_FEATURE_FDISK_WRITABLE |
736 | static void | 736 | /* start_sect and nr_sects are stored little endian on all machines */ |
737 | set_start_sect(struct partition *p, unsigned start_sect) | 737 | /* moreover, they are not aligned correctly */ |
738 | static inline_if_little_endian void | ||
739 | store4_little_endian(unsigned char *cp, unsigned val) | ||
738 | { | 740 | { |
739 | store4_little_endian(p->start4, start_sect); | 741 | uint32_t v = SWAP_LE32(val); |
742 | move_to_unaligned32(cp, v); | ||
740 | } | 743 | } |
741 | #endif | ||
742 | 744 | ||
743 | static sector_t | 745 | static void |
744 | get_start_sect(const struct partition *p) | 746 | set_start_sect(struct partition *p, unsigned start_sect) |
745 | { | 747 | { |
746 | return read4_little_endian(p->start4); | 748 | store4_little_endian(p->start4, start_sect); |
747 | } | 749 | } |
748 | 750 | ||
749 | #if ENABLE_FEATURE_FDISK_WRITABLE | ||
750 | static void | 751 | static void |
751 | set_nr_sects(struct partition *p, unsigned nr_sects) | 752 | set_nr_sects(struct partition *p, unsigned nr_sects) |
752 | { | 753 | { |
@@ -754,12 +755,6 @@ set_nr_sects(struct partition *p, unsigned nr_sects) | |||
754 | } | 755 | } |
755 | #endif | 756 | #endif |
756 | 757 | ||
757 | static sector_t | ||
758 | get_nr_sects(const struct partition *p) | ||
759 | { | ||
760 | return read4_little_endian(p->size4); | ||
761 | } | ||
762 | |||
763 | /* Allocate a buffer and read a partition table sector */ | 758 | /* Allocate a buffer and read a partition table sector */ |
764 | static void | 759 | static void |
765 | read_pte(struct pte *pe, sector_t offset) | 760 | read_pte(struct pte *pe, sector_t offset) |
@@ -942,7 +937,7 @@ get_sys_types(void) | |||
942 | } | 937 | } |
943 | #else | 938 | #else |
944 | #define get_sys_types() i386_sys_types | 939 | #define get_sys_types() i386_sys_types |
945 | #endif /* FEATURE_FDISK_WRITABLE */ | 940 | #endif |
946 | 941 | ||
947 | static const char * | 942 | static const char * |
948 | partition_type(unsigned char type) | 943 | partition_type(unsigned char type) |
@@ -957,6 +952,24 @@ partition_type(unsigned char type) | |||
957 | return "Unknown"; | 952 | return "Unknown"; |
958 | } | 953 | } |
959 | 954 | ||
955 | static int | ||
956 | is_cleared_partition(const struct partition *p) | ||
957 | { | ||
958 | /* We consider partition "cleared" only if it has only zeros */ | ||
959 | const char *cp = (const char *)p; | ||
960 | int cnt = sizeof(*p); | ||
961 | char bits = 0; | ||
962 | while (--cnt >= 0) | ||
963 | bits |= *cp++; | ||
964 | return (bits == 0); | ||
965 | } | ||
966 | |||
967 | static void | ||
968 | clear_partition(struct partition *p) | ||
969 | { | ||
970 | if (p) | ||
971 | memset(p, 0, sizeof(*p)); | ||
972 | } | ||
960 | 973 | ||
961 | #if ENABLE_FEATURE_FDISK_WRITABLE | 974 | #if ENABLE_FEATURE_FDISK_WRITABLE |
962 | static int | 975 | static int |
@@ -998,26 +1011,8 @@ list_types(const char *const *sys) | |||
998 | } while (done < last[0]); | 1011 | } while (done < last[0]); |
999 | bb_putchar('\n'); | 1012 | bb_putchar('\n'); |
1000 | } | 1013 | } |
1001 | #endif /* FEATURE_FDISK_WRITABLE */ | ||
1002 | |||
1003 | static int | ||
1004 | is_cleared_partition(const struct partition *p) | ||
1005 | { | ||
1006 | return !(!p || p->boot_ind || p->head || p->sector || p->cyl || | ||
1007 | p->sys_ind || p->end_head || p->end_sector || p->end_cyl || | ||
1008 | get_start_sect(p) || get_nr_sects(p)); | ||
1009 | } | ||
1010 | 1014 | ||
1011 | static void | 1015 | static void |
1012 | clear_partition(struct partition *p) | ||
1013 | { | ||
1014 | if (!p) | ||
1015 | return; | ||
1016 | memset(p, 0, sizeof(struct partition)); | ||
1017 | } | ||
1018 | |||
1019 | #if ENABLE_FEATURE_FDISK_WRITABLE | ||
1020 | static void | ||
1021 | set_partition(int i, int doext, sector_t start, sector_t stop, int sysid) | 1016 | set_partition(int i, int doext, sector_t start, sector_t stop, int sysid) |
1022 | { | 1017 | { |
1023 | struct partition *p; | 1018 | struct partition *p; |
@@ -1189,26 +1184,22 @@ read_extended(int ext) | |||
1189 | static void | 1184 | static void |
1190 | create_doslabel(void) | 1185 | create_doslabel(void) |
1191 | { | 1186 | { |
1192 | int i; | ||
1193 | |||
1194 | printf(msg_building_new_label, "DOS disklabel"); | 1187 | printf(msg_building_new_label, "DOS disklabel"); |
1195 | 1188 | ||
1196 | current_label_type = LABEL_DOS; | 1189 | current_label_type = LABEL_DOS; |
1197 | |||
1198 | #if ENABLE_FEATURE_OSF_LABEL | 1190 | #if ENABLE_FEATURE_OSF_LABEL |
1199 | possibly_osf_label = 0; | 1191 | possibly_osf_label = 0; |
1200 | #endif | 1192 | #endif |
1201 | g_partitions = 4; | 1193 | g_partitions = 4; |
1202 | 1194 | ||
1203 | for (i = 510-64; i < 510; i++) | 1195 | memset(&MBRbuffer[510 - 4*16], 0, 4*16); |
1204 | MBRbuffer[i] = 0; | ||
1205 | write_part_table_flag(MBRbuffer); | 1196 | write_part_table_flag(MBRbuffer); |
1206 | extended_offset = 0; | 1197 | extended_offset = 0; |
1207 | set_all_unchanged(); | 1198 | set_all_unchanged(); |
1208 | set_changed(0); | 1199 | set_changed(0); |
1209 | get_boot(CREATE_EMPTY_DOS); | 1200 | get_boot(CREATE_EMPTY_DOS); |
1210 | } | 1201 | } |
1211 | #endif /* FEATURE_FDISK_WRITABLE */ | 1202 | #endif |
1212 | 1203 | ||
1213 | static void | 1204 | static void |
1214 | get_sectorsize(void) | 1205 | get_sectorsize(void) |
@@ -1721,9 +1712,10 @@ delete_partition(int i) | |||
1721 | ptes[i] = ptes[i+1]; | 1712 | ptes[i] = ptes[i+1]; |
1722 | i++; | 1713 | i++; |
1723 | } | 1714 | } |
1724 | } else | 1715 | } else { |
1725 | /* the only logical: clear only */ | 1716 | /* the only logical: clear only */ |
1726 | clear_partition(ptes[i].part_table); | 1717 | clear_partition(ptes[i].part_table); |
1718 | } | ||
1727 | } | 1719 | } |
1728 | } | 1720 | } |
1729 | 1721 | ||