diff options
author | Karel Zak <kzak@redhat.com> | 2006-12-07 00:25:43 +0100 |
---|---|---|
committer | Karel Zak <kzak@redhat.com> | 2006-12-07 00:25:43 +0100 |
commit | 22853e4a82c6ef7b336527529acb94b14a0b0fd8 (patch) | |
tree | ee28e4598c8c449d7e811711d8ce8eb17caecfb6 /fdisk | |
parent | eb63b9b8f4cecb34c2478282567862bc48ef256d (diff) | |
download | util-linux-22853e4a82c6ef7b336527529acb94b14a0b0fd8.tar.gz |
Imported from util-linux-2.10m tarball.
Diffstat (limited to 'fdisk')
-rw-r--r-- | fdisk/Makefile | 8 | ||||
-rw-r--r-- | fdisk/addpart.c | 40 | ||||
-rw-r--r-- | fdisk/cfdisk.c | 254 | ||||
-rw-r--r-- | fdisk/common.h | 7 | ||||
-rw-r--r-- | fdisk/delpart.c | 40 | ||||
-rw-r--r-- | fdisk/fdisk.8 | 17 | ||||
-rw-r--r-- | fdisk/fdisk.c | 1074 | ||||
-rw-r--r-- | fdisk/fdisk.h | 19 | ||||
-rw-r--r-- | fdisk/fdiskaixlabel.c | 7 | ||||
-rw-r--r-- | fdisk/fdiskaixlabel.h | 4 | ||||
-rw-r--r-- | fdisk/fdiskbsdlabel.c | 337 | ||||
-rw-r--r-- | fdisk/fdiskbsdlabel.h | 8 | ||||
-rw-r--r-- | fdisk/fdisksgilabel.c | 220 | ||||
-rw-r--r-- | fdisk/fdisksgilabel.h | 6 | ||||
-rw-r--r-- | fdisk/fdisksunlabel.c | 82 | ||||
-rw-r--r-- | fdisk/fdisksunlabel.h | 7 | ||||
-rw-r--r-- | fdisk/i386_sys_types.c | 2 | ||||
-rw-r--r-- | fdisk/llseek.c | 2 | ||||
-rw-r--r-- | fdisk/partname.c | 46 | ||||
-rw-r--r-- | fdisk/sfdisk.8 | 15 | ||||
-rw-r--r-- | fdisk/sfdisk.c | 349 |
21 files changed, 1440 insertions, 1104 deletions
diff --git a/fdisk/Makefile b/fdisk/Makefile index 873b2850..a319c2ba 100644 --- a/fdisk/Makefile +++ b/fdisk/Makefile @@ -59,14 +59,14 @@ activate: sfdisk ln -s sfdisk activate fdisk: fdisk.o llseek.o fdiskbsdlabel.o fdisksgilabel.o fdisksunlabel.o \ - fdiskaixlabel.o i386_sys_types.o + fdiskaixlabel.o i386_sys_types.o partname.o fdisk.o: fdisk.c fdisk.h fdiskbsdlabel.o: fdiskbsdlabel.c fdisk.h fdiskbsdlabel.h fdisksunlabel.o: fdisksunlabel.c fdisksunlabel.h fdisk.h fdiskaixlabel.o: fdiskaixlabel.c fdiskaixlabel.h fdisk.h fdisk.o cfdisk.o sfdisk.o fdiskbsdlabel.o fdisksunlabel.o \ - fdisksgilabel.o fdiskaixlabel.o i386_sys_types.o: common.h -sfdisk: sfdisk.o i386_sys_types.o + fdisksgilabel.o fdiskaixlabel.o i386_sys_types.o partname.o: common.h +sfdisk: sfdisk.o i386_sys_types.o partname.o install: all $(INSTALLDIR) $(SBINDIR) @@ -76,4 +76,4 @@ install: all .PHONY: clean clean: - -rm -f *.o *~ core $(SBIN) addpart delpart + -rm -f *.o *~ core $(SBIN) diff --git a/fdisk/addpart.c b/fdisk/addpart.c deleted file mode 100644 index 11d4305b..00000000 --- a/fdisk/addpart.c +++ /dev/null @@ -1,40 +0,0 @@ -/* very primitive wrapper around the `add partition' ioctl */ -#include <stdio.h> -#include <fcntl.h> -#include <stdlib.h> -#include <sys/ioctl.h> -#include <linux/blkpg.h> - -int -main(int argc, char **argv){ - int fd; - struct blkpg_ioctl_arg a; - struct blkpg_partition p; - - if (argc != 5) { - fprintf(stderr, - "usage: %s diskdevice partitionnr start length\n", - argv[0]); - exit(1); - } - if ((fd = open(argv[1], O_RDONLY)) < 0) { - perror(argv[1]); - exit(1); - } - p.pno = atoi(argv[2]); - p.start = 512 * ((long long) atol(argv[3])); - p.length = 512 * ((long long) atol(argv[4])); - p.devname[0] = 0; - p.volname[0] = 0; - a.op = BLKPG_ADD_PARTITION; - a.flags = 0; - a.datalen = sizeof(p); - a.data = &p; - - if (ioctl(fd, BLKPG, &a) == -1) { - perror("BLKPG"); - exit(1); - } - - return 0; -} diff --git a/fdisk/cfdisk.c b/fdisk/cfdisk.c index 4d0eb7ea..055046d7 100644 --- a/fdisk/cfdisk.c +++ b/fdisk/cfdisk.c @@ -74,7 +74,6 @@ #include <sys/ioctl.h> #include <linux/types.h> #include <linux/hdreg.h> -#include <linux/fs.h> /* for BLKRRPART, BLKGETSIZE */ #include "nls.h" #include "common.h" @@ -206,7 +205,7 @@ int kern_heads = 0, kern_sectors = 0; int pt_heads = 0, pt_sectors = 0; -void +static void set_hsc0(unsigned char *h, unsigned char *s, int *c, int sector) { if (sector >= 1024*cylinder_size) sector = 1024*cylinder_size - 1; @@ -217,7 +216,7 @@ set_hsc0(unsigned char *h, unsigned char *s, int *c, int sector) { *c = sector; } -void +static void set_hsc(unsigned char *h, unsigned char *s, unsigned char *c, int sector) { int cc; @@ -226,12 +225,12 @@ set_hsc(unsigned char *h, unsigned char *s, unsigned char *c, int sector) { *s |= (cc >> 2) & 0xC0; } -void +static void set_hsc_begin(struct partition *p, int sector) { set_hsc(& p->head, & p->sector, & p->cyl, sector); } -void +static void set_hsc_end(struct partition *p, int sector) { set_hsc(& p->end_head, & p->end_sector, & p->end_cyl, sector); } @@ -246,7 +245,7 @@ set_hsc_end(struct partition *p, int sector) { /* start_sect and nr_sects are stored little endian on all machines */ /* moreover, they are not aligned correctly */ -void +static void store4_little_endian(unsigned char *cp, unsigned int val) { cp[0] = (val & 0xff); cp[1] = ((val >> 8) & 0xff); @@ -254,28 +253,28 @@ store4_little_endian(unsigned char *cp, unsigned int val) { cp[3] = ((val >> 24) & 0xff); } -unsigned int +static unsigned int read4_little_endian(unsigned char *cp) { return (uint)(cp[0]) + ((uint)(cp[1]) << 8) + ((uint)(cp[2]) << 16) + ((uint)(cp[3]) << 24); } -void +static void set_start_sect(struct partition *p, unsigned int start_sect) { store4_little_endian(p->start4, start_sect); } -unsigned int +static unsigned int get_start_sect(struct partition *p) { return read4_little_endian(p->start4); } -void +static void set_nr_sects(struct partition *p, unsigned int nr_sects) { store4_little_endian(p->size4, nr_sects); } -unsigned int +static unsigned int get_nr_sects(struct partition *p) { return read4_little_endian(p->size4); } @@ -353,11 +352,11 @@ int LABEL_START = 54; int SIZE_START = 70; int COMMAND_LINE_X = 5; -void die_x(int ret); -void draw_screen(void); +static void die_x(int ret); +static void draw_screen(void); /* Guaranteed alloc */ -void * +static void * xmalloc (size_t size) { void *t; @@ -373,14 +372,14 @@ xmalloc (size_t size) { } /* Some libc's have their own basename() */ -char *my_basename(char *devname) -{ +static char * +my_basename(char *devname) { char *s = rindex(devname, '/'); return s ? s+1 : devname; } -char *partition_type_name(unsigned char type) -{ +static char * +partition_type_name(unsigned char type) { struct systypes *s = i386_sys_types; while(s->name && s->type != type) @@ -388,8 +387,8 @@ char *partition_type_name(unsigned char type) return s->name; } -char *partition_type_text(int i) -{ +static char * +partition_type_text(int i) { if (p_info[i].id == UNUSABLE) return _("Unusable"); else if (p_info[i].id == FREE_SPACE) @@ -412,8 +411,8 @@ char *partition_type_text(int i) return partition_type_name(p_info[i].id); } -void fdexit(int ret) -{ +static void +fdexit(int ret) { if (opened) close(fd); @@ -430,8 +429,8 @@ void fdexit(int ret) exit(ret); } -int get_string(char *str, int len, char *def) -{ +static int +get_string(char *str, int len, char *def) { char c; int i = 0; int x, y; @@ -489,8 +488,8 @@ int get_string(char *str, int len, char *def) return i; } -void clear_warning(void) -{ +static void +clear_warning(void) { int i; if (!curses_started || !warning_last_time) @@ -503,8 +502,8 @@ void clear_warning(void) warning_last_time = FALSE; } -void print_warning(char *s) -{ +static void +print_warning(char *s) { if (!curses_started) { fprintf(stderr, "%s\n", s); } else { @@ -515,8 +514,8 @@ void print_warning(char *s) } } -void fatal(char *s, int ret) -{ +static void +fatal(char *s, int ret) { char *err = _("FATAL ERROR"); if (curses_started) { @@ -538,13 +537,13 @@ void fatal(char *s, int ret) } } -void die(int dummy) -{ +static void +die(int dummy) { die_x(0); } -void die_x(int ret) -{ +static void +die_x(int ret) { signal(SIGINT, old_SIGINT); signal(SIGTERM, old_SIGTERM); #ifdef SLCURSES @@ -559,23 +558,24 @@ void die_x(int ret) fdexit(ret); } -void read_sector(char *buffer, int sect_num) -{ +static void +read_sector(char *buffer, int sect_num) { if (ext2_llseek(fd, ((ext2_loff_t) sect_num)*SECTOR_SIZE, SEEK_SET) < 0) fatal(_("Cannot seek on disk drive"), 2); if (read(fd, buffer, SECTOR_SIZE) != SECTOR_SIZE) fatal(_("Cannot read disk drive"), 2); } -void write_sector(char *buffer, int sect_num) -{ +static void +write_sector(char *buffer, int sect_num) { if (ext2_llseek(fd, ((ext2_loff_t) sect_num)*SECTOR_SIZE, SEEK_SET) < 0) fatal(_("Cannot seek on disk drive"), 2); if (write(fd, buffer, SECTOR_SIZE) != SECTOR_SIZE) fatal(_("Cannot write disk drive"), 2); } -void dos_copy_to_info(char *to, int tosz, char *from, int fromsz) { +static void +dos_copy_to_info(char *to, int tosz, char *from, int fromsz) { int i; for(i=0; i<tosz && i<fromsz && isascii(from[i]); i++) @@ -583,8 +583,8 @@ void dos_copy_to_info(char *to, int tosz, char *from, int fromsz) { to[i] = 0; } -void get_dos_label(int i) -{ +static void +get_dos_label(int i) { char sector[128]; #define DOS_OSTYPE_OFFSET 3 #define DOS_LABEL_OFFSET 43 @@ -607,8 +607,8 @@ void get_dos_label(int i) } } -void get_ext2_label(int i) -{ +static void +get_ext2_label(int i) { #define EXT2_SUPER_MAGIC 0xEF53 #define EXT2LABELSZ 16 struct ext2_super_block { @@ -637,8 +637,8 @@ void get_ext2_label(int i) } } -void check_part_info(void) -{ +static void +check_part_info(void) { int i, pri = 0, log = 0; for (i = 0; i < num_parts; i++) @@ -718,8 +718,8 @@ void check_part_info(void) } } -void remove_part(int i) -{ +static void +remove_part(int i) { int p; for (p = i; p < num_parts; p++) @@ -730,8 +730,8 @@ void remove_part(int i) cur_part--; } -void insert_empty_part(int i, int first, int last) -{ +static void +insert_empty_part(int i, int first, int last) { int p; for (p = num_parts; p > i; p--) @@ -750,8 +750,8 @@ void insert_empty_part(int i, int first, int last) num_parts++; } -void del_part(int i) -{ +static void +del_part(int i) { int num = p_info[i].num; if (i > 0 && (p_info[i-1].id == FREE_SPACE || @@ -805,9 +805,9 @@ void del_part(int i) check_part_info(); } -int add_part(int num, int id, int flags, int first, int last, int offset, - int want_label, char **errmsg) -{ +static int +add_part(int num, int id, int flags, int first, int last, int offset, + int want_label, char **errmsg) { int i, pri = 0, log = 0; if (num_parts == MAXIMUM_PARTS) { @@ -952,8 +952,8 @@ int add_part(int num, int id, int flags, int first, int last, int offset, return 0; } -int find_primary(void) -{ +static int +find_primary(void) { int num = 0, cur = 0; while (cur < num_parts && IS_PRIMARY(num)) @@ -970,8 +970,8 @@ int find_primary(void) return num; } -int find_logical(int i) -{ +static int +find_logical(int i) { int num = -1; int j; @@ -989,8 +989,8 @@ int find_logical(int i) return num; } -void inc_logical(int i) -{ +static void +inc_logical(int i) { int j; for (j = i; j < num_parts; j++) @@ -1025,9 +1025,9 @@ struct MenuItem * Should not be called directly. Call function menuSelect instead. */ -int menuUpdate( int y, int x, struct MenuItem *menuItems, int itemLength, - char *available, int menuType, int current ) -{ +static int +menuUpdate( int y, int x, struct MenuItem *menuItems, int itemLength, + char *available, int menuType, int current ) { int i, lmargin = x, ymargin = y; char *mcd; @@ -1112,9 +1112,9 @@ int menuUpdate( int y, int x, struct MenuItem *menuItems, int itemLength, /* This function takes a list of menu items, lets the user choose one * * and returns the value keyboard shortcut of the selected menu item */ -int menuSelect( int y, int x, struct MenuItem *menuItems, int itemLength, - char *available, int menuType, int menuDefault ) -{ +static int +menuSelect( int y, int x, struct MenuItem *menuItems, int itemLength, + char *available, int menuType, int menuDefault ) { int i, ylast = y, key = 0, current = menuDefault; if( !( menuType & ( MENU_HORIZ | MENU_VERT ) ) ) @@ -1268,8 +1268,8 @@ int menuSelect( int y, int x, struct MenuItem *menuItems, int itemLength, * and waits for a keypress. * * Perhaps calling function menuSelect is a bit overkill but who cares? */ -void menuContinue(void) -{ +static void +menuContinue(void) { static struct MenuItem menuContinueBtn[]= { { 'c', "", N_("Press a key to continue") }, @@ -1283,8 +1283,8 @@ void menuContinue(void) /* Function menuSelect takes way too many parameters * * Luckily, most of time we can do with this function */ -int menuSimple(struct MenuItem *menuItems, int menuDefault) -{ +static int +menuSimple(struct MenuItem *menuItems, int menuDefault) { int i, j, itemLength = 0; char available[MENU_MAX_ITEMS]; @@ -1301,8 +1301,8 @@ int menuSimple(struct MenuItem *menuItems, int menuDefault) /* End of command menu support code */ -void new_part(int i) -{ +static void +new_part(int i) { char response[LINE_LENGTH], def[LINE_LENGTH]; char c; int first = p_info[i].first_sector; @@ -1411,8 +1411,8 @@ void new_part(int i) (void) add_part(num, id, flags, first, last, offset, 0, &errmsg); } -void get_kernel_geometry(void) -{ +static void +get_kernel_geometry(void) { #ifdef HDIO_GETGEO struct hd_geometry geometry; @@ -1423,8 +1423,8 @@ void get_kernel_geometry(void) #endif } -void get_partition_table_geometry(partition_table *bufp) -{ +static void +get_partition_table_geometry(partition_table *bufp) { struct partition *p; int i,h,s,hh,ss; int first = TRUE; @@ -1455,8 +1455,8 @@ void get_partition_table_geometry(partition_table *bufp) } } -void decide_on_geometry(void) -{ +static void +decide_on_geometry(void) { heads = (user_heads ? user_heads : pt_heads ? pt_heads : kern_heads ? kern_heads : 255); @@ -1473,8 +1473,8 @@ void decide_on_geometry(void) print_warning(_("You specified more cylinders than fit on disk")); } -void clear_p_info(void) -{ +static void +clear_p_info(void) { num_parts = 1; p_info[0].first_sector = 0; p_info[0].last_sector = total_size - 1; @@ -1491,8 +1491,8 @@ void clear_p_info(void) ext_info.num = PRIMARY; } -void fill_p_info(void) -{ +static void +fill_p_info(void) { int pn, i, bs, bsz; struct partition *p; partition_table buffer; @@ -1602,8 +1602,8 @@ void fill_p_info(void) } } -void fill_part_table(struct partition *p, partition_info *pi) -{ +static void +fill_part_table(struct partition *p, partition_info *pi) { int begin; p->boot_ind = pi->flags; @@ -1618,8 +1618,8 @@ void fill_part_table(struct partition *p, partition_info *pi) set_hsc_end(p, pi->last_sector); } -void fill_primary_table(partition_table *buffer) -{ +static void +fill_primary_table(partition_table *buffer) { int i; /* Zero out existing table */ @@ -1637,8 +1637,8 @@ void fill_primary_table(partition_table *buffer) buffer->p.magicflag[1] = PART_TABLE_FLAG1; } -void fill_logical_table(partition_table *buffer, partition_info *pi) -{ +static void +fill_logical_table(partition_table *buffer, partition_info *pi) { struct partition *p; int i; @@ -1674,8 +1674,8 @@ void fill_logical_table(partition_table *buffer, partition_info *pi) buffer->p.magicflag[1] = PART_TABLE_FLAG1; } -void write_part_table(void) -{ +static void +write_part_table(void) { int i, ct, done = FALSE, len; partition_table buffer; struct stat s; @@ -1755,8 +1755,8 @@ void write_part_table(void) print_warning(_("Not precisely one primary partition is bootable. DOS MBR cannot boot this.")); } -void fp_printf(FILE *fp, char *format, ...) -{ +static void +fp_printf(FILE *fp, char *format, ...) { va_list args; char buf[1024]; int y, x; @@ -1780,8 +1780,8 @@ void fp_printf(FILE *fp, char *format, ...) } #define MAX_PER_LINE 16 -void print_file_buffer(FILE *fp, char *buffer) -{ +static void +print_file_buffer(FILE *fp, char *buffer) { int i,l; for (i = 0, l = 0; i < SECTOR_SIZE; i++, l++) { @@ -1798,8 +1798,8 @@ void print_file_buffer(FILE *fp, char *buffer) fp_printf(fp, "\n"); } -void print_raw_table(void) -{ +static void +print_raw_table(void) { int i, to_file; partition_table buffer; char fname[LINE_LENGTH]; @@ -1852,8 +1852,8 @@ void print_raw_table(void) } } -void print_p_info_entry(FILE *fp, partition_info *p) -{ +static void +print_p_info_entry(FILE *fp, partition_info *p) { int size; char part_str[40]; @@ -1917,8 +1917,8 @@ void print_p_info_entry(FILE *fp, partition_info *p) fp_printf(fp, "\n"); } -void print_p_info(void) -{ +static void +print_p_info(void) { char fname[LINE_LENGTH]; FILE *fp; int i, to_file, pext = is_extended(ext_info.id); @@ -1969,8 +1969,8 @@ void print_p_info(void) } } -void print_part_entry(FILE *fp, int num, partition_info *pi) -{ +static void +print_part_entry(FILE *fp, int num, partition_info *pi) { int first = 0, start = 0, end = 0, size = 0; unsigned char ss, es, sh, eh; int sc, ec; @@ -2001,8 +2001,8 @@ void print_part_entry(FILE *fp, int num, partition_info *pi) } -void print_part_table(void) -{ +static void +print_part_table(void) { int i, j, to_file; char fname[LINE_LENGTH]; FILE *fp; @@ -2062,8 +2062,8 @@ void print_part_table(void) } } -void print_tables(void) -{ +static void +print_tables(void) { int done = FALSE; static struct MenuItem menuFormat[]= @@ -2096,8 +2096,8 @@ void print_tables(void) } #define END_OF_HELP "EOHS!" -void display_help() -{ +static void +display_help(void) { char *help_text[] = { N_("Help Screen for cfdisk"), "", @@ -2158,8 +2158,8 @@ void display_help() menuContinue(); } -int change_geometry(void) -{ +static int +change_geometry(void) { int ret_val = FALSE; int done = FALSE; char def[LINE_LENGTH]; @@ -2277,8 +2277,8 @@ int change_geometry(void) return ret_val; } -void change_id(int i) -{ +static void +change_id(int i) { char id[LINE_LENGTH], def[LINE_LENGTH]; int num_types = 0; int num_across, num_down; @@ -2351,8 +2351,8 @@ void change_id(int i) p_info[i].id = new_id; } -void draw_partition(int i) -{ +static void +draw_partition(int i) { int size, j; int y = i + DISK_TABLE_START + 2 - (cur_part/NUM_ON_SCREEN)*NUM_ON_SCREEN; char *t; @@ -2429,8 +2429,8 @@ void draw_partition(int i) mvprintw(y, COLUMNS-1, "*"); } -void init_const(void) -{ +static void +init_const(void) { if (!defined) { NAME_START = (((float)NAME_START)/COLUMNS)*COLS; FLAGS_START = (((float)FLAGS_START)/COLUMNS)*COLS; @@ -2451,8 +2451,8 @@ void init_const(void) } } -void draw_screen(void) -{ +static void +draw_screen(void) { int i; char *line; @@ -2514,8 +2514,8 @@ void draw_screen(void) free(line); } -int draw_cursor(int move) -{ +static int +draw_cursor(int move) { if (move != 0 && (cur_part + move < 0 || cur_part + move >= num_parts)) return -1; @@ -2543,8 +2543,8 @@ int draw_cursor(int move) return 0; } -void do_curses_fdisk(void) -{ +static void +do_curses_fdisk(void) { int done = FALSE; char command; @@ -2713,13 +2713,13 @@ void do_curses_fdisk(void) die_x(0); } -void copyright(void) -{ - fprintf(stderr, _("Copyright (C) 1994-1999 Kevin E. Martin & aeb\n")); +static void +copyright(void) { + fprintf(stderr, _("Copyright (C) 1994-2000 Kevin E. Martin & aeb\n")); } -void usage(char *prog_name) -{ +static void +usage(char *prog_name) { /* Unfortunately, xgettext does not handle multi-line strings */ /* so, let's use explicit \n's instead */ fprintf(stderr, _("\n" diff --git a/fdisk/common.h b/fdisk/common.h index a79d9acc..c5e23714 100644 --- a/fdisk/common.h +++ b/fdisk/common.h @@ -1,5 +1,11 @@ /* common stuff for fdisk, cfdisk, sfdisk */ +/* including <linux/fs.h> fails */ +#include <sys/ioctl.h> +#define BLKRRPART _IO(0x12,95) /* re-read partition table */ +#define BLKGETSIZE _IO(0x12,96) /* return device size */ +#define BLKFLSBUF _IO(0x12,97) /* flush buffer cache */ + struct systypes { unsigned char type; char *name; @@ -7,3 +13,4 @@ struct systypes { extern struct systypes i386_sys_types[]; +extern char *partname(char *dev, int pno, int lth); diff --git a/fdisk/delpart.c b/fdisk/delpart.c deleted file mode 100644 index 8504c022..00000000 --- a/fdisk/delpart.c +++ /dev/null @@ -1,40 +0,0 @@ -/* very primitive wrapper around the `delete partition' ioctl */ -#include <stdio.h> -#include <fcntl.h> -#include <stdlib.h> -#include <sys/ioctl.h> -#include <linux/blkpg.h> - -int -main(int argc, char **argv){ - int fd; - struct blkpg_ioctl_arg a; - struct blkpg_partition p; - - if (argc != 3) { - fprintf(stderr, - "usage: %s diskdevice partitionnr\n", - argv[0]); - exit(1); - } - if ((fd = open(argv[1], O_RDONLY)) < 0) { - perror(argv[1]); - exit(1); - } - p.pno = atoi(argv[2]); - p.start = 0; - p.length = 0; - p.devname[0] = 0; - p.volname[0] = 0; - a.op = BLKPG_DEL_PARTITION; - a.flags = 0; - a.datalen = sizeof(p); - a.data = &p; - - if (ioctl(fd, BLKPG, &a) == -1) { - perror("BLKPG"); - exit(1); - } - - return 0; -} diff --git a/fdisk/fdisk.8 b/fdisk/fdisk.8 index 2a8c85e8..aad93987 100644 --- a/fdisk/fdisk.8 +++ b/fdisk/fdisk.8 @@ -5,9 +5,9 @@ .SH NAME fdisk \- Partition table manipulator for Linux .SH SYNOPSIS -.BI "fdisk [\-u] " device +.BI "fdisk [\-u] [\-b sectorsize]" device .sp -.BI "fdisk \-l [\-u] [" "device ..." ] +.BI "fdisk \-l [\-u] [\-b sectorsize] [" "device ..." ] .sp .BI "fdisk \-s " "partition ..." .sp @@ -169,10 +169,10 @@ program and Linux partitions with the Linux fdisk or Linux cfdisk program. .SH OPTIONS .TP -.B \-v -Print version number of -.B fdisk -program and exit. +.BI "\-b " sectorsize +Specify the sector size of the disk. Valid values are 512, 1024, or 2048. +(Recent kernels know the sector size. Use this only on old kernels or +to override the kernel's ideas.) .TP .B \-l List the partition tables for the specified devices and then exit. @@ -188,6 +188,11 @@ of cylinders. The .I size of the partition (in blocks) is printed on the standard output. +.TP +.B \-v +Print version number of +.B fdisk +program and exit. .SH BUGS There are several *fdisk programs around. Each has its problems and strengths. diff --git a/fdisk/fdisk.c b/fdisk/fdisk.c index 56caa9a1..45110ccd 100644 --- a/fdisk/fdisk.c +++ b/fdisk/fdisk.c @@ -7,81 +7,27 @@ * published by the Free Software Foundation: either version 1 or * (at your option) any later version. * - * Before Linux version 0.95c, this program requires a kernel patch. - * - * Modified, Tue Feb 2 18:46:49 1993, faith@cs.unc.edu to better support SCSI. - * Modified, Sat Feb 27 18:11:27 1993, faith@cs.unc.edu: added extfs support. - * Modified, Sat Mar 6 10:14:12 1993, faith@cs.unc.edu: added more comments. - * Modified, Sat Mar 6 12:25:45 1993, faith@cs.unc.edu: - * Added patches from Michael Bischoff (i1041905@ws.rz.tu-bs.de - * or mbi@mo.math.nat.tu-bs.de) to fix the following problems: - * 1) Incorrect mapping of head/sector/cylinder to absolute sector - * 2) Odd sector count causes one sector to be lost - * Modified, Sat Mar 6 12:25:52 1993, faith@cs.unc.edu: improved verification. - * Modified, Sat Apr 17 15:00:00 1993, LeBlanc@mcc.ac.uk: add -s, fix -l. - * Modified, Sat Apr 24 10:00:00 1993, LeBlanc@mcc.ac.uk: fix overlap bug. - * Modified, Wed May 5 21:30:00 1993, LeBlanc@mcc.ac.uk: errors to stderr. - * Modified, Mon Mar 21 20:00:00 1994, LeBlanc@mcc.ac.uk: - * more stderr for messages, avoid division by 0, and - * give reboot message only if ioctl(fd, BLKRRPART) fails. - * Modified, Mon Apr 25 01:01:05 1994, martin@cs.unc.edu: - * 1) Added support for DOS, OS/2, ... compatibility. We should be able - * use this fdisk to partition our drives for other operating systems. - * 2) Added a print the raw data in the partition table command. - * Modified, Wed Jun 22 21:05:30 1994, faith@cs.unc.edu: - * Added/changed a few partition type names to conform to cfdisk. - * (suggested by Sujal, smpatel@wam.umd.edu) - * Modified 3/5/95 leisner@sdsp.mc.xerox.com -- on -l only open - * devices RDONLY (instead of RDWR). This allows you to - * have the disks as rw-r----- with group disk (and if you - * want is safe to setguid fdisk to disk). - * Modified Sat Mar 11 10:02 1995 with more partition types, faith@cs.unc.edu - * Modified, Thu May 4 01:11:45 1995, esr@snark.thyrsus.com: - * It's user-interface cleanup time. - * Actual error messages for out-of-bounds values (what a concept!). - * Enable read-only access to partition table for learners. - * Smart defaults for most numeric prompts. - * Fixed a bug preventing a partition from crossing cylinder 8064, aeb, 950801. - * Read partition table twice to avoid kernel bug - * (from Daniel Quinlan <quinlan@yggdrasil.com>), Tue Sep 26 10:25:28 1995 - * Modified, Sat Jul 1 23:43:16 MET DST 1995, fasten@cs.bonn.edu: - * editor for NetBSD/i386 (and Linux/Alpha?) disklabels. - * Tue Sep 26 17:07:54 1995: More patches from aeb. Fix segfaults, all >4GB. - * Don't destroy random data if extd partition starts past 4GB, aeb, 950818. - * Don't segfault on bad partition created by previous fdisk. - * Fixed for using variable blocksizes (needed by magnet-optical drive-patch) - * (from orschaer@cip.informatik.uni-erlangen.de) - * Modified, Fri Jul 14 11:13:35 MET DST 1996, jj@sunsite.mff.cuni.cz: - * editor for Sun disklabels. - * Modified, Wed Jul 3 10:14:17 MET DST 1996, jj@sunsite.mff.cuni.cz: - * support for Sun floppies - * Modified, Thu Jul 24 16:42:33 MET DST 1997, fasten@shw.com: - * LINUX_EXTENDED support - * Added Windows 95 partition types, aeb. - * Fixed a bug described by johnf@whitsunday.net.au, aeb, 980408. - * [There are lots of other bugs - nobody should use this program] - * [cfdisk on the other hand is nice and correct] - * Try to avoid reading a CD-ROM. - * Do not print Begin column -- it confuses too many people -- aeb, 980610. - * Modified, Sat Oct 3 14:40:17 MET DST 1998, ANeuper@GUUG.de - * Support SGI's partitioning -- an, 980930. - * Do the verify using LBA, not CHS, limits -- aeb, 981206. - * Corrected single-cylinder partition creating a little, now that - * ankry@mif.pg.gda.pl pointed out a bug; there are more bugs -- aeb, 990214. + * For detailed old history, see older versions. + * Contributions before 2000 by faith@cs.unc.edu, Michael Bischoff, + * LeBlanc@mcc.ac.uk, martin@cs.unc.edu, leisner@sdsp.mc.xerox.com, + * esr@snark.thyrsus.com, aeb@cwi.nl, quinlan@yggdrasil.com, + * fasten@cs.bonn.edu, orschaer@cip.informatik.uni-erlangen.de, + * jj@sunsite.mff.cuni.cz, fasten@shw.com, ANeuper@GUUG.de, + * kgw@suse.de. * - * Sat Mar 20 09:31:05 EST 1999 Arnaldo Carvalho de Melo <acme@conectiva.com.br> - * Internationalization + * Modified, Sun Feb 20 2000, kalium@gmx.de + * Added fix operation allowing to reorder primary/extended partition + * entries within the partition table. Some programs or OSes have + * problems using a partition table with entries not ordered + * according to their positions on disk. + * Munged this patch to also make it work for logical partitions. + * aeb, 2000-02-20. * - * Corrected deleting last logical partition -- aeb, 990430. - * Removed all assumptions on file names -- aeb, 990709 - * [modprobe gave ugly error messages, and the number of devices to probe - * increased all the time: hda, sda, eda, rd/c0d0, ida/c0d0, ... - * Also partition naming was very ugly.] + * Wed Mar 1 14:34:53 EST 2000 David Huggins-Daines <dhuggins@linuxcare.com> + * Better support for OSF/1 disklabels on Alpha. * - * Corrected a bug where creating an extended hda3, say, then a logical hda5 - * that does not start at the beginning of hda3, then a logical hda6 that does - * start at the beginning of hda3 would wipe out the partition table describing - * hda5. [Patch by Klaus G. Wagner" <kgw@suse.de>] -- aeb, 990711 + * 2000-04-06, Michal Jaegermann (michal@ellpspace.math.ualberta.ca) + * fixed and added some alpha stuff. */ @@ -94,14 +40,11 @@ #include <setjmp.h> #include <errno.h> #include <getopt.h> -#include "nls.h" - #include <sys/stat.h> -#include <sys/ioctl.h> #include <linux/hdreg.h> /* for HDIO_GETGEO */ -#include <linux/fs.h> /* for BLKRRPART, BLKGETSIZE */ +#include "nls.h" #include "common.h" #include "fdisk.h" @@ -122,7 +65,7 @@ #define LINE_LENGTH 80 -#define offset(b, n) ((struct partition *)((b) + 0x1be + \ +#define pt_offset(b, n) ((struct partition *)((b) + 0x1be + \ (n) * sizeof(struct partition))) #define sector(s) ((s) & 0x3f) #define cylinder(s, c) ((c) | (((s) & 0xc0) << 2)) @@ -139,7 +82,7 @@ } /* A valid partition table sector ends in 0x55 0xaa */ -unsigned int +static unsigned int part_table_flag(char *b) { return ((uint) b[510]) + (((uint) b[511]) << 8); } @@ -149,7 +92,7 @@ valid_part_table_flag(unsigned char *b) { return (b[510] == 0x55 && b[511] == 0xaa); } -void +static void write_part_table_flag(char *b) { b[510] = 0x55; b[511] = 0xaa; @@ -157,7 +100,7 @@ write_part_table_flag(char *b) { /* start_sect and nr_sects are stored little endian on all machines */ /* moreover, they are not aligned correctly */ -void +static void store4_little_endian(unsigned char *cp, unsigned int val) { cp[0] = (val & 0xff); cp[1] = ((val >> 8) & 0xff); @@ -165,13 +108,13 @@ store4_little_endian(unsigned char *cp, unsigned int val) { cp[3] = ((val >> 24) & 0xff); } -unsigned int +static unsigned int read4_little_endian(unsigned char *cp) { return (uint)(cp[0]) + ((uint)(cp[1]) << 8) + ((uint)(cp[2]) << 16) + ((uint)(cp[3]) << 24); } -void +static void set_start_sect(struct partition *p, unsigned int start_sect) { store4_little_endian(p->start4, start_sect); } @@ -181,7 +124,7 @@ get_start_sect(struct partition *p) { return read4_little_endian(p->start4); } -void +static void set_nr_sects(struct partition *p, unsigned int nr_sects) { store4_little_endian(p->size4, nr_sects); } @@ -194,13 +137,31 @@ get_nr_sects(struct partition *p) { /* normally O_RDWR, -l option gives O_RDONLY */ static int type_open = O_RDWR; +/* + * Raw disk label. For DOS-type partition tables the MBR, + * with descriptions of the primary partitions. + */ +char MBRbuffer[MAX_SECTOR_SIZE]; + +/* + * per partition table entry data + * + * The four primary partitions have the same sectorbuffer (MBRbuffer) + * and have NULL ext_pointer. + * Each logical partition table entry has two pointers, one for the + * partition and one link to the next one. + */ +struct pte { + struct partition *part_table; /* points into sectorbuffer */ + struct partition *ext_pointer; /* points into sectorbuffer */ + char changed; /* boolean */ + uint offset; /* disk sector number */ + char *sectorbuffer; /* disk sector contents */ +} ptes[MAXIMUM_PARTS]; + char *disk_device, /* must be specified */ *line_ptr, /* interactive input */ - line_buffer[LINE_LENGTH], - changed[MAXIMUM_PARTS], /* marks changed buffers */ - buffer[MAX_SECTOR_SIZE], /* first four partitions */ - *buffers[MAXIMUM_PARTS] /* pointers to buffers */ - = {buffer, buffer, buffer, buffer}; + line_buffer[LINE_LENGTH]; int fd, /* the disk */ ext_index, /* the prime extended partition */ @@ -209,6 +170,8 @@ int fd, /* the disk */ dos_compatible_flag = ~0, partitions = 4; /* maximum partition + 1 */ +uint user_cylinders, user_heads, user_sectors; + uint heads, sectors, cylinders, @@ -216,23 +179,16 @@ uint heads, sector_offset = 1, units_per_sector = 1, display_in_cyl_units = 1, - extended_offset = 0, /* offset of link pointers */ - offsets[MAXIMUM_PARTS] = {0, 0, 0, 0}; + extended_offset = 0; /* offset of link pointers */ +#define dos_label (!sun_label && !sgi_label && !aix_label && !osf_label) int sun_label = 0; /* looking at sun disklabel */ int sgi_label = 0; /* looking at sgi disklabel */ int aix_label = 0; /* looking at aix disklabel */ - -struct partition *part_table[MAXIMUM_PARTS] /* partitions */ - = {offset(buffer, 0), offset(buffer, 1), - offset(buffer, 2), offset(buffer, 3)}, - *ext_pointers[MAXIMUM_PARTS] /* link pointers */ - = {NULL, NULL, NULL, NULL}; - +int osf_label = 0; /* looking at osf disklabel */ jmp_buf listingbuf; -void fatal(enum failure why) -{ +void fatal(enum failure why) { char error[LINE_LENGTH], *message = error; @@ -289,8 +245,66 @@ void fatal(enum failure why) exit(1); } -void menu(void) -{ +static void +seek_sector(int fd, uint secno) { + ext2_loff_t offset = (ext2_loff_t) secno * sector_size; + if (ext2_llseek(fd, offset, SEEK_SET) == (ext2_loff_t) -1) + fatal(unable_to_seek); +} + +static void +read_sector(int fd, uint secno, char *buf) { + seek_sector(fd, secno); + if (read(fd, buf, sector_size) != sector_size) + fatal(unable_to_read); +} + +static void +write_sector(int fd, uint secno, char *buf) { + seek_sector(fd, secno); + if (write(fd, buf, sector_size) != sector_size) + fatal(unable_to_write); +} + +/* Allocate a buffer and read a partition table sector */ +static void +read_pte(int fd, int pno, uint offset) { + struct pte *pe = &ptes[pno]; + + pe->offset = offset; + pe->sectorbuffer = (char *) malloc(sector_size); + if (!pe->sectorbuffer) + fatal(out_of_memory); + read_sector(fd, offset, pe->sectorbuffer); + pe->changed = 0; + pe->part_table = pe->ext_pointer = NULL; +} + +static unsigned int +get_partition_start(struct pte *pe) { + return pe->offset + get_start_sect(pe->part_table); +} + +struct partition * +get_part_table(int i) { + return ptes[i].part_table; +} + +void +set_all_unchanged(void) { + int i; + + for (i = 0; i < MAXIMUM_PARTS; i++) + ptes[i].changed = 0; +} + +void +set_changed(int i) { + ptes[i].changed = 1; +} + +static void +menu(void) { if (sun_label) { puts(_("Command action")); puts(_(" a toggle a read only flag")); /* sun */ @@ -356,11 +370,11 @@ void menu(void) } } -void xmenu(void) -{ +static void +xmenu(void) { if (sun_label) { puts(_("Command action")); - puts(_(" a change number of alternate cylinders")); /*sun*/ + puts(_(" a change number of alternate cylinders")); /*sun*/ puts(_(" c change number of cylinders")); puts(_(" d print the raw data in the partition table")); puts(_(" e change number of extra sectors per cylinder"));/*sun*/ @@ -376,12 +390,45 @@ void xmenu(void) puts(_(" w write table to disk and exit")); puts(_(" y change number of physical cylinders")); /*sun*/ } + else if(sgi_label) { + puts(_("Command action")); + puts(_(" b move beginning of data in a partition")); /* !sun */ + puts(_(" c change number of cylinders")); + puts(_(" d print the raw data in the partition table")); + puts(_(" e list extended partitions")); /* !sun */ + puts(_(" g create an IRIX partition table")); /* sgi */ + puts(_(" h change number of heads")); + puts(_(" m print this menu")); + puts(_(" p print the partition table")); + puts(_(" q quit without saving changes")); + puts(_(" r return to main menu")); + puts(_(" s change number of sectors/track")); + puts(_(" v verify the partition table")); + puts(_(" w write table to disk and exit")); + } + else if(aix_label) { + puts(_("Command action")); + puts(_(" b move beginning of data in a partition")); /* !sun */ + puts(_(" c change number of cylinders")); + puts(_(" d print the raw data in the partition table")); + puts(_(" e list extended partitions")); /* !sun */ + puts(_(" g create an IRIX partition table")); /* sgi */ + puts(_(" h change number of heads")); + puts(_(" m print this menu")); + puts(_(" p print the partition table")); + puts(_(" q quit without saving changes")); + puts(_(" r return to main menu")); + puts(_(" s change number of sectors/track")); + puts(_(" v verify the partition table")); + puts(_(" w write table to disk and exit")); + } else { puts(_("Command action")); puts(_(" b move beginning of data in a partition")); /* !sun */ puts(_(" c change number of cylinders")); puts(_(" d print the raw data in the partition table")); puts(_(" e list extended partitions")); /* !sun */ + puts(_(" f fix partition order")); /* !sun, !aix, !sgi */ puts(_(" g create an IRIX partition table")); /* sgi */ puts(_(" h change number of heads")); puts(_(" m print this menu")); @@ -391,17 +438,17 @@ void xmenu(void) puts(_(" s change number of sectors/track")); puts(_(" v verify the partition table")); puts(_(" w write table to disk and exit")); - } + } } -int +static int get_sysid(int i) { return ( sun_label ? sunlabel->infos[i].id : - sgi_label ? sgi_get_sysid(i) : part_table[i]->sys_ind); + sgi_label ? sgi_get_sysid(i) : ptes[i].part_table->sys_ind); } -struct systypes * +static struct systypes * get_sys_types(void) { return ( sun_label ? sun_sys_types : @@ -444,8 +491,10 @@ void list_types(struct systypes *sys) putchar('\n'); } -void clear_partition(struct partition *p) -{ +static void +clear_partition(struct partition *p) { + if (!p) + return; p->boot_ind = 0; p->head = 0; p->sector = 0; @@ -458,9 +507,9 @@ void clear_partition(struct partition *p) set_nr_sects(p,0); } -void set_partition(int i, struct partition *p, uint start, uint stop, - int sysid, uint offset) -{ +static void +set_partition(int i, struct partition *p, uint start, uint stop, + int sysid, uint offset) { p->boot_ind = 0; p->sys_ind = sysid; set_start_sect(p, start - offset); @@ -471,11 +520,11 @@ void set_partition(int i, struct partition *p, uint start, uint stop, if (dos_compatible_flag && (stop/(sectors*heads) > 1023)) stop = heads*sectors*1024 - 1; set_hsc(p->end_head, p->end_sector, p->end_cyl, stop); - changed[i] = 1; + ptes[i].changed = 1; } -int test_c(char **m, char *mesg) -{ +static int +test_c(char **m, char *mesg) { int val = 0; if (!*m) fprintf(stderr, _("You must set")); @@ -487,8 +536,8 @@ int test_c(char **m, char *mesg) return val; } -int warn_geometry(void) -{ +static int +warn_geometry(void) { char *m = NULL; int prev = 0; if (!heads) @@ -515,85 +564,95 @@ void update_units(void) units_per_sector = 1; /* in sectors */ } -void warn_cylinders(void) -{ - if (!sun_label && !sgi_label && cylinders > 1024 && !nowarn) +static void +warn_cylinders(void) { + if (dos_label && cylinders > 1024 && !nowarn) fprintf(stderr, "\n\ The number of cylinders for this disk is set to %d.\n\ There is nothing wrong with that, but this is larger than 1024,\n\ and could in certain setups cause problems with:\n\ -1) software that runs at boot time (e.g., LILO)\n\ +1) software that runs at boot time (e.g., old versions of LILO)\n\ 2) booting and partitioning software from other OSs\n\ (e.g., DOS FDISK, OS/2 FDISK)\n", cylinders); } -void read_extended(struct partition *p) -{ +static void +read_extended(int ext) { int i; - struct partition *q; + struct pte *pex; + struct partition *p, *q; + + ext_index = ext; + pex = &ptes[ext]; + pex->ext_pointer = pex->part_table; - ext_pointers[ext_index] = part_table[ext_index]; + p = pex->part_table; if (!get_start_sect(p)) fprintf(stderr, _("Bad offset in primary extended partition\n")); else while (IS_EXTENDED (p->sys_ind)) { + struct pte *pe = &ptes[partitions]; + if (partitions >= MAXIMUM_PARTS) { /* This is not a Linux restriction, but this program uses arrays of size MAXIMUM_PARTS. Do not try to `improve' this test. */ + struct pte *pre = &ptes[partitions-1]; + fprintf(stderr, _("Warning: deleting partitions after %d\n"), partitions); - clear_partition(ext_pointers[partitions - 1]); - changed[partitions - 1] = 1; + clear_partition(pre->ext_pointer); + pre->changed = 1; return; } - offsets[partitions] = extended_offset + get_start_sect(p); + + read_pte(fd, partitions, extended_offset + get_start_sect(p)); + if (!extended_offset) extended_offset = get_start_sect(p); - if (ext2_llseek(fd, (ext2_loff_t)offsets[partitions] - * sector_size, SEEK_SET) < 0) - fatal(unable_to_seek); - if (!(buffers[partitions] = (char *) malloc(sector_size))) - fatal(out_of_memory); - if (sector_size != read(fd, buffers[partitions], sector_size)) - fatal(unable_to_read); - part_table[partitions] = ext_pointers[partitions] = NULL; - q = p = offset(buffers[partitions], 0); + + q = p = pt_offset(pe->sectorbuffer, 0); for (i = 0; i < 4; i++, p++) { if (IS_EXTENDED (p->sys_ind)) { - if (ext_pointers[partitions]) - fprintf(stderr, _("Warning: extra link " - "pointer in partition table " - "%d\n"), partitions + 1); + if (pe->ext_pointer) + fprintf(stderr, _("Warning: extra link" + " pointer in partition table " + "%d\n"), partitions + 1); else - ext_pointers[partitions] = p; + pe->ext_pointer = p; } else if (p->sys_ind) { - if (part_table[partitions]) + if (pe->part_table) fprintf(stderr, _("Warning: ignoring extra data " - "in partition table %d\n"), + "in partition table %d\n"), partitions + 1); else - part_table[partitions] = p; + pe->part_table = p; } } - if (!part_table[partitions]) { - if (q != ext_pointers[partitions]) - part_table[partitions] = q; - else part_table[partitions] = q + 1; + + /* very strange code here... */ + if (!pe->part_table) { + if (q != pe->ext_pointer) + pe->part_table = q; + else + pe->part_table = q + 1; } - if (!ext_pointers[partitions]) { - if (q != part_table[partitions]) - ext_pointers[partitions] = q; - else ext_pointers[partitions] = q + 1; + if (!pe->ext_pointer) { + if (q != pe->part_table) + pe->ext_pointer = q; + else + pe->ext_pointer = q + 1; } - p = ext_pointers[partitions++]; + + p = pe->ext_pointer; + partitions++; } } -void create_doslabel(void) -{ +static void +create_doslabel(void) { int i; fprintf(stderr, @@ -604,38 +663,17 @@ void create_doslabel(void) sun_nolabel(); /* otherwise always recognised as sun */ sgi_nolabel(); /* otherwise always recognised as sgi */ - write_part_table_flag(buffer); + write_part_table_flag(MBRbuffer); for (i = 0; i < 4; i++) - clear_partition(part_table[i]); - for (i = 1; i < MAXIMUM_PARTS; i++) - changed[i] = 0; - changed[0] = 1; + if (ptes[i].part_table) + clear_partition(ptes[i].part_table); + set_all_unchanged(); + set_changed(0); get_boot(create_empty); } -/* - * Read MBR. Returns: - * -1: no 0xaa55 flag present (possibly entire disk BSD) - * 0: found or created label - */ -int get_boot(enum action what) -{ - int i, sec_fac; - struct hd_geometry geometry; - - partitions = 4; - sec_fac = sector_size / 512; - - if (what == create_empty) - goto got_table; /* skip reading disk */ - - if ((fd = open(disk_device, type_open)) < 0) { - if ((fd = open(disk_device, O_RDONLY)) < 0) - fatal(unable_to_open); - else - printf(_("You will not be able to write the partition table.\n")); - } - +static void +get_sectorsize(int fd) { #if defined(BLKSSZGET) && defined(HAVE_blkpg_h) /* For a short while BLKSSZGET gave a wrong sector size */ { int arg; @@ -645,36 +683,95 @@ int get_boot(enum action what) printf(_("Note: sector size is %d (not %d)\n"), sector_size, DEFAULT_SECTOR_SIZE); } +#else + sector_size = DEFAULT_SECTOR_SIZE; #endif +} - guess_device_type(fd); +/* + * Ask kernel about geometry. Invent something reasonable + * in case the kernel has no opinion. + */ +void +get_geometry(int fd, struct geom *g) { + int sec_fac; + long longsectors; + struct hd_geometry geometry; + int res1, res2; - if (sector_size != read(fd, buffer, sector_size)) - fatal(unable_to_read); + get_sectorsize(fd); + sec_fac = sector_size / 512; + guess_device_type(fd); + + res1 = ioctl(fd, BLKGETSIZE, &longsectors); #ifdef HDIO_REQ - if (!ioctl(fd, HDIO_REQ, &geometry)) { + res2 = ioctl(fd, HDIO_REQ, &geometry); #else - if (!ioctl(fd, HDIO_GETGEO, &geometry)) { + res2 = ioctl(fd, HDIO_GETGEO, &geometry); #endif + + /* never use geometry.cylinders - it is truncated */ + heads = cylinders = sectors = 0; + sector_offset = 1; + if (res2 == 0) { heads = geometry.heads; sectors = geometry.sectors; - cylinders = geometry.cylinders; - cylinders /= sec_fac; /* do not round up */ - if (dos_compatible_flag) + if (heads * sectors == 0) + res2 = -1; + else if (dos_compatible_flag) sector_offset = sectors; - } else { - long longsectors; - if (!ioctl(fd, BLKGETSIZE, &longsectors)) { - heads = 1; - cylinders = 1; - sectors = longsectors / sec_fac; - } else { - heads = cylinders = sectors = 0; - } } + if (res1 == 0 && res2 == 0) { /* normal case */ + cylinders = longsectors / (heads * sectors); + cylinders /= sec_fac; /* do not round up */ + } else if (res1 == 0) { /* size but no geometry */ + heads = cylinders = 1; + sectors = longsectors / sec_fac; + } + + if (!sectors) + sectors = user_sectors; + if (!heads) + heads = user_heads; + if (!cylinders) + cylinders = user_cylinders; + + if (g) { + g->heads = heads; + g->sectors = sectors; + g->cylinders = cylinders; + } +} + +/* + * Read MBR. Returns: + * -1: no 0xaa55 flag present (possibly entire disk BSD) + * 0: found or created label + */ +int +get_boot(enum action what) { + int i; + + partitions = 4; + + if (what == create_empty) + goto got_table; /* skip reading disk */ + + if ((fd = open(disk_device, type_open)) < 0) { + if ((fd = open(disk_device, O_RDONLY)) < 0) + fatal(unable_to_open); + else + printf(_("You will not be able to write the partition table.\n")); + } + + get_geometry(fd, NULL); + update_units(); + if (sector_size != read(fd, MBRbuffer, sector_size)) + fatal(unable_to_read); + got_table: if (check_sun_label()) @@ -686,12 +783,15 @@ got_table: if (check_aix_label()) return 0; - if (!valid_part_table_flag(buffer)) { + if (check_osf_label()) + return 0; + + if (!valid_part_table_flag(MBRbuffer)) { switch(what) { case fdisk: fprintf(stderr, _("Device contains neither a valid DOS partition" - " table, nor Sun or SGI disklabel\n")); + " table, nor Sun, SGI or OSF disklabel\n")); #ifdef __sparc__ create_sunlabel(); #else @@ -713,21 +813,39 @@ got_table: warn_cylinders(); warn_geometry(); - for (i = 0; i < 4; i++) - if(IS_EXTENDED (part_table[i]->sys_ind)) { + for (i = 0; i < 4; i++) { + struct pte *pe = &ptes[i]; + + pe->part_table = pt_offset(MBRbuffer, i); + pe->ext_pointer = NULL; + pe->changed = 0; + pe->offset = 0; + pe->sectorbuffer = MBRbuffer; + } + + for (i = 0; i < 4; i++) { + struct pte *pe = &ptes[i]; + + if (IS_EXTENDED (pe->part_table->sys_ind)) { if (partitions != 4) fprintf(stderr, _("Ignoring extra extended " "partition %d\n"), i + 1); - else read_extended(part_table[ext_index = i]); + else + read_extended(i); } - for (i = 3; i < partitions; i++) - if (!valid_part_table_flag(buffers[i])) { + } + + for (i = 3; i < partitions; i++) { + struct pte *pe = &ptes[i]; + + if (!valid_part_table_flag(pe->sectorbuffer)) { fprintf(stderr, _("Warning: invalid flag 0x%04x of partition " "table %d will be corrected by w(rite)\n"), - part_table_flag(buffers[i]), i + 1); - changed[i] = 1; + part_table_flag(pe->sectorbuffer), i + 1); + pe->changed = 1; } + } return 0; } @@ -874,7 +992,7 @@ read_int(uint low, uint dflt, uint high, uint base, char *mesg) } } if (use_default) - printf(_("Using default value %d\n"), i = dflt); + printf(_("Using default value %d\n"), i = dflt); if (i >= low && i <= high) break; else @@ -883,12 +1001,16 @@ read_int(uint low, uint dflt, uint high, uint base, char *mesg) return i; } -int get_partition(int warn, int max) -{ - int i = read_int(1, 0, max, 0, _("Partition number")) - 1; +int +get_partition(int warn, int max) { + struct pte *pe; + int i; + + i = read_int(1, 0, max, 0, _("Partition number")) - 1; + pe = &ptes[i]; if (warn && ( - (!sun_label && !sgi_label && !part_table[i]->sys_ind) + (!sun_label && !sgi_label && !pe->part_table->sys_ind) || (sun_label && (!sunlabel->partitions[i].num_sectors || !sunlabel->infos[i].id)) @@ -897,8 +1019,8 @@ int get_partition(int warn, int max) return i; } -char *const str_units(int n) /* n==1: use singular */ -{ +char * const +str_units(int n) { /* n==1: use singular */ if (n == 1) return display_in_cyl_units ? _("cylinder") : _("sector"); else @@ -913,22 +1035,21 @@ void change_units(void) str_units(PLURAL)); } -void toggle_active(int i) -{ - struct partition *p = part_table[i]; +static void +toggle_active(int i) { + struct pte *pe = &ptes[i]; + struct partition *p = pe->part_table; if (IS_EXTENDED (p->sys_ind) && !p->boot_ind) fprintf(stderr, _("WARNING: Partition %d is an extended partition\n"), i + 1); - if (p->boot_ind) - p->boot_ind = 0; - else p->boot_ind = ACTIVE_FLAG; - changed[i] = 1; + p->boot_ind = (p->boot_ind ? 0 : ACTIVE_FLAG); + pe->changed = 1; } -void toggle_dos(void) -{ +static void +toggle_dos_compatibility_flag(void) { dos_compatible_flag = ~dos_compatible_flag; if (dos_compatible_flag) { sector_offset = sectors; @@ -940,9 +1061,11 @@ void toggle_dos(void) } } -void delete_partition(int i) -{ - struct partition *p = part_table[i], *q = ext_pointers[i]; +static void +delete_partition(int i) { + struct pte *pe = &ptes[i]; + struct partition *p = pe->part_table; + struct partition *q = pe->ext_pointer; /* Note that for the fifth partition (i == 4) we don't actually * decrement partitions. @@ -950,7 +1073,7 @@ void delete_partition(int i) if (warn_geometry()) return; - changed[i] = 1; + pe->changed = 1; if (sun_label) { sun_delete_partition(i); @@ -962,21 +1085,21 @@ void delete_partition(int i) } if (i < 4) { if (IS_EXTENDED (p->sys_ind) && i == ext_index) { - while (partitions > 4) - free(buffers[--partitions]); - ext_pointers[ext_index] = NULL; + partitions = 4; + ptes[ext_index].ext_pointer = NULL; extended_offset = 0; } clear_partition(p); } else if (!q->sys_ind && i > 4) { - free(buffers[--partitions]); - clear_partition(ext_pointers[--i]); - changed[i] = 1; + --partitions; + --i; + clear_partition(ptes[i].ext_pointer); + ptes[i].changed = 1; } else if (i > 3) { if (i > 4) { - p = ext_pointers[i - 1]; + p = ptes[i-1].ext_pointer; p->boot_ind = 0; p->head = q->head; p->sector = q->sector; @@ -987,37 +1110,33 @@ void delete_partition(int i) p->end_cyl = q->end_cyl; set_start_sect(p, get_start_sect(q)); set_nr_sects(p, get_nr_sects(q)); - changed[i - 1] = 1; + ptes[i-1].changed = 1; } else { - if(part_table[5]) /* prevent SEGFAULT */ - set_start_sect(part_table[5], - get_start_sect(part_table[5]) + - offsets[5] - extended_offset); - offsets[5] = extended_offset; - changed[5] = 1; + struct pte *pe = &ptes[5]; + + if(pe->part_table) /* prevent SEGFAULT */ + set_start_sect(pe->part_table, + get_partition_start(pe) - + extended_offset); + pe->offset = extended_offset; + pe->changed = 1; } if (partitions > 5) { partitions--; - free(buffers[i]); while (i < partitions) { - changed[i] = changed[i + 1]; - buffers[i] = buffers[i + 1]; - offsets[i] = offsets[i + 1]; - part_table[i] = part_table[i + 1]; - ext_pointers[i] = ext_pointers[i + 1]; + ptes[i] = ptes[i+1]; i++; } - } - else - clear_partition(part_table[i]); + } else + clear_partition(ptes[i].part_table); } } -void change_sysid(void) -{ +static void +change_sysid(void) { char *temp; int i = get_partition(0, partitions), sys, origsys; - struct partition *p = part_table[i]; + struct partition *p = ptes[i].part_table; origsys = sys = get_sysid(i); @@ -1064,12 +1183,12 @@ void change_sysid(void) if (sgi_label) { sgi_change_sysid(i, sys); } else - part_table[i]->sys_ind = sys; + p->sys_ind = sys; printf (_("Changed system type of partition %d " "to %x (%s)\n"), i + 1, sys, (temp = partition_type(sys)) ? temp : _("Unknown")); - changed[i] = 1; + ptes[i].changed = 1; break; } } @@ -1080,8 +1199,7 @@ void change_sysid(void) * Jan. 1990 (version 1.2.1 by Gordon W. Ross Aug. 1990; Modified by S. * Lubkin Oct. 1991). */ -static void long2chs(ulong ls, uint *c, uint *h, uint *s) -{ +static void long2chs(ulong ls, uint *c, uint *h, uint *s) { int spc = heads * sectors; *c = ls / spc; @@ -1090,8 +1208,7 @@ static void long2chs(ulong ls, uint *c, uint *h, uint *s) *s = ls % sectors + 1; /* sectors count from 1 */ } -static void check_consistency(struct partition *p, int partition) -{ +static void check_consistency(struct partition *p, int partition) { uint pbc, pbh, pbs; /* physical beginning c, h, s */ uint pec, peh, pes; /* physical ending c, h, s */ uint lbc, lbh, lbs; /* logical beginning c, h, s */ @@ -1152,18 +1269,91 @@ static void check_consistency(struct partition *p, int partition) } } -void list_disk_geometry(void) -{ +static void +list_disk_geometry(void) { printf(_("\nDisk %s: %d heads, %d sectors, %d cylinders\nUnits = " "%s of %d * %d bytes\n\n"), disk_device, heads, sectors, cylinders, str_units(PLURAL), units_per_sector, sector_size); } -void list_table(int xtra) -{ +/* + * Check whether partition entries are ordered by their starting positions. + * Return 0 if OK. Return i if partition i should have been earlier. + * Two separate checks: primary and logical partitions. + */ +static int +wrong_p_order(int *prev) { + struct pte *pe; + struct partition *p; + uint last_p_start_pos = 0, p_start_pos; + int i, last_i = 0; + + for (i = 0 ; i < partitions; i++) { + if (i == 4) { + last_i = 4; + last_p_start_pos = 0; + } + pe = &ptes[i]; + if ((p = pe->part_table)->sys_ind) { + p_start_pos = get_partition_start(pe); + + if (last_p_start_pos > p_start_pos) { + if (prev) + *prev = last_i; + return i; + } + + last_p_start_pos = p_start_pos; + last_i = i; + } + } + return 0; +} + +static void +fix_partition_table_order(void) { + struct pte *pei, *pek, ptebuf; + int i,k; + + if(!wrong_p_order(NULL)) { + printf(_("Nothing to do. Ordering is correct already.\n\n")); + return; + } + + while ((i = wrong_p_order(&k)) != 0) { + /* partition i should have come earlier, move it */ + pei = &ptes[i]; + pek = &ptes[k]; + + if (i < 4) { + /* We have to move data in the MBR */ + struct partition *pi, *pk, *pe, pbuf; + + pe = pei->ext_pointer; + pei->ext_pointer = pek->ext_pointer; + pek->ext_pointer = pe; + + pi = pei->part_table; + pk = pek->part_table; + + memmove(&pbuf, pi, sizeof(struct partition)); + memmove(pi, pk, sizeof(struct partition)); + memmove(pk, &pbuf, sizeof(struct partition)); + } else { + /* Only change is change in numbering */ + ptebuf = *pei; + *pei = *pek; + *pek = ptebuf; + } + pei->changed = pek->changed = 1; + + } +} + +static void +list_table(int xtra) { struct partition *p; char *type; - int digit_last = 0; int i, w; if (sun_label) { @@ -1176,26 +1366,30 @@ void list_table(int xtra) return; } - w = strlen(disk_device); + list_disk_geometry(); + + if (osf_label) { + xbsd_print_disklabel(xtra); + return; + } + /* Heuristic: we list partition 3 of /dev/foo as /dev/foo3, but if the device name ends in a digit, say /dev/foo1, then the partition is called /dev/foo1p3. */ - if (isdigit(disk_device[w-1])) - digit_last = 1; - - list_disk_geometry(); - + w = strlen(disk_device); + if (w && isdigit(disk_device[w-1])) + w++; if (w < 5) w = 5; - /* FIXME! let's see how this shows up with other languagues - acme@conectiva.com.br */ - printf(_("%*s Boot Start End Blocks Id System\n"), - (digit_last ? w + 2 : w + 1), _("Device")); + w+1, _("Device")); for (i = 0 ; i < partitions; i++) { - if ((p = part_table[i])->sys_ind) { + struct pte *pe = &ptes[i]; + + p = pe->part_table; + if (p->sys_ind) { unsigned int psects = get_nr_sects(p); unsigned int pblocks = psects; unsigned int podd = 0; @@ -1207,12 +1401,12 @@ void list_table(int xtra) if (sector_size > 1024) pblocks *= (sector_size / 1024); printf( - "%*s%s%-2d %c %9ld %9ld %9ld%c %2x %s\n", -/* device */ w, disk_device, (digit_last ? "p" : ""), i+1, + "%s %c %9ld %9ld %9ld%c %2x %s\n", + partname(disk_device, i+1, w+2), /* boot flag */ !p->boot_ind ? ' ' : p->boot_ind == ACTIVE_FLAG ? '*' : '?', -/* start */ (long) cround(get_start_sect(p) + offsets[i]), -/* end */ (long) cround(get_start_sect(p) + offsets[i] + psects +/* start */ (long) cround(get_partition_start(pe)), +/* end */ (long) cround(get_partition_start(pe) + psects - (psects ? 1 : 0)), /* odd flag on end */ (long) pblocks, podd ? '+' : ' ', /* type id */ p->sys_ind, @@ -1221,22 +1415,28 @@ void list_table(int xtra) check_consistency(p, i); } } + + /* Is partition table in disk order? It need not be, but... */ + /* partition table entries are not checked for correct order if this + is a sgi, sun or aix labeled disk... */ + if (dos_label && wrong_p_order(NULL)) { + printf(_("\nPartition table entries are not in disk order\n")); + } } -void x_list_table(int extend) -{ - struct partition *p, **q; +static void +x_list_table(int extend) { + struct pte *pe; + struct partition *p; int i; - if (extend) - q = ext_pointers; - else - q = part_table; printf(_("\nDisk %s: %d heads, %d sectors, %d cylinders\n\n"), disk_device, heads, sectors, cylinders); printf(_("Nr AF Hd Sec Cyl Hd Sec Cyl Start Size ID\n")); - for (i = 0 ; i < partitions; i++) - if ((p = q[i]) != NULL) { + for (i = 0 ; i < partitions; i++) { + pe = &ptes[i]; + p = (extend ? pe->ext_pointer : pe->part_table); + if (p != NULL) { printf("%2d %02x%4d%4d%5d%4d%4d%5d%9d%9d %02x\n", i + 1, p->boot_ind, p->head, sector(p->sector), @@ -1247,26 +1447,29 @@ void x_list_table(int extend) if (p->sys_ind) check_consistency(p, i); } + } } -void fill_bounds(uint *first, uint *last) -{ +static void +fill_bounds(uint *first, uint *last) { int i; - struct partition *p = part_table[0]; + struct pte *pe = &ptes[0]; + struct partition *p; - for (i = 0; i < partitions; p = part_table[++i]) { + for (i = 0; i < partitions; pe++,i++) { + p = pe->part_table; if (!p->sys_ind || IS_EXTENDED (p->sys_ind)) { first[i] = 0xffffffff; last[i] = 0; } else { - first[i] = get_start_sect(p) + offsets[i]; + first[i] = get_partition_start(pe); last[i] = first[i] + get_nr_sects(p) - 1; } } } -void check(int n, uint h, uint s, uint c, uint start) -{ +static void +check(int n, uint h, uint s, uint c, uint start) { uint total, real_s, real_c; real_s = sector(s) - 1; @@ -1290,9 +1493,8 @@ void check(int n, uint h, uint s, uint c, uint start) "total %d\n"), n, start, total); } - -void verify(void) -{ +static void +verify(void) { int i, j; uint total = 1; uint first[partitions], last[partitions]; @@ -1312,10 +1514,13 @@ void verify(void) } fill_bounds(first, last); - for (i = 0; i < partitions; p = part_table[++i]) + for (i = 0; i < partitions; i++) { + struct pte *pe = &ptes[i]; + + p = pe->part_table; if (p->sys_ind && !IS_EXTENDED (p->sys_ind)) { check_consistency(p, i); - if (get_start_sect(p) + offsets[i] < first[i]) + if (get_partition_start(pe) < first[i]) printf(_("Warning: bad start-of-data in " "partition %d\n"), i + 1); check(i + 1, p->end_head, p->end_sector, p->end_cyl, @@ -1332,14 +1537,16 @@ void verify(void) last[i] : last[j]; } } + } if (extended_offset) { - uint e_last = get_start_sect(part_table[ext_index]) + - get_nr_sects(part_table[ext_index]) - 1; + struct pte *pex = &ptes[ext_index]; + uint e_last = get_start_sect(pex->part_table) + + get_nr_sects(pex->part_table) - 1; - for (p = part_table[i = 4]; i < partitions; - p = part_table[++i]) { + for (i = 4; i < partitions; i++) { total++; + p = ptes[i].part_table; if (!p->sys_ind) { if (i != 4 || i + 1 < partitions) printf(_("Warning: partition %d " @@ -1359,15 +1566,16 @@ void verify(void) printf(_("%d unallocated sectors\n"), total); } -void add_partition(int n, int sys) -{ +static void +add_partition(int n, int sys) { char mesg[256]; /* 48 does not suffice in Japanese */ int i, read = 0; - struct partition *p = part_table[n], *q = part_table[ext_index]; + struct partition *p = ptes[n].part_table; + struct partition *q = ptes[ext_index].part_table; uint start, stop = 0, limit, temp, first[partitions], last[partitions]; - if (p->sys_ind) { + if (p && p->sys_ind) { printf(_("Partition %d is already defined. Delete " "it before re-adding it.\n"), n + 1); return; @@ -1395,7 +1603,7 @@ void add_partition(int n, int sys) for (i = 0; i < partitions; i++) { int lastplusoff; - if (start == offsets[i]) + if (start == ptes[i].offset) start += sector_offset; lastplusoff = last[i] + ((n<4) ? 0 : sector_offset); if (start >= first[i] && start <= lastplusoff) @@ -1421,26 +1629,28 @@ void add_partition(int n, int sys) } } while (start != temp || !read); if (n > 4) { /* NOT for fifth partition */ - offsets[n] = start - sector_offset; - if (offsets[n] == extended_offset) { /* must be corrected */ - offsets[n]++; + struct pte *pe = &ptes[n]; + + pe->offset = start - sector_offset; + if (pe->offset == extended_offset) { /* must be corrected */ + pe->offset++; if (sector_offset == 1) start++; } } for (i = 0; i < partitions; i++) { - if (start < offsets[i] && limit >= offsets[i]) - limit = offsets[i] - 1; + struct pte *pe = &ptes[i]; + + if (start < pe->offset && limit >= pe->offset) + limit = pe->offset - 1; if (start < first[i] && limit >= first[i]) limit = first[i] - 1; } if (start > limit) { printf(_("No free sectors available\n")); - if (n > 4) { - free(buffers[n]); + if (n > 4) partitions--; - } return; } if (cround(start) == cround(limit)) { @@ -1457,22 +1667,25 @@ void add_partition(int n, int sys) } } - set_partition(n, p, start, stop, sys, offsets[n]); + set_partition(n, p, start, stop, sys, ptes[n].offset); if (IS_EXTENDED (sys)) { + struct pte *pe4 = &ptes[4]; + struct pte *pen = &ptes[n]; + ext_index = n; - offsets[4] = extended_offset = start; - ext_pointers[n] = p; - if (!(buffers[4] = calloc(1, sector_size))) + pen->ext_pointer = p; + pe4->offset = extended_offset = start; + if (!(pe4->sectorbuffer = calloc(1, sector_size))) fatal(out_of_memory); - part_table[4] = offset(buffers[4], 0); - ext_pointers[4] = part_table[4] + 1; - changed[4] = 1; + pe4->part_table = pt_offset(pe4->sectorbuffer, 0); + pe4->ext_pointer = pe4->part_table + 1; + pe4->changed = 1; partitions = 5; } else { if (n > 4) - set_partition(n - 1, ext_pointers[n - 1], - offsets[n], stop, EXTENDED, + set_partition(n - 1, ptes[n-1].ext_pointer, + ptes[n].offset, stop, EXTENDED, extended_offset); #if 0 if ((limit = get_nr_sects(p)) & 1) @@ -1482,21 +1695,24 @@ void add_partition(int n, int sys) } } -void add_logical(void) -{ - if (partitions > 5 || part_table[4]->sys_ind) { - if (!(buffers[partitions] = calloc(1, sector_size))) +static void +add_logical(void) { + if (partitions > 5 || ptes[4].part_table->sys_ind) { + struct pte *pe = &ptes[partitions]; + + if (!(pe->sectorbuffer = calloc(1, sector_size))) fatal(out_of_memory); - part_table[partitions] = offset(buffers[partitions], 0); - ext_pointers[partitions] = part_table[partitions] + 1; - offsets[partitions] = 0; + pe->part_table = pt_offset(pe->sectorbuffer, 0); + pe->ext_pointer = pe->part_table + 1; + pe->offset = 0; + pe->changed = 1; partitions++; } add_partition(partitions - 1, LINUX_NATIVE); } -void new_partition(void) -{ +static void +new_partition(void) { int i, free_primary = 0; if (warn_geometry()) @@ -1518,7 +1734,7 @@ void new_partition(void) } for (i = 0; i < 4; i++) - free_primary += !part_table[i]->sys_ind; + free_primary += !ptes[i].part_table->sys_ind; if (!free_primary) { if (extended_offset) add_logical(); @@ -1552,30 +1768,33 @@ void new_partition(void) } } -void write_table(void) -{ +static void +write_table(void) { int i; - changed[3] = changed[0] || changed[1] || changed[2] || changed[3]; - if (!sun_label && !sgi_label) { - for (i = 3; i < partitions; i++) { - if (changed[i]) { - write_part_table_flag(buffers[i]); - if (ext2_llseek(fd, (ext2_loff_t)offsets[i] - * sector_size, SEEK_SET) < 0) - fatal(unable_to_seek); - if (write(fd, buffers[i], sector_size) != sector_size) - fatal(unable_to_write); + if (dos_label) { + for (i=0; i<3; i++) + if(ptes[i].changed) + ptes[3].changed = 1; + for (i = 3; i < partitions; i++) { + struct pte *pe = &ptes[i]; + + if (pe->changed) { + write_part_table_flag(pe->sectorbuffer); + write_sector(fd, pe->offset, pe->sectorbuffer); + } } - } } else if (sgi_label) { - /* no test on change? the printf below might be mistaken */ - sgi_write_table(); + /* no test on change? the printf below might be mistaken */ + sgi_write_table(); } else if (sun_label) { - if (changed[3] || changed[4] || changed[5] || - changed[6] || changed[7]) { - sun_write_table(); - } + int needw = 0; + + for (i=0; i<8; i++) + if(ptes[i].changed) + needw = 1; + if (needw) + sun_write_table(); } printf(_("The partition table has been altered!\n\n")); @@ -1624,15 +1843,15 @@ reread_partition_table(int leave) { } #define MAX_PER_LINE 16 -void print_buffer(char buffer[]) -{ +static void +print_buffer(char pbuffer[]) { int i, l; for (i = 0, l = 0; i < sector_size; i++, l++) { if (l == 0) printf("0x%03X:", i); - printf(" %02X", (unsigned char) buffer[i]); + printf(" %02X", (unsigned char) pbuffer[i]); if (l == MAX_PER_LINE - 1) { printf("\n"); l = -1; @@ -1643,20 +1862,21 @@ void print_buffer(char buffer[]) printf("\n"); } -void print_raw(void) -{ +static void +print_raw(void) { int i; printf(_("Device: %s\n"), disk_device); if (sun_label || sgi_label) - print_buffer(buffer); + print_buffer(MBRbuffer); else for (i = 3; i < partitions; i++) - print_buffer(buffers[i]); + print_buffer(ptes[i].sectorbuffer); } -void move_begin(int i) -{ - struct partition *p = part_table[i]; +static void +move_begin(int i) { + struct pte *pe = &ptes[i]; + struct partition *p = pe->part_table; uint new, first; if (warn_geometry()) @@ -1665,38 +1885,42 @@ void move_begin(int i) printf(_("Partition %d has no data area\n"), i + 1); return; } - first = get_start_sect(p) + offsets[i]; - new = read_int(first, first, - get_start_sect(p) + get_nr_sects(p) + offsets[i] - 1, - first, _("New beginning of data")) - offsets[i]; + first = get_partition_start(pe); + new = read_int(first, first, first + get_nr_sects(p) - 1, first, + _("New beginning of data")) - pe->offset; if (new != get_nr_sects(p)) { first = get_nr_sects(p) + get_start_sect(p) - new; set_nr_sects(p, first); set_start_sect(p, new); - changed[i] = 1; + pe->changed = 1; } } -void xselect(void) -{ +static void +xselect(void) { + char c; + while(1) { putchar('\n'); - switch (tolower(read_char(_("Expert command (m for help): ")))) { + c = tolower(read_char(_("Expert command (m for help): "))); + switch (c) { case 'a': if (sun_label) sun_set_alt_cyl(); break; case 'b': - if (!sun_label && !sgi_label) + if (dos_label) move_begin(get_partition(0, partitions)); break; case 'c': - cylinders = read_int(1, cylinders, 131071, - 0, _("Number of cylinders")); + user_cylinders = cylinders = + read_int(1, cylinders, 131071, 0, + _("Number of cylinders")); if (sun_label) sun_set_ncyl(cylinders); - warn_cylinders(); + if (dos_label) + warn_cylinders(); break; case 'd': print_raw(); @@ -1706,14 +1930,18 @@ void xselect(void) sgi_set_xcyl(); else if (sun_label) sun_set_xcyl(); - else + else if (dos_label) x_list_table(1); break; + case 'f': + if(dos_label) + fix_partition_table_order(); + break; case 'g': create_sgilabel(); break; case 'h': - heads = read_int(1, heads, 256, 0, + user_heads = heads = read_int(1, heads, 256, 0, _("Number of heads")); update_units(); break; @@ -1738,7 +1966,7 @@ void xselect(void) case 'r': return; case 's': - sectors = read_int(1, sectors, 63, 0, + user_sectors = sectors = read_int(1, sectors, 63, 0, _("Number of sectors")); if (dos_compatible_flag) { sector_offset = sectors; @@ -1764,7 +1992,7 @@ void xselect(void) } } -int +static int is_ide_cdrom(char *device) { /* No device was given explicitly, and we are trying some likely things. But opening /dev/hdc may produce errors like @@ -1792,8 +2020,8 @@ is_ide_cdrom(char *device) { return 0; } -void try(char *device, int user_specified) -{ +static void +try(char *device, int user_specified) { disk_device = device; if (!setjmp(listingbuf)) { if (!user_specified) @@ -1827,8 +2055,8 @@ void try(char *device, int user_specified) /* for fdisk -l: try all things in /proc/partitions that look like a partition name (do not end in a digit) */ -void -tryprocpt() { +static void +tryprocpt(void) { FILE *procpt; char line[100], ptname[100], devname[120], *s; int ma, mi, sz; @@ -1851,16 +2079,14 @@ tryprocpt() { } } -int -dir_exists(char *dirname) { - struct stat statbuf; +static void +dummy(int *kk) {} - return (stat(dirname, &statbuf) == 0 && S_ISDIR(statbuf.st_mode)); +static void +unknown_command(int c) { + printf(_("%c: unknown command\n"), c); } -void -dummy(int *kk) {} - int main(int argc, char **argv) { int j, c; @@ -1878,7 +2104,7 @@ main(int argc, char **argv) { * fdisk -s [partition] ... * fdisk [-b sectorsize] [-u] device */ - while ((c = getopt(argc, argv, "b:lsuv")) != EOF) { + while ((c = getopt(argc, argv, "b:lsuvV")) != EOF) { switch (c) { case 'b': /* ugly: this sector size is really per device, @@ -1899,6 +2125,7 @@ main(int argc, char **argv) { case 'u': display_in_cyl_units = 0; break; + case 'V': case 'v': printf("fdisk v" UTIL_LINUX_VERSION "\n"); exit(0); @@ -1968,19 +2195,34 @@ main(int argc, char **argv) { get_boot(fdisk); +#ifdef __alpha__ + /* On alpha, if we detect a disklabel, go directly to + disklabel mode (typically you'll be switching from DOS + partition tables to disklabels, not the other way around) + - dhuggins@linuxcare.com */ + if (osf_label) { + printf(_("Detected an OSF/1 disklabel on %s, entering disklabel mode.\n" + "To return to DOS partition table mode, use the 'r' command.\n"), + disk_device); + bselect(); + } +#endif + while (1) { putchar('\n'); - switch (tolower(read_char(_("Command (m for help): ")))) { + c = tolower(read_char(_("Command (m for help): "))); + switch (c) { case 'a': - if (sun_label) + if (dos_label) + toggle_active(get_partition(1, partitions)); + else if (sun_label) toggle_sunflags(get_partition(1, partitions), 0x01); + else if (sgi_label) + sgi_set_bootpartition( + get_partition(1, partitions)); else - if (sgi_label) - sgi_set_bootpartition( - get_partition(1, partitions)); - else - toggle_active(get_partition(1, partitions)); + unknown_command(c); break; case 'b': if (sgi_label) { @@ -1995,15 +2237,16 @@ main(int argc, char **argv) { bselect(); break; case 'c': - if (sun_label) + if (dos_label) + toggle_dos_compatibility_flag(); + else if (sun_label) toggle_sunflags(get_partition(1, partitions), 0x10); - else - if (sgi_label) - sgi_set_swappartition( + else if (sgi_label) + sgi_set_swappartition( get_partition(1, partitions)); - else - toggle_dos(); + else + unknown_command(c); break; case 'd': delete_partition( @@ -2013,10 +2256,13 @@ main(int argc, char **argv) { if (sgi_label) create_sgiinfo(); else - menu(); + unknown_command(c); case 'l': list_types(get_sys_types()); break; + case 'm': + menu(); + break; case 'n': new_partition(); break; @@ -2046,14 +2292,16 @@ main(int argc, char **argv) { write_table(); /* does not return */ break; case 'x': - if( sgi_label ) { + if(sgi_label) { fprintf(stderr, _("\n\tSorry, no experts menu for SGI " "partition tables available.\n\n")); } else xselect(); break; - default: menu(); + default: + unknown_command(c); + menu(); } } return 0; diff --git a/fdisk/fdisk.h b/fdisk/fdisk.h index 551b02f6..868251df 100644 --- a/fdisk/fdisk.h +++ b/fdisk/fdisk.h @@ -53,6 +53,12 @@ enum failure {usage, usage2, ioctl_error, enum action {fdisk, require, try_only, create_empty}; +struct geom { + unsigned int heads; + unsigned int sectors; + unsigned int cylinders; +}; + /* prototypes for fdisk.c */ extern char *disk_device, *line_ptr; @@ -60,8 +66,10 @@ extern int fd, partitions; extern uint display_in_cyl_units, units_per_sector; +extern void change_units(void); extern struct partition *part_table[]; extern void fatal(enum failure why); +extern void get_geometry(int fd, struct geom *); extern int get_boot(enum action what); extern int get_partition(int warn, int max); extern void list_types(struct systypes *sys); @@ -69,7 +77,10 @@ extern int read_line (void); extern char read_char(char *mesg); extern int read_hex(struct systypes *sys); extern void reread_partition_table(int leave); -uint read_int(uint low, uint dflt, uint high, uint base, char *mesg); +extern struct partition *get_part_table(int); +extern int valid_part_table_flag(unsigned char *b); +extern uint read_int(uint low, uint dflt, uint high, uint base, char *mesg); + #define PLURAL 0 #define SINGULAR 1 @@ -78,9 +89,13 @@ extern char *const str_units(int); extern unsigned int get_start_sect(struct partition *p); extern unsigned int get_nr_sects(struct partition *p); +extern int osf_label; + /* prototypes for fdiskbsdlabel.c */ extern void bselect(void); -extern int btrydev (char * dev); +extern int check_osf_label(void); +extern int btrydev(char * dev); +extern void xbsd_print_disklabel(int); /* prototypes for fdisksgilabel.c */ extern int valid_part_table_flag(unsigned char *b); diff --git a/fdisk/fdiskaixlabel.c b/fdisk/fdiskaixlabel.c index 7540f9a6..395de53e 100644 --- a/fdisk/fdiskaixlabel.c +++ b/fdisk/fdiskaixlabel.c @@ -22,9 +22,8 @@ static short volumes=1; * only dealing with free blocks here */ -void -aix_info( void ) -{ +static void +aix_info( void ) { puts( _("\n\tThere is a valid AIX label on this disk.\n" "\tUnfortunately Linux cannot handle these\n" @@ -46,7 +45,7 @@ aix_nolabel( void ) aixlabel->magic = 0; aix_label = 0; partitions = 4; - memset( buffer, 0, sizeof(buffer) ); /* avoid fdisk cores */ + memset( MBRbuffer, 0, sizeof(MBRbuffer) ); /* avoid fdisk cores */ return; } diff --git a/fdisk/fdiskaixlabel.h b/fdisk/fdiskaixlabel.h index fd95bc01..ca6919d7 100644 --- a/fdisk/fdiskaixlabel.h +++ b/fdisk/fdiskaixlabel.h @@ -18,8 +18,8 @@ typedef struct { #define AIX_INFO_MAGIC_SWAPPED 0x59290700 /* fdisk.c */ -#define aixlabel ((aix_partition *)buffer) -extern char buffer[MAX_SECTOR_SIZE]; +#define aixlabel ((aix_partition *)MBRbuffer) +extern char MBRbuffer[MAX_SECTOR_SIZE]; extern char changed[MAXIMUM_PARTS]; extern uint heads, sectors, cylinders; extern int show_begin; diff --git a/fdisk/fdiskbsdlabel.c b/fdisk/fdiskbsdlabel.c index 980bc38c..0f3c6813 100644 --- a/fdisk/fdiskbsdlabel.c +++ b/fdisk/fdiskbsdlabel.c @@ -36,6 +36,10 @@ Changes: 19990319 - Arnaldo Carvalho de Melo <acme@conectiva.com.br> - i18n/nls + + 20000101 - David Huggins-Daines <dhuggins@linuxcare.com> - Better + support for OSF/1 disklabels on Alpha. Also fixed unaligned + accesses in alpha_bootblock_checksum() */ #include <unistd.h> @@ -61,7 +65,6 @@ static void xbsd_delete_part (void); static void xbsd_new_part (void); -static void xbsd_print_disklabel (int show_all); static void xbsd_write_disklabel (void); static int xbsd_create_disklabel (void); static void xbsd_edit_disklabel (void); @@ -75,33 +78,49 @@ static int xbsd_initlabel (struct partition *p, struct xbsd_disklabel *d, int p static int xbsd_readlabel (struct partition *p, struct xbsd_disklabel *d); static int xbsd_writelabel (struct partition *p, struct xbsd_disklabel *d); static void sync_disks (void); -#if defined (i386) || defined (__sparc__) || defined (__arm__) -static int xbsd_translate_fstype (int linux_type); -static void xbsd_link_part (void); -#endif + #if defined (__alpha__) void alpha_bootblock_checksum (char *boot); #endif -static struct xbsd_disklabel xbsd_dlabel; -static char buffer[BSD_BBSIZE]; -#if defined (i386) || defined (__sparc__) || defined (__arm__) +#if !defined (__alpha__) +static int xbsd_translate_fstype (int linux_type); +static void xbsd_link_part (void); static struct partition *xbsd_part; static int xbsd_part_index; #endif +#if defined (__alpha__) +/* We access this through a u_int64_t * when checksumming */ +static char disklabelbuffer[BSD_BBSIZE] __attribute__((aligned(8))); +#else +static char disklabelbuffer[BSD_BBSIZE]; +#endif + +static struct xbsd_disklabel xbsd_dlabel; + +#define bsd_cround(n) \ + (display_in_cyl_units ? ((n)/xbsd_dlabel.d_secpercyl) + 1 : (n)) + +int +check_osf_label(void) { + if (xbsd_readlabel (NULL, &xbsd_dlabel) == 0) + return 0; + osf_label = 1; + return 1; +} + int btrydev (char * dev) { if (xbsd_readlabel (NULL, &xbsd_dlabel) == 0) - return -1; + return -1; printf(_("\nBSD label for device: %s\n"), dev); xbsd_print_disklabel (0); return 0; } -void -bmenu (void) -{ +static void +bmenu (void) { puts (_("Command action")); puts (_(" d delete a BSD partition")); puts (_(" e edit drive data")); @@ -111,49 +130,53 @@ bmenu (void) puts (_(" n add a new BSD partition")); puts (_(" p print BSD partition table")); puts (_(" q quit without saving changes")); -#if defined (i386) || defined (__sparc__) || defined (__arm__) puts (_(" r return to main menu")); -#endif puts (_(" s show complete disklabel")); puts (_(" t change a partition's filesystem id")); + puts (_(" u change units (cylinders/sectors)")); puts (_(" w write disklabel to disk")); -#if defined (i386) || defined (__sparc__) || defined (__arm__) +#if !defined (__alpha__) puts (_(" x link BSD partition to non-BSD partition")); #endif } -int +#if !defined (__alpha__) +static int hidden(int type) { return type ^ 0x10; } -int +static int is_netbsd_partition_type(int type) { return (type == NETBSD_PARTITION || type == hidden(NETBSD_PARTITION)); } +#endif void bselect (void) { -#if defined (i386) || defined (__sparc__) || defined (__arm__) +#if !defined (__alpha__) int t, ss; + struct partition *p; - for (t=0; t<4; t++) - if (is_netbsd_partition_type(part_table[t] -> sys_ind)) { - xbsd_part = part_table[t]; + for (t=0; t<4; t++) { + p = get_part_table(t); + if (p && is_netbsd_partition_type(p->sys_ind)) { + xbsd_part = p; xbsd_part_index = t; ss = get_start_sect(xbsd_part); if (ss == 0) { - fprintf (stderr, _("Partition %s%d has invalid starting sector 0.\n"), - disk_device, t+1); - return; + fprintf (stderr, _("Partition %s has invalid starting sector 0.\n"), + partname(disk_device, t+1, 0)); + return; } - printf (_("Reading disklabel of %s%d at sector %d.\n"), - disk_device, t+1, ss + BSD_LABELSECTOR); + printf (_("Reading disklabel of %s at sector %d.\n"), + partname(disk_device, t+1, 0), ss + BSD_LABELSECTOR); if (xbsd_readlabel (xbsd_part, &xbsd_dlabel) == 0) - if (xbsd_create_disklabel () == 0) + if (xbsd_create_disklabel () == 0) return; break; } + } if (t == 4) { printf (_("There is no *BSD partition on %s.\n"), disk_device); @@ -168,22 +191,20 @@ bselect (void) { #endif - while (1) - { + while (1) { putchar ('\n'); - switch (tolower (read_char (_("BSD disklabel command (m for help): ")))) - { + switch (tolower (read_char (_("BSD disklabel command (m for help): ")))) { case 'd': - xbsd_delete_part (); + xbsd_delete_part (); break; case 'e': - xbsd_edit_disklabel (); + xbsd_edit_disklabel (); break; case 'i': - xbsd_write_bootstrap (); + xbsd_write_bootstrap (); break; case 'l': - xbsd_list_types (); + xbsd_list_types (); break; case 'n': xbsd_new_part (); @@ -194,18 +215,21 @@ bselect (void) { case 'q': close (fd); exit ( EXIT_SUCCESS ); + case 'r': + return; case 's': xbsd_print_disklabel (1); break; case 't': - xbsd_change_fstype (); + xbsd_change_fstype (); + break; + case 'u': + change_units(); break; case 'w': xbsd_write_disklabel (); break; -#if defined (i386) || defined (__sparc__) || defined (__arm__) - case 'r': - return; +#if !defined (__alpha__) case 'x': xbsd_link_part (); break; @@ -225,7 +249,7 @@ xbsd_delete_part (void) i = xbsd_get_part_index (xbsd_dlabel.d_npartitions); xbsd_dlabel.d_partitions[i].p_size = 0; xbsd_dlabel.d_partitions[i].p_offset = 0; - xbsd_dlabel.d_partitions[i].p_fstype = BSD_FS_UNUSED; + xbsd_dlabel.d_partitions[i].p_fstype = BSD_FS_UNUSED; if (xbsd_dlabel.d_npartitions == i + 1) while (xbsd_dlabel.d_partitions[xbsd_dlabel.d_npartitions-1].p_size == 0) xbsd_dlabel.d_npartitions--; @@ -241,7 +265,7 @@ xbsd_new_part (void) if (!xbsd_check_new_partition (&i)) return; -#if defined (i386) || defined (__sparc__) || defined (__arm__) +#if !defined (__alpha__) && !defined (__powerpc__) begin = get_start_sect(xbsd_part); end = begin + get_nr_sects(xbsd_part) - 1; #elif defined (__alpha__) || defined (__powerpc__) @@ -250,39 +274,37 @@ xbsd_new_part (void) #endif sprintf (mesg, _("First %s"), str_units(SINGULAR)); - begin = read_int (cround (begin), cround (begin), cround (end), + begin = read_int (bsd_cround (begin), bsd_cround (begin), bsd_cround (end), 0, mesg); if (display_in_cyl_units) - begin = (begin - 1) * units_per_sector; + begin = (begin - 1) * xbsd_dlabel.d_secpercyl; sprintf (mesg, _("Last %s or +size or +sizeM or +sizeK"), str_units(SINGULAR)); - end = read_int (cround (begin), cround (end), cround (end), - cround (begin), mesg); + end = read_int (bsd_cround (begin), bsd_cround (end), bsd_cround (end), + bsd_cround (begin), mesg); if (display_in_cyl_units) - end = end * units_per_sector - 1; + end = end * xbsd_dlabel.d_secpercyl - 1; xbsd_dlabel.d_partitions[i].p_size = end - begin + 1; xbsd_dlabel.d_partitions[i].p_offset = begin; - xbsd_dlabel.d_partitions[i].p_fstype = BSD_FS_UNUSED; + xbsd_dlabel.d_partitions[i].p_fstype = BSD_FS_UNUSED; } -static void -xbsd_print_disklabel (int show_all) -{ +void +xbsd_print_disklabel (int show_all) { struct xbsd_disklabel *lp = &xbsd_dlabel; struct xbsd_partition *pp; FILE *f = stdout; int i, j; - if (show_all) - { -#if defined (i386) || defined (__sparc__) || defined (__arm__) - fprintf(f, "# %s%d:\n", disk_device, xbsd_part_index+1); -#elif defined (__alpha__) + if (show_all) { +#if defined (__alpha__) fprintf(f, "# %s:\n", disk_device); +#else + fprintf(f, "# %s:\n", partname(disk_device, xbsd_part_index+1, 0)); #endif if ((unsigned) lp->d_type < BSD_DKMAXTYPES) fprintf(f, _("type: %s\n"), xbsd_dktypenames[lp->d_type]); @@ -309,8 +331,10 @@ xbsd_print_disklabel (int show_all) fprintf(f, _("interleave: %d\n"), lp->d_interleave); fprintf(f, _("trackskew: %d\n"), lp->d_trackskew); fprintf(f, _("cylinderskew: %d\n"), lp->d_cylskew); - fprintf(f, _("headswitch: %ld\t\t# milliseconds\n"), (long) lp->d_headswitch); - fprintf(f, _("track-to-track seek: %ld\t# milliseconds\n"), (long) lp->d_trkseek); + fprintf(f, _("headswitch: %ld\t\t# milliseconds\n"), + (long) lp->d_headswitch); + fprintf(f, _("track-to-track seek: %ld\t# milliseconds\n"), + (long) lp->d_trkseek); fprintf(f, _("drivedata: ")); for (i = NDDATA - 1; i >= 0; i--) if (lp->d_drivedata[i]) @@ -321,19 +345,33 @@ xbsd_print_disklabel (int show_all) fprintf(f, "%ld ", (long) lp->d_drivedata[j]); } fprintf (f, _("\n%d partitions:\n"), lp->d_npartitions); - fprintf (f, _("# size offset fstype [fsize bsize cpg]\n")); + fprintf (f, _("# start end size fstype [fsize bsize cpg]\n")); pp = lp->d_partitions; for (i = 0; i < lp->d_npartitions; i++, pp++) { if (pp->p_size) { - fprintf(f, " %c: %8ld %8ld ", 'a' + i, - (long) pp->p_size, (long) pp->p_offset); + if (display_in_cyl_units && lp->d_secpercyl) { + fprintf(f, " %c: %8ld%c %8ld%c %8ld%c ", + 'a' + i, + (long) pp->p_offset / lp->d_secpercyl + 1, + (pp->p_offset % lp->d_secpercyl) ? '*' : ' ', + (long) (pp->p_offset + pp->p_size + lp->d_secpercyl - 1) + / lp->d_secpercyl, + ((pp->p_offset + pp->p_size) % lp->d_secpercyl) ? '*' : ' ', + (long) pp->p_size / lp->d_secpercyl, + (pp->p_size % lp->d_secpercyl) ? '*' : ' '); + } else { + fprintf(f, " %c: %8ld %8ld %8ld ", + 'a' + i, + (long) pp->p_offset, + (long) pp->p_offset + pp->p_size - 1, + (long) pp->p_size); + } if ((unsigned) pp->p_fstype < BSD_FSMAXTYPES) fprintf(f, "%8.8s", xbsd_fstypes[pp->p_fstype].name); else fprintf(f, "%8x", pp->p_fstype); - switch (pp->p_fstype) - { - case BSD_FS_UNUSED: + switch (pp->p_fstype) { + case BSD_FS_UNUSED: fprintf(f, " %5ld %5ld %5.5s ", (long) pp->p_fsize, (long) pp->p_fsize * pp->p_frag, ""); break; @@ -345,76 +383,55 @@ xbsd_print_disklabel (int show_all) break; default: - fprintf(f, "%20.20s", ""); + fprintf(f, "%22.22s", ""); break; } - fprintf(f, "\t# (Cyl. %4ld", (long) -#if 0 - pp->p_offset / lp->d_secpercyl); /* differs from Linux fdisk */ -#else - pp->p_offset / lp->d_secpercyl + 1); -#endif - if (pp->p_offset % lp->d_secpercyl) - putc('*', f); - else - putc(' ', f); - fprintf(f, "- %ld", - (long) (pp->p_offset + - pp->p_size + lp->d_secpercyl - 1) / -#if 0 - lp->d_secpercyl - 1); /* differs from Linux fdisk */ -#else - lp->d_secpercyl); -#endif - if (pp->p_size % lp->d_secpercyl) - putc('*', f); - fprintf(f, ")\n"); + fprintf(f, "\n"); } } } static void -xbsd_write_disklabel (void) -{ -#if defined (i386) || defined (__sparc__) || defined (__arm__) - printf (_("Writing disklabel to %s%d.\n"), disk_device, xbsd_part_index+1); - xbsd_writelabel (xbsd_part, &xbsd_dlabel); -#elif defined (__alpha__) - printf (_("Writing disklabel to %s.\n"), disk_device); - xbsd_writelabel (NULL, &xbsd_dlabel); +xbsd_write_disklabel (void) { +#if defined (__alpha__) + printf (_("Writing disklabel to %s.\n"), disk_device); + xbsd_writelabel (NULL, &xbsd_dlabel); +#else + printf (_("Writing disklabel to %s.\n"), + partname(disk_device, xbsd_part_index+1, 0)); + xbsd_writelabel (xbsd_part, &xbsd_dlabel); #endif - reread_partition_table(0); /* no exit yet */ + reread_partition_table(0); /* no exit yet */ } static int -xbsd_create_disklabel (void) -{ - char c; +xbsd_create_disklabel (void) { + char c; -#if defined (i386) || defined (__sparc__) || defined (__arm__) - fprintf (stderr, _("%s%d contains no disklabel.\n"), - disk_device, xbsd_part_index+1); -#elif defined (__alpha__) - fprintf (stderr, _("%s contains no disklabel.\n"), disk_device); +#if defined (__alpha__) + fprintf (stderr, _("%s contains no disklabel.\n"), disk_device); +#else + fprintf (stderr, _("%s contains no disklabel.\n"), + partname(disk_device, xbsd_part_index+1, 0)); #endif - while (1) - if ((c = tolower (read_char (_("Do you want to create a disklabel? (y/n) ")))) == 'y') - { -#if defined (i386) || defined (__sparc__) || defined (__arm__) - if (xbsd_initlabel (xbsd_part, &xbsd_dlabel, xbsd_part_index) == 1) -#elif defined (__alpha__) || defined (__powerpc__) - if (xbsd_initlabel (NULL, &xbsd_dlabel, 0) == 1) + while (1) { + c = read_char (_("Do you want to create a disklabel? (y/n) ")); + if (tolower(c) == 'y') { + if (xbsd_initlabel ( +#if defined (__alpha__) || defined (__powerpc__) + NULL, &xbsd_dlabel, 0 +#else + xbsd_part, &xbsd_dlabel, xbsd_part_index #endif - { - xbsd_print_disklabel (1); - return 1; - } - else - return 0; - } - else if (c == 'n') - return 0; + ) == 1) { + xbsd_print_disklabel (1); + return 1; + } else + return 0; + } else if (c == 'n') + return 0; + } } static int @@ -437,7 +454,7 @@ xbsd_edit_disklabel (void) d = &xbsd_dlabel; -#ifdef __alpha__ +#if defined (__alpha__) || defined (__ia64__) d -> d_secsize = (u_long) edit_int ((u_long) d -> d_secsize ,_("bytes/sector")); d -> d_nsectors = (u_long) edit_int ((u_long) d -> d_nsectors ,_("sectors/track")); d -> d_ntracks = (u_long) edit_int ((u_long) d -> d_ntracks ,_("tracks/cylinder")); @@ -507,18 +524,18 @@ xbsd_write_bootstrap (void) dkbasename = line_ptr; } sprintf (path, "%s/%sboot", bootdir, dkbasename); - if (!xbsd_get_bootstrap (path, buffer, (int) xbsd_dlabel.d_secsize)) + if (!xbsd_get_bootstrap (path, disklabelbuffer, (int) xbsd_dlabel.d_secsize)) return; /* We need a backup of the disklabel (xbsd_dlabel might have changed). */ - d = &buffer[BSD_LABELSECTOR * SECTOR_SIZE]; + d = &disklabelbuffer[BSD_LABELSECTOR * SECTOR_SIZE]; bcopy (d, &dl, sizeof (struct xbsd_disklabel)); /* The disklabel will be overwritten by 0's from bootxx anyway */ bzero (d, sizeof (struct xbsd_disklabel)); sprintf (path, "%s/boot%s", bootdir, dkbasename); - if (!xbsd_get_bootstrap (path, &buffer[xbsd_dlabel.d_secsize], + if (!xbsd_get_bootstrap (path, &disklabelbuffer[xbsd_dlabel.d_secsize], (int) xbsd_dlabel.d_bbsize - xbsd_dlabel.d_secsize)) return; @@ -532,24 +549,25 @@ xbsd_write_bootstrap (void) bcopy (&dl, d, sizeof (struct xbsd_disklabel)); -#if defined (i386) || defined (__sparc__) || defined (__arm__) - sector = get_start_sect(xbsd_part); -#elif defined (__powerpc__) +#if defined (__powerpc__) sector = 0; #elif defined (__alpha__) sector = 0; - alpha_bootblock_checksum (buffer); + alpha_bootblock_checksum (disklabelbuffer); +#else + sector = get_start_sect(xbsd_part); #endif - if (ext2_llseek (fd, sector * SECTOR_SIZE, SEEK_SET) == -1) + if (ext2_llseek (fd, (ext2_loff_t) sector * SECTOR_SIZE, SEEK_SET) == -1) fatal (unable_to_seek); - if (BSD_BBSIZE != write (fd, buffer, BSD_BBSIZE)) + if (BSD_BBSIZE != write (fd, disklabelbuffer, BSD_BBSIZE)) fatal (unable_to_write); -#if defined (i386) || defined (__sparc__) || defined (__arm__) - printf (_("Bootstrap installed on %s%d.\n"), disk_device, xbsd_part_index+1); -#elif defined (__alpha__) +#if defined (__alpha__) printf (_("Bootstrap installed on %s.\n"), disk_device); +#else + printf (_("Bootstrap installed on %s.\n"), + partname (disk_device, xbsd_part_index+1, 0)); #endif sync_disks (); @@ -629,14 +647,10 @@ xbsd_dkcksum (struct xbsd_disklabel *lp) static int xbsd_initlabel (struct partition *p, struct xbsd_disklabel *d, int pindex) { - struct hd_geometry geometry; struct xbsd_partition *pp; + struct geom g; - if (ioctl (fd, HDIO_GETGEO, &geometry) == -1) - { - perror ("ioctl"); - return 0; - } + get_geometry (fd, &g); bzero (d, sizeof (struct xbsd_disklabel)); d -> d_magic = BSD_DISKMAGIC; @@ -650,16 +664,18 @@ xbsd_initlabel (struct partition *p, struct xbsd_disklabel *d, int pindex) d -> d_subtype = BSD_DSTYPE_INDOSPART & pindex; #endif -#if defined (i386) || defined (__sparc__) || defined (__arm__) +#if !defined (__alpha__) d -> d_flags = BSD_D_DOSPART; #else d -> d_flags = 0; #endif - d -> d_secsize = SECTOR_SIZE; /* bytes/sector */ - d -> d_nsectors = geometry.sectors; /* sectors/track */ - d -> d_ntracks = geometry.heads; /* tracks/cylinder (heads) */ - d -> d_ncylinders = geometry.cylinders; - d -> d_secpercyl = geometry.sectors * geometry.heads; /* sectors/cylinder */ + d -> d_secsize = SECTOR_SIZE; /* bytes/sector */ + d -> d_nsectors = g.sectors; /* sectors/track */ + d -> d_ntracks = g.heads; /* tracks/cylinder (heads) */ + d -> d_ncylinders = g.cylinders; + d -> d_secpercyl = g.sectors * g.heads; /* sectors/cylinder */ + if (d -> d_secpercyl == 0) + d -> d_secpercyl = 1; /* avoid segfaults */ d -> d_secperunit = d -> d_secpercyl * d -> d_ncylinders; d -> d_rpm = 3600; @@ -673,7 +689,7 @@ xbsd_initlabel (struct partition *p, struct xbsd_disklabel *d, int pindex) d -> d_bbsize = BSD_BBSIZE; d -> d_sbsize = BSD_SBSIZE; -#if defined (i386) || defined (__sparc__) || defined (__arm__) +#if !defined (__alpha__) d -> d_npartitions = 4; pp = &d -> d_partitions[2]; /* Partition C should be the NetBSD partition */ pp -> p_offset = get_start_sect(p); @@ -699,18 +715,18 @@ xbsd_readlabel (struct partition *p, struct xbsd_disklabel *d) { int t, sector; -#if defined (i386) || defined (__sparc__) || defined (__arm__) +#if !defined (__alpha__) sector = (p ? get_start_sect(p) : 0); #elif defined (__alpha__) sector = 0; #endif - if (ext2_llseek (fd, sector * SECTOR_SIZE, SEEK_SET) == -1) + if (ext2_llseek (fd, (ext2_loff_t) sector * SECTOR_SIZE, SEEK_SET) == -1) fatal (unable_to_seek); - if (BSD_BBSIZE != read (fd, buffer, BSD_BBSIZE)) + if (BSD_BBSIZE != read (fd, disklabelbuffer, BSD_BBSIZE)) fatal (unable_to_read); - bcopy (&buffer[BSD_LABELSECTOR * SECTOR_SIZE + BSD_LABELOFFSET], + bcopy (&disklabelbuffer[BSD_LABELSECTOR * SECTOR_SIZE + BSD_LABELOFFSET], d, sizeof (struct xbsd_disklabel)); for (t = d -> d_npartitions; t < BSD_MAXPARTITIONS; t++) @@ -733,7 +749,7 @@ xbsd_writelabel (struct partition *p, struct xbsd_disklabel *d) { int sector; -#if defined (i386) || defined (__sparc__) || defined (__arm__) +#if !defined (__alpha__) && !defined (__powerpc__) sector = get_start_sect(p) + BSD_LABELSECTOR; #elif defined (__alpha__) || defined (__powerpc__) sector = BSD_LABELSECTOR; @@ -745,17 +761,18 @@ xbsd_writelabel (struct partition *p, struct xbsd_disklabel *d) /* This is necessary if we want to write the bootstrap later, otherwise we'd write the old disklabel with the bootstrap. */ - bcopy (d, &buffer[BSD_LABELSECTOR * SECTOR_SIZE + BSD_LABELOFFSET], + bcopy (d, &disklabelbuffer[BSD_LABELSECTOR * SECTOR_SIZE + BSD_LABELOFFSET], sizeof (struct xbsd_disklabel)); #if defined (__alpha__) && BSD_LABELSECTOR == 0 - alpha_bootblock_checksum (buffer); - if (ext2_llseek (fd, 0, SEEK_SET) == -1) + alpha_bootblock_checksum (disklabelbuffer); + if (ext2_llseek (fd, (ext2_loff_t) 0, SEEK_SET) == -1) fatal (unable_to_seek); - if (BSD_BBSIZE != write (fd, buffer, BSD_BBSIZE)) + if (BSD_BBSIZE != write (fd, disklabelbuffer, BSD_BBSIZE)) fatal (unable_to_write); #else - if (ext2_llseek (fd, sector * SECTOR_SIZE + BSD_LABELOFFSET, SEEK_SET) == -1) + if (ext2_llseek (fd, (ext2_loff_t) sector * SECTOR_SIZE + BSD_LABELOFFSET, + SEEK_SET) == -1) fatal (unable_to_seek); if (sizeof (struct xbsd_disklabel) != write (fd, d, sizeof (struct xbsd_disklabel))) fatal (unable_to_write); @@ -774,7 +791,7 @@ sync_disks (void) sleep (4); } -#if defined (i386) || defined (__sparc__) || defined (__arm__) +#if !defined (__alpha__) static int xbsd_translate_fstype (int linux_type) { @@ -798,16 +815,18 @@ static void xbsd_link_part (void) { int k, i; + struct partition *p; k = get_partition (1, partitions); if (!xbsd_check_new_partition (&i)) return; - xbsd_dlabel.d_partitions[i].p_size = get_nr_sects(part_table[k]); - xbsd_dlabel.d_partitions[i].p_offset = get_start_sect(part_table[k]); - xbsd_dlabel.d_partitions[i].p_fstype = - xbsd_translate_fstype (part_table[k] -> sys_ind); + p = get_part_table(k); + + xbsd_dlabel.d_partitions[i].p_size = get_nr_sects(p); + xbsd_dlabel.d_partitions[i].p_offset = get_start_sect(p); + xbsd_dlabel.d_partitions[i].p_fstype = xbsd_translate_fstype(p->sys_ind); } #endif diff --git a/fdisk/fdiskbsdlabel.h b/fdisk/fdiskbsdlabel.h index 1a06a08d..68747d48 100644 --- a/fdisk/fdiskbsdlabel.h +++ b/fdisk/fdiskbsdlabel.h @@ -43,10 +43,10 @@ #define BSD_LINUX_BOOTDIR "/usr/ucb/mdec" -#if defined (i386) || defined (__sparc__) || defined (__arm__) +#if defined (i386) || defined (__sparc__) || defined (__arm__) || defined (__mips__) #define BSD_LABELSECTOR 1 #define BSD_LABELOFFSET 0 -#elif defined (__alpha__) || defined (__powerpc__) +#elif defined (__alpha__) || defined (__powerpc__) || defined (__ia64__) #define BSD_LABELSECTOR 0 #define BSD_LABELOFFSET 64 #else @@ -182,10 +182,11 @@ static char *xbsd_dktypenames[] = { #define BSD_FS_BOOT 13 /* partition contains bootstrap */ #define BSD_FS_ADOS 14 /* AmigaDOS fast file system */ #define BSD_FS_HFS 15 /* Macintosh HFS */ +#define BSD_FS_ADVFS 16 /* Digital Unix AdvFS */ /* this is annoying, but it's also the way it is :-( */ #ifdef __alpha__ -#define BSD_FS_EXT2 8 /* MS-DOS file system */ +#define BSD_FS_EXT2 8 /* ext2 file system */ #else #define BSD_FS_MSDOS 8 /* MS-DOS file system */ #endif @@ -212,6 +213,7 @@ static struct systypes xbsd_fstypes[] = { {BSD_FS_BOOT, "boot"}, {BSD_FS_ADOS, "ADOS"}, {BSD_FS_HFS, "HFS"}, + {BSD_FS_ADVFS, "AdvFS"}, { 0, NULL } }; #define BSD_FSMAXTYPES (SIZE(xbsd_fstypes)-1) diff --git a/fdisk/fdisksgilabel.c b/fdisk/fdisksgilabel.c index b2870e65..97e6c595 100644 --- a/fdisk/fdisksgilabel.c +++ b/fdisk/fdisksgilabel.c @@ -36,17 +36,40 @@ static short volumes=1; typedef struct { int first; int last; } freeblocks; static freeblocks freelist[17]; /* 16 partitions can produce 17 vacant slots */ -void setfreelist( int i, int f, int l ) \ - { freelist[i].first = f; freelist[i].last = l; return; } -void add2freelist( int f, int l ) \ - { int i = 0; for( ; i<17 ; i++ ) { if(freelist[i].last==0) break; }\ - setfreelist( i, f, l ); return; } -void clearfreelist( void ) \ - { int i = 0; for( ; i<17 ; i++ ) { setfreelist( i, 0, 0 ); } return; } -int isinfreelist( int b ) \ - { int i = 0; for( ; i<17 ; i++ )\ - { if( ( freelist[i].first <= b ) && ( freelist[i].last >= b) )\ - { return freelist[i].last; } } return 0; } + +static void +setfreelist( int i, int f, int l ) { + freelist[i].first = f; + freelist[i].last = l; +} + +static void +add2freelist( int f, int l ) { + int i = 0; + for( ; i<17 ; i++ ) { + if(freelist[i].last==0) break; + } + setfreelist( i, f, l ); +} + +static void +clearfreelist(void) { + int i = 0; + for( ; i<17 ; i++ ) { + setfreelist( i, 0, 0 ); + } +} + +static int +isinfreelist( int b ) { + int i = 0; + for( ; i<17 ; i++ ) { + if (freelist[i].first <= b && freelist[i].last >= b) { + return freelist[i].last; + } + } + return 0; +} /* return last vacant block of this stride (never 0). */ /* the '>=' is not quite correct, but simplifies the code */ /* @@ -63,53 +86,49 @@ struct systypes sgi_sys_types[] = { {SGI_EFS, N_("SGI efs")}, {0x08, N_("SGI lvol")}, {0x09, N_("SGI rlvol")}, - {0x0A, N_("SGI xfs")}, - {0x0B, N_("SGI xlvol")}, - {0x0C, N_("SGI rxlvol")}, + {0x0a, N_("SGI xfs")}, + {0x0b, N_("SGI xlvol")}, + {0x0c, N_("SGI rxlvol")}, {LINUX_SWAP, N_("Linux swap")}, {LINUX_NATIVE,N_("Linux native")}, + {0x8e, N_("Linux LVM")}, {0, NULL } }; -static inline unsigned short __swap16(unsigned short x) { +static inline unsigned short +__swap16(unsigned short x) { return (((__u16)(x) & 0xFF) << 8) | (((__u16)(x) & 0xFF00) >> 8); } -static inline __u32 __swap32(__u32 x) { + +static inline __u32 +__swap32(__u32 x) { return (((__u32)(x) & 0xFF) << 24) | (((__u32)(x) & 0xFF00) << 8) | (((__u32)(x) & 0xFF0000) >> 8) | (((__u32)(x) & 0xFF000000) >> 24); } -static -int -sgi_get_nsect( void ) -{ +static int +sgi_get_nsect(void) { return SSWAP16(sgilabel->devparam.nsect); } -static -int -sgi_get_ntrks( void ) -{ +static int +sgi_get_ntrks(void) { return SSWAP16(sgilabel->devparam.ntrks); } #if 0 static int -sgi_get_head_vol0( void ) -{ +sgi_get_head_vol0(void) { return SSWAP16(sgilabel->devparam.head_vol0); } static int -sgi_get_bytes( void ) -{ +sgi_get_bytes(void) { return SSWAP16(sgilabel->devparam.bytes); } #endif -static -int -sgi_get_pcylcount( void ) -{ +static int +sgi_get_pcylcount(void) { return SSWAP16(sgilabel->devparam.pcylcount); } @@ -121,23 +140,19 @@ sgi_nolabel() partitions = 4; } -unsigned int -two_s_complement_32bit_sum( - unsigned int* base, - int size /* in bytes */ ) -{ +static unsigned int +two_s_complement_32bit_sum(unsigned int* base, int size /* in bytes */ ) { int i=0; unsigned int sum=0; + size = size / sizeof( unsigned int ); for( i=0; i<size; i++ ) - { sum = sum - SSWAP32(base[i]); - } return sum; } -int check_sgi_label() -{ +int +check_sgi_label() { if (sizeof(sgilabel) > 512) { fprintf(stderr, _("According to MIPS Computer Systems, Inc the " @@ -174,8 +189,7 @@ int check_sgi_label() } void -sgi_list_table( int xtra ) -{ +sgi_list_table( int xtra ) { int i, w; char *type; @@ -241,14 +255,12 @@ sgi_list_table( int xtra ) } int -sgi_get_start_sector( int i ) -{ +sgi_get_start_sector( int i ) { return SSWAP32(sgilabel->partitions[i].start_sector); } int -sgi_get_num_sectors( int i ) -{ +sgi_get_num_sectors( int i ) { return SSWAP32(sgilabel->partitions[i].num_sectors); } @@ -259,13 +271,13 @@ sgi_get_sysid( int i ) } int -sgi_get_bootpartition( void ) +sgi_get_bootpartition(void) { return SSWAP16(sgilabel->boot_part); } int -sgi_get_swappartition( void ) +sgi_get_swappartition(void) { return SSWAP16(sgilabel->swap_part); } @@ -274,25 +286,20 @@ void sgi_set_bootpartition( int i ) { sgilabel->boot_part = SSWAP16(((short)i)); - return; } -int -sgi_get_lastblock( void ) -{ +static int +sgi_get_lastblock(void) { return heads * sectors * cylinders; } void -sgi_set_swappartition( int i ) -{ +sgi_set_swappartition( int i ) { sgilabel->swap_part = SSWAP16(((short)i)); - return; } static int -sgi_check_bootfile( const char* aFile ) -{ +sgi_check_bootfile( const char* aFile ) { if( strlen( aFile ) < 3 ) /* "/a\n" is minimum */ { printf( _("\nInvalid Bootfile!\n" @@ -342,23 +349,21 @@ sgi_set_bootfile( const char* aFile ) } printf( _("\n\tBootfile is changed to \"%s\".\n"), sgilabel->boot_file ); } - return; } void -create_sgiinfo( void ) +create_sgiinfo(void) { /* I keep SGI's habit to write the sgilabel to the second block */ sgilabel->directory[0].vol_file_start = SSWAP32( 2 ); sgilabel->directory[0].vol_file_size = SSWAP32( sizeof( sgiinfo ) ); strncpy( sgilabel->directory[0].vol_file_name, "sgilabel",8 ); - return; } -sgiinfo * fill_sgiinfo( void ); +sgiinfo * fill_sgiinfo(void); void -sgi_write_table( void ) +sgi_write_table(void) { sgilabel->csum = 0; sgilabel->csum = SSWAP32( two_s_complement_32bit_sum( @@ -385,13 +390,10 @@ sgi_write_table( void ) fatal(unable_to_write); free( info ); } - return; } -static -int -compare_start( int *x, int *y ) -{ +static int +compare_start( int *x, int *y ) { /* * sort according to start sectors * and prefers largest partition: @@ -410,10 +412,8 @@ compare_start( int *x, int *y ) return( a - b ); } -static -int -sgi_gaps() -{ +static int +sgi_gaps(void) { /* * returned value is: * = 0 : disk is properly filled to the rim @@ -582,12 +582,11 @@ sgi_change_sysid( int i, int sys ) return; } sgilabel->partitions[i].id = SSWAP32(sys); - return; } -int -sgi_entire( void ) -{ /* returns partition index of first entry marked as entire disk */ +/* returns partition index of first entry marked as entire disk */ +static int +sgi_entire(void) { int i=0; for( i=0; i<16; i++ ) if( sgi_get_sysid(i) == SGI_VOLUME ) @@ -595,52 +594,33 @@ sgi_entire( void ) return -1; } -int -sgi_num_partitions( void ) -{ - int i=0, - n=0; - for( i=0; i<16; i++ ) - if( sgi_get_num_sectors(i)!=0 ) - n++; - return n; -} - -static -void -sgi_set_partition( int i, uint start, uint length, int sys ) -{ +static void +sgi_set_partition( int i, uint start, uint length, int sys ) { sgilabel->partitions[i].id = SSWAP32( sys ); sgilabel->partitions[i].num_sectors = SSWAP32( length ); sgilabel->partitions[i].start_sector = SSWAP32( start ); - changed[i] = 1; - if( sgi_gaps(0) < 0 ) /* rebuild freelist */ + set_changed(i); + if( sgi_gaps() < 0 ) /* rebuild freelist */ printf(_("Do You know, You got a partition overlap on the disk?\n")); - return; } -static -void -sgi_set_entire( void ) -{ +static void +sgi_set_entire(void) { int n; - for( n=10; n<partitions; n++ ) - { - if(!sgi_get_num_sectors( n ) ) - { + for( n=10; n<partitions; n++ ) { + if(!sgi_get_num_sectors( n ) ) { sgi_set_partition( n, 0, sgi_get_lastblock(), SGI_VOLUME ); break; } } - return; } static void -sgi_set_volhdr( void ) +sgi_set_volhdr(void) { int n; for( n=8; n<partitions; n++ ) @@ -658,14 +638,12 @@ sgi_set_volhdr( void ) break; } } - return; } void sgi_delete_partition( int i ) { sgi_set_partition( i, 0, 0, 0 ); - return; } void @@ -741,11 +719,10 @@ sgi_add_partition( int n, int sys ) printf(_("It is highly recommended that eleventh partition\n" "covers the entire disk and is of type `SGI volume'\n")); sgi_set_partition( n, first, last-first, sys ); - return; } void -create_sgilabel( void ) +create_sgilabel(void) { struct hd_geometry geometry; struct { int start; @@ -755,7 +732,7 @@ create_sgilabel( void ) fprintf( stderr, _("Building a new SGI disklabel. Changes will remain in memory only,\n" "until you decide to write them. After that, of course, the previous\n" - "content will be unrecoverable lost.\n\n")); + "content will be unrecoverably lost.\n\n")); #if BYTE_ORDER == LITTLE_ENDIAN other_endian = 1; #else @@ -774,13 +751,13 @@ create_sgilabel( void ) for (i = 0; i < 4; i++) { old[i].sysid = 0; - if( valid_part_table_flag(buffer) ) + if( valid_part_table_flag(MBRbuffer) ) { - if( part_table[i]->sys_ind ) + if( get_part_table(i)->sys_ind ) { - old[i].sysid = part_table[i]->sys_ind; - old[i].start = get_start_sect( part_table[i] ); - old[i].nsect = get_nr_sects( part_table[i] ); + old[i].sysid = get_part_table(i)->sys_ind; + old[i].start = get_start_sect( get_part_table(i) ); + old[i].nsect = get_nr_sects( get_part_table(i) ); printf( _("Trying to keep parameters of partition %d.\n"), i ); if( debug ) printf( _("ID=%02x\tSTART=%d\tLENGTH=%d\n"), @@ -788,7 +765,7 @@ create_sgilabel( void ) } } } - memset(buffer, 0, SECTOR_SIZE); + memset(MBRbuffer, 0, sizeof(MBRbuffer)); sgilabel->magic = SSWAP32(SGI_LABEL_MAGIC); sgilabel->boot_part = SSWAP16(0); sgilabel->swap_part = SSWAP16(1); strncpy( @@ -833,35 +810,34 @@ create_sgilabel( void ) sgi_set_partition( i, old[i].start, old[i].nsect, old[i].sysid ); } } - return; } void -sgi_set_ilfact( void ) +sgi_set_ilfact(void) { /* do nothing in the beginning */ } void -sgi_set_rspeed( void ) +sgi_set_rspeed(void) { /* do nothing in the beginning */ } void -sgi_set_pcylcount( void ) +sgi_set_pcylcount(void) { /* do nothing in the beginning */ } void -sgi_set_xcyl( void ) +sgi_set_xcyl(void) { /* do nothing in the beginning */ } void -sgi_set_ncyl( void ) +sgi_set_ncyl(void) { /* do nothing in the beginning */ } @@ -870,7 +846,7 @@ sgi_set_ncyl( void ) */ sgiinfo* -fill_sgiinfo( void ) +fill_sgiinfo(void) { sgiinfo*info=calloc( 1, sizeof(sgiinfo) ); info->magic=SSWAP32(SGI_INFO_MAGIC); diff --git a/fdisk/fdisksgilabel.h b/fdisk/fdisksgilabel.h index fa35f8f3..a0c3a105 100644 --- a/fdisk/fdisksgilabel.h +++ b/fdisk/fdisksgilabel.h @@ -93,16 +93,16 @@ typedef struct { : (__u32)(x)) /* fdisk.c */ -#define sgilabel ((sgi_partition *)buffer) +#define sgilabel ((sgi_partition *)MBRbuffer) #define sgiparam (sgilabel->devparam) -extern char buffer[MAX_SECTOR_SIZE]; -extern char changed[MAXIMUM_PARTS]; +extern char MBRbuffer[MAX_SECTOR_SIZE]; extern uint heads, sectors, cylinders; extern int show_begin; extern int sgi_label; extern char *partition_type(unsigned char type); extern void update_units(void); extern char read_chars(char *mesg); +extern void set_changed(int); /* fdisksgilabel.c */ extern struct systypes sgi_sys_types[]; diff --git a/fdisk/fdisksunlabel.c b/fdisk/fdisksunlabel.c index 48916ad4..3ec5624a 100644 --- a/fdisk/fdisksunlabel.c +++ b/fdisk/fdisksunlabel.c @@ -51,6 +51,7 @@ struct systypes sun_sys_types[] = { {8, N_("SunOS home")}, {LINUX_SWAP, N_("Linux swap")}, {LINUX_NATIVE, N_("Linux native")}, + {0x8e, N_("Linux LVM")}, { 0, NULL } }; @@ -87,25 +88,25 @@ void guess_device_type(int fd) { } } -void set_sun_partition(int i, uint start, uint stop, int sysid) -{ +static void +set_sun_partition(int i, uint start, uint stop, int sysid) { sunlabel->infos[i].id = sysid; sunlabel->partitions[i].start_cylinder = SSWAP32(start / (heads * sectors)); sunlabel->partitions[i].num_sectors = SSWAP32(stop - start); - changed[i] = 1; + set_changed(i); } -void sun_nolabel(void) -{ +void +sun_nolabel(void) { sun_label = 0; sunlabel->magic = 0; partitions = 4; } -int check_sun_label(void) -{ +int +check_sun_label(void) { unsigned short *ush; int csum; @@ -148,6 +149,10 @@ struct sun_predefined_drives { {"Quantum","ProDrive 80S",1,832,2,834,6,34,3662}, {"Quantum","ProDrive 105S",1,974,2,1019,6,35,3662}, {"CDC","Wren IV 94171-344",3,1545,2,1549,9,46,3600}, +{"IBM","DPES-31080",0,4901,2,4903,4,108,5400}, +{"IBM","DORS-32160",0,1015,2,1017,67,62,5400}, +{"IBM","DNES-318350",0,11199,2,11474,10,320,7200}, +{"SEAGATE","ST34371",0,3880,2,3882,16,135,7228}, {"","SUN0104",1,974,2,1019,6,35,3662}, {"","SUN0207",4,1254,2,1272,9,36,3600}, {"","SUN0327",3,1545,2,1549,9,46,3600}, @@ -162,8 +167,8 @@ struct sun_predefined_drives { {"IOMEGA","Jaz",0,1019,2,1021,64,32,5394}, }; -struct sun_predefined_drives * -sun_autoconfigure_scsi() { +static struct sun_predefined_drives * +sun_autoconfigure_scsi(void) { struct sun_predefined_drives *p = NULL; #ifdef SCSI_IOCTL_GET_IDLUN @@ -193,16 +198,18 @@ sun_autoconfigure_scsi() { pfd = fopen("/proc/scsi/scsi","r"); if (pfd) { while (fgets(buffer2,2048,pfd)) { - if (!strcmp(buffer, buffer2)) { + if (!strcmp(buffer, buffer2)) { if (fgets(buffer2,2048,pfd)) { q = strstr(buffer2,"Vendor: "); if (q) { q += 8; vendor = q; - q = strstr(q," Model: "); + q = strstr(q," "); + *q++ = 0; /* truncate vendor name */ + q = strstr(q,"Model: "); if (q) { *q = 0; - q += 8; + q += 7; model = q; q = strstr(q," Rev: "); if (q) { @@ -247,7 +254,7 @@ void create_sunlabel(void) #else other_endian = 0; #endif - memset(buffer, 0, SECTOR_SIZE); + memset(MBRbuffer, 0, sizeof(MBRbuffer)); sunlabel->magic = SSWAP16(SUN_LABEL_MAGIC); if (!floppy) { puts(_("Drive type\n" @@ -328,14 +335,19 @@ void create_sunlabel(void) sunlabel->ntrks = SSWAP16(p->ntrks); sunlabel->nsect = SSWAP16(p->nsect); sunlabel->rspeed = SSWAP16(p->rspeed); + sunlabel->ilfact = SSWAP16(1); cylinders = p->ncyl; heads = p->ntrks; sectors = p->nsect; puts(_("You may change all the disk params from the x menu")); } - sprintf(buffer, "%s%s%s cyl %d alt %d hd %d sec %d", - p ? p->vendor : "", (p && *p->vendor) ? " " : "", p ? p->model : (floppy ? _("3,5\" floppy") : _("Linux custom")), - cylinders, SSWAP16(sunlabel->nacyl), heads, sectors); + + sprintf(sunlabel->info, "%s%s%s cyl %d alt %d hd %d sec %d", + p ? p->vendor : "", + (p && *p->vendor) ? " " : "", + p ? p->model : (floppy ? _("3,5\" floppy") : _("Linux custom")), + cylinders, SSWAP16(sunlabel->nacyl), heads, sectors); + sunlabel->ntrks = SSWAP16(heads); sunlabel->nsect = SSWAP16(sectors); sunlabel->ncyl = SSWAP16(cylinders); @@ -358,26 +370,28 @@ void create_sunlabel(void) csum ^= *ush++; sunlabel->csum = csum; } - for (i = 1; i < MAXIMUM_PARTS; i++) - changed[i] = 0; - changed[0] = 1; + + set_all_unchanged(); + set_changed(0); get_boot(create_empty); } -void toggle_sunflags(int i, unsigned char mask) -{ +void +toggle_sunflags(int i, unsigned char mask) { if (sunlabel->infos[i].flags & mask) sunlabel->infos[i].flags &= ~mask; else sunlabel->infos[i].flags |= mask; - changed[i] = 1; + set_changed(i); } -void fetch_sun(uint *starts, uint *lens, uint *start, uint *stop) -{ +static void +fetch_sun(uint *starts, uint *lens, uint *start, uint *stop) { int i, continuous = 1; *start = 0; *stop = cylinders * heads * sectors; for (i = 0; i < partitions; i++) { - if (sunlabel->partitions[i].num_sectors && sunlabel->infos[i].id && sunlabel->infos[i].id != WHOLE_DISK) { + if (sunlabel->partitions[i].num_sectors + && sunlabel->infos[i].id + && sunlabel->infos[i].id != WHOLE_DISK) { starts[i] = SSWAP32(sunlabel->partitions[i].start_cylinder) * heads * sectors; lens[i] = SSWAP32(sunlabel->partitions[i].num_sectors); if (continuous) { @@ -386,7 +400,9 @@ void fetch_sun(uint *starts, uint *lens, uint *start, uint *stop) else if (starts[i] + lens[i] >= *stop) *stop = starts[i]; else - continuous = 0; /* There will be probably more gaps than one, so lets check afterwards */ + continuous = 0; + /* There will be probably more gaps + than one, so lets check afterwards */ } } else { starts[i] = 0; @@ -396,16 +412,17 @@ void fetch_sun(uint *starts, uint *lens, uint *start, uint *stop) } static uint *verify_sun_starts; -int verify_sun_cmp(int *a, int *b) -{ + +static int +verify_sun_cmp(int *a, int *b) { if (*a == -1) return 1; if (*b == -1) return -1; if (verify_sun_starts[*a] > verify_sun_starts[*b]) return 1; return -1; } -void verify_sun(void) -{ +void +verify_sun(void) { uint starts[8], lens[8], start, stop; int i,j,k,starto,endo; int array[8]; @@ -466,8 +483,8 @@ void verify_sun(void) printf(_("Unused gap - sectors %d-%d\n"),start,stop); } -void add_sun_partition(int n, int sys) -{ +void +add_sun_partition(int n, int sys) { uint start, stop, stop2; uint starts[8], lens[8]; int whole_disk = 0; @@ -701,4 +718,3 @@ sun_write_table(void) { if (write(fd, sunlabel, SECTOR_SIZE) != SECTOR_SIZE) fatal(unable_to_write); } - diff --git a/fdisk/fdisksunlabel.h b/fdisk/fdisksunlabel.h index 1a75713c..424f462e 100644 --- a/fdisk/fdisksunlabel.h +++ b/fdisk/fdisksunlabel.h @@ -30,21 +30,22 @@ typedef struct { #define SUN_LABEL_MAGIC 0xDABE #define SUN_LABEL_MAGIC_SWAPPED 0xBEDA -#define sunlabel ((sun_partition *)buffer) +#define sunlabel ((sun_partition *)MBRbuffer) #define SSWAP16(x) (other_endian ? __swap16(x) \ : (__u16)(x)) #define SSWAP32(x) (other_endian ? __swap32(x) \ : (__u32)(x)) /* fdisk.c */ -extern char changed[MAXIMUM_PARTS]; -extern char buffer[MAX_SECTOR_SIZE]; +extern char MBRbuffer[MAX_SECTOR_SIZE]; extern uint heads, sectors, cylinders; extern int show_begin; extern int sun_label; extern char *partition_type(unsigned char type); extern void update_units(void); extern char read_chars(char *mesg); +extern void set_all_unchanged(void); +extern void set_changed(int); /* fdisksunlabel.c */ #define SUNOS_SWAP 3 diff --git a/fdisk/i386_sys_types.c b/fdisk/i386_sys_types.c index f3624724..0cad6fa7 100644 --- a/fdisk/i386_sys_types.c +++ b/fdisk/i386_sys_types.c @@ -58,8 +58,10 @@ struct systypes i386_sys_types[] = { {0x85, N_("Linux extended")}, {0x86, N_("NTFS volume set")}, {0x87, N_("NTFS volume set")}, + {0x8e, N_("Linux LVM")}, {0x93, N_("Amoeba")}, {0x94, N_("Amoeba BBT")}, /* (bad block table) */ + {0x9f, N_("BSD/OS")}, /* BSDI */ {0xa0, N_("IBM Thinkpad hibernation")}, {0xa5, N_("BSD/386")}, {0xa6, N_("OpenBSD")}, diff --git a/fdisk/llseek.c b/fdisk/llseek.c index a9cd5a3a..9e00d3e6 100644 --- a/fdisk/llseek.c +++ b/fdisk/llseek.c @@ -25,7 +25,7 @@ extern ext2_loff_t ext2_llseek (unsigned int, ext2_loff_t, unsigned int); #else /* HAVE_LLSEEK */ -#ifdef __alpha__ +#if defined(__alpha__) || defined(__ia64__) #define my_llseek lseek diff --git a/fdisk/partname.c b/fdisk/partname.c new file mode 100644 index 00000000..b09b958a --- /dev/null +++ b/fdisk/partname.c @@ -0,0 +1,46 @@ +#include <ctype.h> +#include <stdio.h> +#include <string.h> +#include "common.h" + +/* + * return partition name - uses static storage unless buf is supplied + */ +static char * +partnamebf(char *dev, int pno, int lth, int bufsiz, char *bufp) { + static char buffer[80]; + char *p; + int w, wp; + + if (!bufp) { + bufp = buffer; + bufsiz = sizeof(buffer); + } + + w = strlen(dev); + p = ""; + + if (isdigit(dev[w-1])) + p = "p"; + + /* devfs kludge - note: fdisk partition names are not supposed + to equal kernel names, so there is no reason to do this */ + if (strcmp (dev + w - 4, "disc") == 0) { + w -= 4; + p = "part"; + } + + wp = strlen(p); + + if (lth) { + sprintf(bufp, "%*.*s%s%-2u", lth-wp-2, w, dev, p, pno); + } else { + sprintf(bufp, "%.*s%s%-2u", w, dev, p, pno); + } + return bufp; +} + +char * +partname(char *dev, int pno, int lth) { + return partnamebf(dev, pno, lth, 0, NULL); +} diff --git a/fdisk/sfdisk.8 b/fdisk/sfdisk.8 index e7f3e82b..0c62c2e9 100644 --- a/fdisk/sfdisk.8 +++ b/fdisk/sfdisk.8 @@ -265,6 +265,17 @@ Certain Disk Managers and boot loaders (such as OSBS, but not LILO or the OS/2 Boot Manager) also live in this empty space, so maybe you want this option if you use one. .TP +.BR \-E " or " \-\-DOS-extended +Take the starting sector numbers of "inner" extended partitions +to be relative to the starting cylinder boundary of the outer one, +(like some versions of DOS do) rather than to the starting sector +(like Linux does). +(The fact that there is a difference here means that one should +always let extended partitions start at cylinder boundaries if +DOS and Linux should interpret the partition table in the same way. +Of course one can only know where cylinder boundaries are when +one knows what geometry DOS will use for this disk.) +.TP .BR \-\-IBM " or " \-\-leave\-last Certain IBM diagnostic programs assume that they can use the last cylinder on a disk for disk-testing purposes. If you think @@ -339,7 +350,7 @@ details, see the .B lilo documentation. .LP -Each partition has a type, its `Id', and if this type is 5 +Each partition has a type, its `Id', and if this type is 5 or f .IR "" "(`" "extended partition" "')" the starting sector of the partition again contains 4 partition descriptors. MSDOS only uses the @@ -347,7 +358,7 @@ first two of these: the first one an actual data partition, and the second one again an extended partition (or empty). In this way one gets a chain of extended partitions. Other operating systems have slightly different conventions. -Linux also accepts type 85 as equivalent to 5 - this can be +Linux also accepts type 85 as equivalent to 5 and f - this can be useful if one wants to have extended partitions under Linux past the 1024 cylinder boundary, without DOS FDISK hanging. (If there is no good reason, you should just use 5, which is diff --git a/fdisk/sfdisk.c b/fdisk/sfdisk.c index 7bf7fd83..206ea28d 100644 --- a/fdisk/sfdisk.c +++ b/fdisk/sfdisk.c @@ -45,9 +45,9 @@ #include <getopt.h> #include <sys/ioctl.h> #include <sys/stat.h> +#include <sys/utsname.h> #include <linux/unistd.h> /* _syscall */ #include <linux/hdreg.h> /* HDIO_GETGEO */ -#include <linux/fs.h> /* BLKGETSIZE */ #include "nls.h" #include "common.h" @@ -69,8 +69,11 @@ int exit_status = 0; int force = 0; /* 1: do what I say, even if it is stupid ... */ int quiet = 0; /* 1: suppress all warnings */ +/* IA-64 gcc spec file currently does -DLinux... */ +#undef Linux int Linux = 0; /* 1: suppress warnings irrelevant for Linux */ int DOS = 0; /* 1: shift extended partitions by #sectors, not 1 */ +int DOS_extended = 0; /* 1: use starting cylinder boundary of extd partn */ int dump = 0; /* 1: list in a format suitable for later input */ int verify = 0; /* 1: check that listed partition is reasonable */ int no_write = 0; /* 1: do not actually write to disk */ @@ -80,7 +83,7 @@ int opt_list = 0; char *save_sector_file = NULL; char *restore_sector_file = NULL; -void +static void warn(char *s, ...) { va_list p; @@ -91,7 +94,7 @@ warn(char *s, ...) { va_end(p); } -void +static void error(char *s, ...) { va_list p; @@ -102,7 +105,7 @@ error(char *s, ...) { va_end(p); } -void +static void fatal(char *s, ...) { va_list p; @@ -125,23 +128,25 @@ fatal(char *s, ...) { * On the other hand, a 32 bit sector number is OK until 2TB. * The routines _llseek and sseek below are the only ones that * know about the loff_t type. + * + * Note: we use 512-byte sectors here, irrespective of the hardware ss. */ -#ifndef __alpha__ +#if !defined (__alpha__) && !defined (__ia64__) static _syscall5(int, _llseek, uint, fd, ulong, hi, ulong, lo, loff_t *, res, uint, wh); #endif -int +static int sseek(char *dev, unsigned int fd, unsigned long s) { loff_t in, out; in = ((loff_t) s << 9); out = 1; -#ifndef __alpha__ +#if !defined (__alpha__) && !defined (__ia64__) if (_llseek (fd, in>>32, in & 0xffffffff, &out, SEEK_SET) != 0) { #else - if ((out = lseek(fd, in, SEEK_SET)) != in) { + if ((out = lseek(fd, in, SEEK_SET)) != in) { #endif perror("llseek"); error(_("seek error on %s - cannot seek to %lu\n"), dev, s); @@ -172,7 +177,7 @@ struct sector { char data[512]; } *sectorhead; -void +static void free_sectors(void) { struct sector *s; @@ -183,7 +188,7 @@ free_sectors(void) { } } -struct sector * +static struct sector * get_sector(char *dev, int fd, unsigned long sno) { struct sector *s; @@ -198,7 +203,8 @@ get_sector(char *dev, int fd, unsigned long sno) { fatal(_("out of memory - giving up\n")); if (read(fd, s->data, sizeof(s->data)) != sizeof(s->data)) { - perror("read"); + if (errno) /* 0 in case we read past end-of-disk */ + perror("read"); error(_("read error on %s - cannot read sector %lu\n"), dev, sno); free(s); return 0; @@ -212,7 +218,7 @@ get_sector(char *dev, int fd, unsigned long sno) { return s; } -int +static int msdos_signature (struct sector *s) { if (*(unsigned short *) (s->data + 0x1fe) != 0xaa55) { error(_("ERROR: sector %lu does not have an msdos signature\n"), @@ -222,7 +228,7 @@ msdos_signature (struct sector *s) { return 1; } -int +static int write_sectors(char *dev, int fd) { struct sector *s; @@ -241,7 +247,7 @@ write_sectors(char *dev, int fd) { return 1; } -void +static void ulong_to_chars(unsigned long u, char *uu) { int i; @@ -251,7 +257,7 @@ ulong_to_chars(unsigned long u, char *uu) { } } -unsigned long +static unsigned long chars_to_ulong(unsigned char *uu) { int i; unsigned long u = 0; @@ -261,7 +267,7 @@ chars_to_ulong(unsigned char *uu) { return u; } -int +static int save_sectors(char *dev, int fdin) { struct sector *s; char ss[516]; @@ -295,9 +301,9 @@ save_sectors(char *dev, int fdin) { return 1; } -void reread_disk_partition(char *dev, int fd); +static void reread_disk_partition(char *dev, int fd); -int +static int restore_sectors(char *dev) { int fdin, fdout, ct; struct stat statbuf; @@ -370,6 +376,8 @@ restore_sectors(char *dev) { * unsigned short cylinders; * unsigned long start; * }; + * + * For large disks g.cylinders is truncated, so we use BLKGETSIZE. */ /* @@ -383,52 +391,64 @@ restore_sectors(char *dev) { struct geometry { unsigned long cylindersize; unsigned long heads, sectors, cylinders; + unsigned long start; } B, F, U; -void -get_cylindersize(char *dev, int fd, int silent) { +static struct geometry +get_geometry(char *dev, int fd, int silent) { struct hd_geometry g; - int ioctl_ok = 0; + long size; + struct geometry R; - B.heads = B.sectors = B.cylinders = 0; + if (ioctl(fd, BLKGETSIZE, &size)) { + size = 0; + if (!silent) + printf(_("Disk %s: cannot get size\n"), dev); + } + if (ioctl(fd, HDIO_GETGEO, &g)) { + g.heads = g.sectors = g.cylinders = g.start = 0; + if (!silent) + printf(_("Disk %s: cannot get geometry\n"), dev); + } + R.heads = g.heads; + R.sectors = g.sectors; + R.cylindersize = R.heads * R.sectors; + R.cylinders = (R.cylindersize ? size / R.cylindersize : 0); + R.start = g.start; + return R; +} - if (!ioctl(fd, HDIO_GETGEO, &g)) { - ioctl_ok = 1; +static void +get_cylindersize(char *dev, int fd, int silent) { + struct geometry R; - B.heads = g.heads; - B.sectors = g.sectors; - B.cylinders = g.cylinders; - } + R = get_geometry(dev, fd, silent); - if (U.heads) - B.heads = U.heads; - if (U.sectors) - B.sectors = U.sectors; - if (U.cylinders) - B.cylinders = U.cylinders; + B.heads = (U.heads ? U.heads : R.heads); + B.sectors = (U.sectors ? U.sectors : R.sectors); + B.cylinders = (U.cylinders ? U.cylinders : R.cylinders); B.cylindersize = B.heads * B.sectors; - if (ioctl_ok) { - if (g.start && !force) { - warn( - _("Warning: start=%d - this looks like a partition rather than\n" - "the entire disk. Using fdisk on it is probably meaningless.\n" - "[Use the --force option if you really want this]\n"), g.start); - exit(1); - } - if (B.heads != g.heads) - warn(_("Warning: HDIO_GETGEO says that there are %d heads\n"), - g.heads); - if (B.sectors != g.sectors) - warn(_("Warning: HDIO_GETGEO says that there are %d sectors\n"), - g.sectors); - if (B.cylinders != g.cylinders) - warn(_("Warning: HDIO_GETGEO says that there are %d cylinders\n"), - g.cylinders); - } else if (!silent) - if (!B.heads || !B.sectors || !B.cylinders) - printf(_("Disk %s: cannot get geometry\n"), dev); + if (R.start && !force) { + warn( + _("Warning: start=%d - this looks like a partition rather than\n" + "the entire disk. Using fdisk on it is probably meaningless.\n" + "[Use the --force option if you really want this]\n"), R.start); + exit(1); + } + + if (R.heads && B.heads != R.heads) + warn(_("Warning: HDIO_GETGEO says that there are %d heads\n"), + R.heads); + if (R.sectors && B.sectors != R.sectors) + warn(_("Warning: HDIO_GETGEO says that there are %d sectors\n"), + R.sectors); + if (R.cylinders && B.cylinders != R.cylinders + && B.cylinders < 65536 && R.cylinders < 65536) + warn(_("Warning: BLKGETSIZE/HDIO_GETGEO says that there are %d cylinders\n"), + R.cylinders); + if (B.sectors > 63) warn(_("Warning: unlikely number of sectors (%d) - usually at most 63\n" "This will give problems with all software that uses C/H/S addressing.\n"), @@ -444,7 +464,7 @@ chs zero_chs = { 0,0,0 }; typedef struct { unsigned long h,s,c; } longchs; longchs zero_longchs; -chs +static chs longchs_to_chs (longchs aa, struct geometry G) { chs a; @@ -461,7 +481,7 @@ longchs_to_chs (longchs aa, struct geometry G) { return a; } -longchs +static longchs chs_to_longchs (chs a) { longchs aa; @@ -472,7 +492,7 @@ chs_to_longchs (chs a) { return aa; } -longchs +static longchs ulong_to_longchs (unsigned long sno, struct geometry G) { longchs aa; @@ -486,27 +506,29 @@ ulong_to_longchs (unsigned long sno, struct geometry G) { } } -unsigned long -longchs_to_ulong (longchs aa, struct geometry G) { - return (aa.c*G.cylindersize + aa.h*G.sectors + aa.s - 1); -} - -chs +static chs ulong_to_chs (unsigned long sno, struct geometry G) { return longchs_to_chs(ulong_to_longchs(sno, G), G); } -unsigned long +#if 0 +static unsigned long +longchs_to_ulong (longchs aa, struct geometry G) { + return (aa.c*G.cylindersize + aa.h*G.sectors + aa.s - 1); +} + +static unsigned long chs_to_ulong (chs a, struct geometry G) { return longchs_to_ulong(chs_to_longchs(a), G); } +#endif -int +static int is_equal_chs (chs a, chs b) { return (a.h == b.h && a.s == b.s && a.c == b.c); } -int +static int chs_ok (chs a, char *v, char *w) { longchs aa = chs_to_longchs(a); int ret = 1; @@ -549,7 +571,7 @@ chs_ok (chs a, char *v, char *w) { /* List of partition types now in i386_sys_types.c */ -const char * +static const char * sysname(unsigned char type) { struct systypes *s; @@ -559,7 +581,7 @@ sysname(unsigned char type) { return _("Unknown"); } -void +static void list_types(void) { struct systypes *s; @@ -568,14 +590,14 @@ list_types(void) { printf("%2x %s\n", s->type, _(s->name)); } -int +static int is_extended(unsigned char type) { return (type == EXTENDED_PARTITION || type == LINUX_EXTENDED || type == WIN98_EXTENDED); } -int +static int is_bsd(unsigned char type) { return (type == BSD_PARTITION); } @@ -597,7 +619,7 @@ struct partition { /* Unfortunately, partitions are not aligned, and non-Intel machines are unhappy with non-aligned integers. So, we need a copy by hand. */ -int +static int copy_to_int(unsigned char *cp) { unsigned int m; @@ -608,7 +630,7 @@ copy_to_int(unsigned char *cp) { return m; } -void +static void copy_from_int(int m, char *cp) { *cp++ = (m & 0xff); m >>= 8; *cp++ = (m & 0xff); m >>= 8; @@ -616,7 +638,7 @@ copy_from_int(int m, char *cp) { *cp++ = (m & 0xff); } -void +static void copy_to_part(char *cp, struct partition *p) { p->bootable = *cp++; p->begin_chs.h = *cp++; @@ -630,7 +652,7 @@ copy_to_part(char *cp, struct partition *p) { p->nr_sects = copy_to_int(cp+4); } -void +static void copy_from_part(struct partition *p, char *cp) { *cp++ = p->bootable; *cp++ = p->begin_chs.h; @@ -661,14 +683,14 @@ struct part_desc { #define BSD_TYPE 1 } zero_part_desc; -struct part_desc * +static struct part_desc * outer_extended_partition(struct part_desc *p) { while (p->ep) p = p->ep; return p; } -int +static int is_parent(struct part_desc *pp, struct part_desc *p) { while (p) { if (pp == p) @@ -684,7 +706,7 @@ struct disk_desc { } oldp, newp; /* determine where on the disk this information goes */ -void +static void add_sector_and_offset(struct disk_desc *z) { int pno; struct part_desc *p; @@ -697,7 +719,7 @@ add_sector_and_offset(struct disk_desc *z) { } /* tell the kernel to reread the partition tables */ -int +static int reread_ioctl(int fd) { if(ioctl(fd, BLKRRPART)) { perror("BLKRRPART"); @@ -706,7 +728,7 @@ reread_ioctl(int fd) { return 0; } -int +static int is_blockdev(int fd) { struct stat statbuf; @@ -714,7 +736,7 @@ is_blockdev(int fd) { } /* reread after writing */ -void +static void reread_disk_partition(char *dev, int fd) { printf(_("Re-reading the partition table ...\n")); fflush(stdout); @@ -733,7 +755,7 @@ reread_disk_partition(char *dev, int fd) { } /* find Linux name of this partition, assuming that it will have a name */ -int +static int index_to_linux(int pno, struct disk_desc *z) { int i, ct = 1; struct part_desc *p = &(z->partitions[0]); @@ -743,7 +765,7 @@ index_to_linux(int pno, struct disk_desc *z) { return ct; } -int +static int linux_to_index(int lpno, struct disk_desc *z) { int i, ct = 0; struct part_desc *p = &(z->partitions[0]); @@ -754,7 +776,7 @@ linux_to_index(int lpno, struct disk_desc *z) { return -1; } -int +static int asc_to_index(char *pnam, struct disk_desc *z) { int pnum, pno; @@ -784,7 +806,7 @@ int one_only = 0; int one_only_pno; int increment = 0; -void +static void set_format(char c) { switch(c) { default: @@ -796,7 +818,7 @@ set_format(char c) { } } -unsigned long +static unsigned long unitsize(int format) { default_format = (B.cylindersize ? F_CYLINDER : F_MEGABYTE); if (!format && !(format = specified_format)) @@ -816,7 +838,7 @@ unitsize(int format) { } } -unsigned long +static unsigned long get_disksize(int format) { unsigned long cs = B.cylinders; if (cs && leave_last) @@ -824,7 +846,7 @@ get_disksize(int format) { return (cs * B.cylindersize) / unitsize(format); } -void +static void out_partition_header(char *dev, int format, struct geometry G) { if (dump) { printf(_("# partition table of %s\n"), dev); @@ -894,7 +916,7 @@ out_roundup_size(int width, unsigned long n, unsigned long unit) { putchar(' '); } -int +static int get_fdisk_geometry(struct part_desc *p) { chs b = p->p.end_chs; longchs bb = chs_to_longchs(b); @@ -904,7 +926,7 @@ get_fdisk_geometry(struct part_desc *p) { return (F.sectors != B.sectors || F.heads != B.heads); } -void +static void out_partition(char *dev, int format, struct part_desc *p, struct disk_desc *z, struct geometry G) { unsigned long start, end, size; @@ -916,7 +938,7 @@ out_partition(char *dev, int format, struct part_desc *p, pno = p - &(z->partitions[0]); /* our index */ lpno = index_to_linux(pno, z); /* name of next one that has a name */ if(pno == linux_to_index(lpno, z)) /* was that us? */ - printf("%8s%-2u", dev, lpno); /* yes */ + printf("%s", partname(dev, lpno, 10)); /* yes */ else if(show_extended) printf(" - "); else @@ -1009,7 +1031,7 @@ out_partition(char *dev, int format, struct part_desc *p, } } -void +static void out_partitions(char *dev, struct disk_desc *z) { struct part_desc *p; int pno, format = 0; @@ -1020,7 +1042,7 @@ out_partitions(char *dev, struct disk_desc *z) { for (pno=0; pno < z->partno; pno++) { p = &(z->partitions[pno]); if (p->size != 0 && p->p.sys_type != 0) { - if (get_fdisk_geometry(p)) + if (get_fdisk_geometry(p) && !dump) printf( _("Warning: The first partition looks like it was made\n" " for C/H/S=*/%ld/%ld (instead of %ld/%ld/%ld).\n" @@ -1046,7 +1068,7 @@ disj(struct part_desc *p, struct part_desc *q) { && q->start + q->size <= p->start + p->size)); } -char * +static char * pnumber(struct part_desc *p, struct disk_desc *z) { static char buf[20]; int this, next; @@ -1062,7 +1084,7 @@ pnumber(struct part_desc *p, struct disk_desc *z) { return buf; } -int +static int partitions_ok(struct disk_desc *z) { struct part_desc *partitions = &(z->partitions[0]), *p, *q; int partno = z->partno; @@ -1258,6 +1280,20 @@ extended_partition(char *dev, int fd, struct part_desc *ep, struct disk_desc *z) here = start = ep->start; + if (B.cylindersize && start % B.cylindersize) { + /* This is BAD */ + if (DOS_extended) { + here = start -= (start % B.cylindersize); + printf(_("Warning: shifted start of the extd partition from %ld to %ld\n"), + ep->start, start); + printf(_("(For listing purposes only. Do not change its contents.)\n")); + } else { + printf(_("Warning: extended partition does not start at a " + "cylinder boundary.\n")); + printf(_("DOS and Linux will interpret the contents differently.\n")); + } + } + while (moretodo) { moretodo = 0; @@ -1365,6 +1401,22 @@ bsd_partition(char *dev, int fd, struct part_desc *ep, struct disk_desc *z) { z->partno = pno; } +#define MAKE_VERSION(p,q,r) (65536*(p) + 256*(q) + (r)) + +static int +linux_version_code(void) { + struct utsname my_utsname; + int p, q, r; + + if (uname(&my_utsname) == 0) { + p = atoi(strtok(my_utsname.release, ".")); + q = atoi(strtok(NULL, ".")); + r = atoi(strtok(NULL, ".")); + return MAKE_VERSION(p,q,r); + } + return 0; +} + static int msdos_partition(char *dev, int fd, unsigned long start, struct disk_desc *z) { int i; @@ -1373,6 +1425,7 @@ msdos_partition(char *dev, int fd, unsigned long start, struct disk_desc *z) { struct sector *s; struct part_desc *partitions = &(z->partitions[0]); int pno = z->partno; + int bsd_later = (linux_version_code() >= MAKE_VERSION(2,3,40)); if (!(s = get_sector(dev, fd, start))) return 0; @@ -1421,7 +1474,7 @@ msdos_partition(char *dev, int fd, unsigned long start, struct disk_desc *z) { } extended_partition(dev, fd, &partitions[i], z); } - if (is_bsd(partitions[i].p.sys_type)) { + if (!bsd_later && is_bsd(partitions[i].p.sys_type)) { if (!partitions[i].size) { printf(_("strange..., a BSD partition of size 0?\n")); continue; @@ -1429,6 +1482,19 @@ msdos_partition(char *dev, int fd, unsigned long start, struct disk_desc *z) { bsd_partition(dev, fd, &partitions[i], z); } } + + if (bsd_later) { + for (i=0; i<4; i++) { + if (is_bsd(partitions[i].p.sys_type)) { + if (!partitions[i].size) { + printf(_("strange..., a BSD partition of size 0?\n")); + continue; + } + bsd_partition(dev, fd, &partitions[i], z); + } + } + } + return 1; } @@ -1447,7 +1513,7 @@ amiga_partition(char *dev, int fd, unsigned long start, struct disk_desc *z) { return 0; } -void +static void get_partitions(char *dev, int fd, struct disk_desc *z) { z->partno = 0; @@ -1460,7 +1526,7 @@ get_partitions(char *dev, int fd, struct disk_desc *z) { } } -int +static int write_partitions(char *dev, int fd, struct disk_desc *z) { struct sector *s; struct part_desc *partitions = &(z->partitions[0]), *p; @@ -1543,7 +1609,7 @@ struct dumpfld { #define RD_EOF (-1) #define RD_CMD (-2) -int +static int read_stdin(unsigned char **fields, unsigned char *line, int fieldssize, int linesize) { unsigned char *lp, *ip; int c, fno; @@ -1635,7 +1701,7 @@ read_stdin(unsigned char **fields, unsigned char *line, int fieldssize, int line } /* read a number, use default if absent */ -int +static int get_ul(char *u, unsigned long *up, unsigned long def, int base) { char *nu; @@ -1672,7 +1738,7 @@ int all_logicals_inside_outermost_extended = 1; enum { NESTED, CHAINED, ONESECTOR } boxes = NESTED; /* find the default value for <start> - assuming entire units */ -unsigned long +static unsigned long first_free(int pno, int is_extended, struct part_desc *ep, int format, unsigned long mid, struct disk_desc *z) { unsigned long ff, fff; @@ -1716,7 +1782,7 @@ first_free(int pno, int is_extended, struct part_desc *ep, int format, } /* find the default value for <size> - assuming entire units */ -unsigned long +static unsigned long max_length(int pno, int is_extended, struct part_desc *ep, int format, unsigned long start, struct disk_desc *z) { unsigned long fu; @@ -1745,7 +1811,7 @@ max_length(int pno, int is_extended, struct part_desc *ep, int format, /* compute starting sector of a partition inside an extended one */ /* ep is 0 or points to surrounding extended partition */ -int +static int compute_start_sect(struct part_desc *p, struct part_desc *ep) { unsigned long base; int inc = (DOS && B.sectors) ? B.sectors : 1; @@ -1785,7 +1851,7 @@ compute_start_sect(struct part_desc *p, struct part_desc *ep) { } /* build the extended partition surrounding a given logical partition */ -int +static int build_surrounding_extended(struct part_desc *p, struct part_desc *ep, struct disk_desc *z) { int inc = (DOS && B.sectors) ? B.sectors : 1; @@ -1819,7 +1885,7 @@ build_surrounding_extended(struct part_desc *p, struct part_desc *ep, return 1; } -int +static int read_line(int pno, struct part_desc *ep, char *dev, int interactive, struct disk_desc *z) { unsigned char line[1000]; @@ -1837,7 +1903,7 @@ read_line(int pno, struct part_desc *ep, char *dev, int interactive, if (interactive) { if (pct == 0 && (show_extended || pno == 0)) warn("\n"); - warn("%8s%d: ", dev, lpno); + warn("%s:", partname(dev, lpno, 10)); } /* read input line - skip blank lines when reading from a file */ @@ -1932,7 +1998,8 @@ read_line(int pno, struct part_desc *ep, char *dev, int interactive, p.size -= (p.size % unitsize(format)); } if (p.size > ml1) { - warn(_("Warning: exceeds max allowable size (%lu)\n"), ml1 / unitsize(0)); + warn(_("Warning: given size (%lu) exceeds max allowable size (%lu)\n"), + (p.size + unitsize(0) - 1) / unitsize(0), ml1 / unitsize(0)); if (!force) return 0; } @@ -2022,7 +2089,7 @@ read_line(int pno, struct part_desc *ep, char *dev, int interactive, /* ep either points to the extended partition to contain this one, or to the empty partition that may become extended or is 0 */ -int +static int read_partition(char *dev, int interactive, int pno, struct part_desc *ep, struct disk_desc *z) { struct part_desc *p = &(z->partitions[pno]); @@ -2050,7 +2117,7 @@ read_partition(char *dev, int interactive, int pno, struct part_desc *ep, return 1; } -void +static void read_partition_chain(char *dev, int interactive, struct part_desc *ep, struct disk_desc *z) { int i, base; @@ -2082,7 +2149,7 @@ read_partition_chain(char *dev, int interactive, struct part_desc *ep, } } -void +static void read_input(char *dev, int interactive, struct disk_desc *z) { int i; struct part_desc *partitions = &(z->partitions[0]), *ep; @@ -2191,6 +2258,7 @@ static const struct option long_opts[] = { { "sectors", required_argument, NULL, 'S' }, { "activate", optional_argument, NULL, 'A' }, { "DOS", no_argument, NULL, 'D' }, + { "DOS-extended", no_argument, NULL, 'E' }, { "Linux", no_argument, NULL, 'L' }, { "re-read", no_argument, NULL, 'R' }, { "list-types", no_argument, NULL, 'T' }, @@ -2219,7 +2287,7 @@ static struct devd { { "ed", "abcd" } }; -int +static int is_ide_cdrom(char *device) { /* No device was given explicitly, and we are trying some likely things. But opening /dev/hdc may produce errors like @@ -2244,14 +2312,14 @@ is_ide_cdrom(char *device) { return 0; } -void do_list(char *dev, int silent); -void do_size(char *dev, int silent); -void do_geom(char *dev, int silent); -void do_fdisk(char *dev); -void do_reread(char *dev); -void do_change_id(char *dev, char *part, char *id); -void do_unhide(char **av, int ac, char *arg); -void do_activate(char **av, int ac, char *arg); +static void do_list(char *dev, int silent); +static void do_size(char *dev, int silent); +static void do_geom(char *dev, int silent); +static void do_fdisk(char *dev); +static void do_reread(char *dev); +static void do_change_id(char *dev, char *part, char *id); +static void do_unhide(char **av, int ac, char *arg); +static void do_activate(char **av, int ac, char *arg); int total_size; @@ -2325,6 +2393,8 @@ main(int argc, char **argv) { U.cylinders = atoi(optarg); break; case 'D': DOS = 1; break; + case 'E': + DOS_extended = 1; break; case 'H': U.heads = atoi(optarg); break; case 'L': @@ -2463,7 +2533,7 @@ main(int argc, char **argv) { * H. Listing the current situation */ -int +static int my_open (char *dev, int rw, int silent) { int fd, mode; @@ -2476,7 +2546,7 @@ my_open (char *dev, int rw, int silent) { return fd; } -void +static void do_list (char *dev, int silent) { int fd; struct disk_desc *z; @@ -2502,25 +2572,23 @@ do_list (char *dev, int silent) { } } -void +static void do_geom (char *dev, int silent) { int fd; - struct hd_geometry g; + struct geometry R; fd = my_open(dev, 0, silent); if (fd < 0) return; - /* get_cylindersize(dev, fd, silent); */ - if (!ioctl(fd, HDIO_GETGEO, &g)) - printf(_("%s: %d cylinders, %d heads, %d sectors/track\n"), - dev, g.cylinders, g.heads, g.sectors); - else - printf(_("%s: unknown geometry\n"), dev); + R = get_geometry(dev, fd, silent); + if (R.cylinders) + printf(_("%s: %ld cylinders, %ld heads, %ld sectors/track\n"), + dev, R.cylinders, R.heads, R.sectors); } /* for compatibility with earlier fdisk: provide option -s */ -void +static void do_size (char *dev, int silent) { int fd; long size; @@ -2575,7 +2643,7 @@ do_size (char *dev, int silent) { * The present syntax was chosen to be (somewhat) compatible with the * activate from the LILO package. */ -void +static void set_active (struct disk_desc *z, char *pnam) { int pno; @@ -2583,7 +2651,7 @@ set_active (struct disk_desc *z, char *pnam) { z->partitions[pno].p.bootable = 0x80; } -void +static void do_activate (char **av, int ac, char *arg) { char *dev = av[0]; int fd; @@ -2605,7 +2673,7 @@ do_activate (char **av, int ac, char *arg) { if (z->partitions[pno].p.bootable) { lpno = index_to_linux(pno, z); if (pno == linux_to_index(lpno, z)) - printf("%s%d\n", dev, lpno); + printf("%s\n", partname(dev, lpno, 0)); else printf("%s#%d\n", dev, pno); if (z->partitions[pno].p.bootable != 0x80) @@ -2639,7 +2707,7 @@ do_activate (char **av, int ac, char *arg) { "but the DOS MBR will only boot a disk with 1 active partition.\n"), i); } -void +static void set_unhidden (struct disk_desc *z, char *pnam) { int pno; unsigned char id; @@ -2656,7 +2724,7 @@ set_unhidden (struct disk_desc *z, char *pnam) { /* * maybe remove and make part of --change-id */ -void +static void do_unhide (char **av, int ac, char *arg) { char *dev = av[0]; int fd, rw, i; @@ -2684,7 +2752,8 @@ do_unhide (char **av, int ac, char *arg) { exit_status = 1; } -void do_change_id(char *dev, char *pnam, char *id) { +static void +do_change_id(char *dev, char *pnam, char *id) { int fd, rw, pno; struct disk_desc *z; unsigned long i; @@ -2714,7 +2783,7 @@ void do_change_id(char *dev, char *pnam, char *id) { exit_status = 1; } -void +static void do_reread(char *dev) { int fd; @@ -2727,7 +2796,7 @@ do_reread(char *dev) { * I. Writing the new situation */ -void +static void do_fdisk(char *dev){ int fd; int c, answer; @@ -2748,15 +2817,15 @@ do_fdisk(char *dev){ if(!no_write && !no_reread) { warn(_("Checking that no-one is using this disk right now ...\n")); if(reread_ioctl(fd)) { - printf(_("\nThis disk is currently in use - repartitioning is probably a bad idea." - "Umount all file systems, and swapoff all swap partitions on this disk." + printf(_("\nThis disk is currently in use - repartitioning is probably a bad idea.\n" + "Umount all file systems, and swapoff all swap partitions on this disk.\n" "Use the --no-reread flag to suppress this check.\n")); if (!force) { printf(_("Use the --force flag to overrule all checks.\n")); exit(1); } } else - warn(_("OK")); + warn(_("OK\n")); } z = &oldp; |