diff options
Diffstat (limited to 'disk-utils/cfdisk.c')
-rw-r--r-- | disk-utils/cfdisk.c | 251 |
1 files changed, 189 insertions, 62 deletions
diff --git a/disk-utils/cfdisk.c b/disk-utils/cfdisk.c index 1b87aae79..f0b5482f1 100644 --- a/disk-utils/cfdisk.c +++ b/disk-utils/cfdisk.c @@ -29,7 +29,9 @@ * >2GB patches: Sat Feb 11 09:08:10 1995, faith@cs.unc.edu * Prettier menus: Sat Feb 11 09:08:25 1995, Janne Kukonlehto * <jtklehto@stekt.oulu.fi> - * Versions 0.8e-h: aeb@cwi.nl + * Versions 0.8e-l: aeb@cwi.nl + * Recognition of NTFS / HPFS difference inspired by patches + * from Marty Leisner <leisner@sdsp.mc.xerox.com> * ****************************************************************************/ @@ -41,12 +43,22 @@ #include <errno.h> #include <getopt.h> #include <fcntl.h> -#include <curses.h> +#ifdef SLCURSES + #include <slcurses.h> +#else +#if NCH + #include <ncurses.h> +#else + #include <curses.h> +#endif +#endif #include <signal.h> #include <math.h> +#include <locale.h> #include <string.h> #include <sys/stat.h> #include <sys/ioctl.h> +#include <linux/types.h> #include <linux/genhd.h> #include <linux/hdreg.h> #include <linux/fs.h> /* for BLKRRPART */ @@ -60,7 +72,7 @@ typedef long ext2_loff_t; extern ext2_loff_t ext2_llseek(unsigned int fd, ext2_loff_t offset, unsigned int origin); -#define VERSION "0.8i" +#define VERSION "0.8l" #define DEFAULT_DEVICE "/dev/hda" #define ALTERNATE_DEVICE "/dev/sda" @@ -78,12 +90,14 @@ extern ext2_loff_t ext2_llseek(unsigned int fd, ext2_loff_t offset, #define PART_TABLE_FLAG 0xAA55 #define UNUSABLE -1 -#define FREE_SPACE 0x00 -#define DOS_EXTENDED 0x05 +#define FREE_SPACE 0x00 +#define DOS_EXTENDED 0x05 +#define OS2_OR_NTFS 0x07 +#define WIN98_EXTENDED 0x0f #define LINUX_EXTENDED 0x85 -#define LINUX_MINIX 0x81 -#define LINUX_SWAP 0x82 -#define LINUX 0x83 +#define LINUX_MINIX 0x81 +#define LINUX_SWAP 0x82 +#define LINUX 0x83 #define ADD_EXISTS "This partition is already in use" #define ADD_UNUSABLE "This partition is unusable" @@ -157,10 +171,13 @@ extern ext2_loff_t ext2_llseek(unsigned int fd, ext2_loff_t offset, s |= (sector >> 2) & 0xC0;\ } -#define is_extended(x) ((x) == DOS_EXTENDED || (x) == LINUX_EXTENDED) +#define is_extended(x) ((x) == DOS_EXTENDED || (x) == WIN98_EXTENDED || \ + (x) == LINUX_EXTENDED) -/* we might also want to recognise 0xe and 0xf */ #define is_dos_partition(x) ((x) == 1 || (x) == 4 || (x) == 6) +#define may_have_dos_label(x) (is_dos_partition(x) \ + || (x) == 7 || (x) == 0xb || (x) == 0xc || (x) == 0xe \ + || (x) == 0x11 || (x) == 0x14 || (x) == 0x16 || (x) == 0x17) #define ALIGNMENT 2 typedef union { @@ -183,8 +200,12 @@ typedef struct { int flags; /* active == 0x80 */ int id; /* filesystem type */ int num; /* number of partition -- primary vs. logical */ -#define LABELSZ 11 - char dos_label[LABELSZ+1]; +#define LABELSZ 16 + char volume_label[LABELSZ+1]; +#define OSTYPESZ 8 + char ostype[OSTYPESZ+1]; +#define FSTYPESZ 8 + char fstype[FSTYPESZ+1]; } partition_info; char *disk_device = DEFAULT_DEVICE; @@ -227,8 +248,9 @@ int COMMAND_LINE_Y = 21; /* X coordinates */ int NAME_START = 4; int FLAGS_START = 16; -int PTYPE_START = 30; -int FSTYPE_START = 45; +int PTYPE_START = 28; +int FSTYPE_START = 38; +int LABEL_START = 54; int SIZE_START = 70; int COMMAND_LINE_X = 5; @@ -241,9 +263,13 @@ char *partition_type[NUM_PART_TYPES] = { [DOS_EXTENDED]= "Extended", [LINUX_EXTENDED] = "Linux extended", [0x01] = "DOS FAT12", + [0x02] = "XENIX root", + [0x03] = "XENIX usr", [0x04] = "DOS FAT16", [0x06] = "DOS FAT16 (big)", - [0x07] = "OS/2 HPFS or NTFS", + [OS2_OR_NTFS] = "OS/2 HPFS or NTFS", + [0x08] = "AIX", + [0x09] = "AIX bootable", [0x0A] = "OS/2 Boot Manager", [0x0B] = "Win95 FAT32", [0x0C] = "Win95 FAT32 (LBA)", @@ -252,17 +278,7 @@ char *partition_type[NUM_PART_TYPES] = { [0x11] = "Hidden DOS FAT12", [0x14] = "Hidden DOS FAT16", [0x16] = "Hidden DOS FAT16 (big)", - [0xA5] = "BSD/386", - -/* The rest of these are taken from A. V. Le Blanc's (LeBlanc@mcc.ac.uk) - * fdisk program. I do not know where they came from, but I include - * them for completeness. (With additions.) - */ - - [0x02] = "XENIX root", - [0x03] = "XENIX usr", - [0x08] = "AIX", - [0x09] = "AIX bootable", + [0x17] = "Hidden OS/2 HPFS or NTFS", [0x40] = "Venix 80286", [0x51] = "Novell?", [0x52] = "Microport", @@ -273,6 +289,9 @@ char *partition_type[NUM_PART_TYPES] = { [0x80] = "Old MINIX", [0x93] = "Amoeba", [0x94] = "Amoeba BBT", + [0xA5] = "BSD/386", + [0xA6] = "OpenBSD", + [0xA7] = "NEXTSTEP", [0xB7] = "BSDI fs", [0xB8] = "BSDI swap", [0xC7] = "Syrinx", @@ -283,6 +302,37 @@ char *partition_type[NUM_PART_TYPES] = { [0xFF] = "BBT" }; +/* Some libc's have their own basename() */ +char *my_basename(char *devname) +{ + char *s = rindex(devname, '/'); + return s ? s+1 : devname; +} + +char *partition_type_text(int i) +{ + if (p_info[i].id == UNUSABLE) + return "Unusable"; + else if (p_info[i].id == FREE_SPACE) + return "Free Space"; + else if (p_info[i].id == LINUX) { + if (!strcmp(p_info[i].fstype, "ext2")) + return "Linux ext2"; + else + return "Linux"; + } else if (p_info[i].id == OS2_OR_NTFS) { + if (!strncmp(p_info[i].fstype, "HPFS", 4)) + return "OS/2 HPFS"; + else if (!strncmp(p_info[i].ostype, "OS2", 3)) + return "OS/2 IFS"; + else if (!p_info[i].ostype) + return p_info[i].ostype; + else + return "NTFS"; + } else + return partition_type[p_info[i].id]; +} + void fdexit(int ret) { if (opened) @@ -416,7 +466,12 @@ void die_x(int ret) { signal(SIGINT, old_SIGINT); signal(SIGTERM, old_SIGTERM); +#ifdef SLCURSES + SLsmg_gotorc(LINES-1, 0); + SLsmg_refresh(); +#else mvcur(0, COLS-1, LINES-1, 0); +#endif nl(); endwin(); printf("\n"); @@ -439,21 +494,65 @@ void write_sector(char *buffer, int sect_num) fatal(BAD_WRITE); } +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++) + to[i] = from[i]; + to[i] = 0; +} + void get_dos_label(int i) { - char label[LABELSZ+1]; + char sector[128]; +#define DOS_OSTYPE_OFFSET 3 +#define DOS_LABEL_OFFSET 43 +#define DOS_FSTYPE_OFFSET 54 +#define DOS_OSTYPE_SZ 8 +#define DOS_LABEL_SZ 11 +#define DOS_FSTYPE_SZ 8 + ext2_loff_t offset; + + offset = ((ext2_loff_t) p_info[i].first_sector + p_info[i].offset) + * SECTOR_SIZE; + if (ext2_llseek(fd, offset, SEEK_SET) == offset + && read(fd, §or, sizeof(sector)) == sizeof(sector)) { + dos_copy_to_info(p_info[i].ostype, OSTYPESZ, + sector+DOS_OSTYPE_OFFSET, DOS_OSTYPE_SZ); + dos_copy_to_info(p_info[i].volume_label, LABELSZ, + sector+DOS_LABEL_OFFSET, DOS_LABEL_SZ); + dos_copy_to_info(p_info[i].fstype, FSTYPESZ, + sector+DOS_FSTYPE_OFFSET, DOS_FSTYPE_SZ); + } +} + +void get_ext2_label(int i) +{ +#define EXT2_SUPER_MAGIC 0xEF53 +#define EXT2LABELSZ 16 + struct ext2_super_block { + char s_dummy0[56]; + unsigned char s_magic[2]; + char s_dummy1[62]; + char s_volume_name[EXT2LABELSZ]; + char s_last_mounted[64]; + char s_dummy2[824]; + } sb; + char *label = sb.s_volume_name; ext2_loff_t offset; int j; offset = ((ext2_loff_t) p_info[i].first_sector + p_info[i].offset) - * SECTOR_SIZE + 43; + * SECTOR_SIZE + 1024; if (ext2_llseek(fd, offset, SEEK_SET) == offset - && read(fd, &label, LABELSZ) == LABELSZ) { - for(j=0; j<LABELSZ; j++) - if(!isascii(label[j])) + && read(fd, &sb, sizeof(sb)) == sizeof(sb) + && sb.s_magic[0] + 256*sb.s_magic[1] == EXT2_SUPER_MAGIC) { + for(j=0; j<EXT2LABELSZ; j++) + if(!isprint(label[j])) label[j] = 0; - label[LABELSZ] = 0; - strcpy(p_info[i].dos_label, label); + label[EXT2LABELSZ] = 0; + strncpy(p_info[i].volume_label, label, LABELSZ); + strncpy(p_info[i].fstype, "ext2", FSTYPESZ); } } @@ -560,7 +659,9 @@ void insert_empty_part(int i, int first, int last) p_info[i].flags = 0; p_info[i].id = FREE_SPACE; p_info[i].num = PRI_OR_LOG; - p_info[i].dos_label[0] = 0; + p_info[i].volume_label[0] = 0; + p_info[i].fstype[0] = 0; + p_info[i].ostype[0] = 0; num_parts++; } @@ -665,7 +766,9 @@ int add_part(int num, int id, int flags, int first, int last, int offset, ext_info.flags = flags; ext_info.id = id; ext_info.num = num; - ext_info.dos_label[0] = 0; + ext_info.volume_label[0] = 0; + ext_info.fstype[0] = 0; + ext_info.ostype[0] = 0; return 0; } else { return -1; /* explicit extended logical */ @@ -721,9 +824,15 @@ int add_part(int num, int id, int flags, int first, int last, int offset, p_info[i].flags = flags; p_info[i].id = id; p_info[i].num = num; - p_info[i].dos_label[0] = 0; - if (want_label && is_dos_partition(id)) - get_dos_label(i); + p_info[i].volume_label[0] = 0; + p_info[i].fstype[0] = 0; + p_info[i].ostype[0] = 0; + if (want_label) { + if (may_have_dos_label(id)) + get_dos_label(i); + else if (id == LINUX) + get_ext2_label(i); + } check_part_info(); @@ -881,7 +990,8 @@ int menuSelect( int y, int x, struct MenuItem *menuItems, int itemLength, char * while( !key ) { /* Display the menu */ - ylast = menuUpdate( y, x, menuItems, itemLength, available, menuType, current ); + ylast = menuUpdate( y, x, menuItems, itemLength, available, + menuType, current ); refresh(); key = getch(); /* Clear out all prompts and such */ @@ -996,8 +1106,9 @@ int menuSelect( int y, int x, struct MenuItem *menuItems, int itemLength, char * return key; } -/* A function which displays "Press a key to continue" and waits for a keypress * - * Perhaps calling function menuSelect is a bit overkill but who cares? */ +/* A function which displays "Press a key to continue" * + * and waits for a keypress. * + * Perhaps calling function menuSelect is a bit overkill but who cares? */ void menuContinue(void) { @@ -1176,7 +1287,15 @@ void fill_p_info(void) opentype = O_RDWR; opened = TRUE; - read_sector(buffer.c.b, 0); + /* Blocks are visible in more than one way: + e.g. as block on /dev/hda and as block on /dev/hda3 + By a bug in the Linux buffer cache, we will see the old + contents of /dev/hda when the change was made to /dev/hda3. + In order to avoid this, discard all blocks on /dev/hda. + Note that partition table blocks do not live in /dev/hdaN, + so this only plays a role if we want to show volume labels. */ + ioctl(fd, BLKFLSBUF); /* ignore errors */ + /* e.g. Permission Denied */ if (!ioctl(fd, HDIO_GETGEO, &geometry)) { if (!heads) @@ -1188,7 +1307,9 @@ void fill_p_info(void) } if (!heads || !sectors || !cylinders) - fatal(BAD_GEOMETRY); + fatal(BAD_GEOMETRY); /* probably a file or cdrom */ + + read_sector(buffer.c.b, 0); clear_p_info(); @@ -1651,7 +1772,7 @@ void print_part_entry(FILE *fp, int num, partition_info *pi) ec = end / heads; } - fp_printf(fp, "%2d 0x%02X %4d %4d %4d 0x%02X %4d %4d %4d %7d %9d\n", + fp_printf(fp, "%2d 0x%02X %4d %4d %4d 0x%02X %4d %4d %4d %8d %9d\n", num+1, flags, sh, ss, sc, id, eh, es, ec, first, size); } @@ -1688,9 +1809,9 @@ void print_part_table(void) fp_printf(fp, "Partition Table for %s\n", disk_device); fp_printf(fp, "\n"); - fp_printf(fp, " ---Starting--- ----Ending---- Start Number of\n"); - fp_printf(fp, " # Flags Head Sect Cyl ID Head Sect Cyl Sector Sectors\n"); - fp_printf(fp, "-- ----- ---- ---- ---- ---- ---- ---- ---- ------- ---------\n"); + fp_printf(fp, " ---Starting--- ----Ending---- Start Number of\n"); + fp_printf(fp, " # Flags Head Sect Cyl ID Head Sect Cyl Sector Sectors\n"); + fp_printf(fp, "-- ----- ---- ---- ---- ---- ---- ---- ---- -------- ---------\n"); for (i = 0; i < 4; i++) { for (j = 0; @@ -1761,7 +1882,7 @@ void display_help() "allows you to create, delete and modify partitions on your hard", "disk drive.", "", - "Copyright (C) 1994-1997 Kevin E. Martin & aeb", + "Copyright (C) 1994-1998 Kevin E. Martin & aeb", "", "Command Meaning", "------- -------", @@ -1984,6 +2105,7 @@ 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; if (!arrow_cursor) { move(y, 0); @@ -1993,7 +2115,7 @@ void draw_partition(int i) if (p_info[i].id > 0) { mvprintw(y, NAME_START, - "%s%d", disk_device, p_info[i].num+1); + "%s%d", my_basename(disk_device), p_info[i].num+1); if (p_info[i].flags) { if (p_info[i].flags == ACTIVE_FLAG) mvaddstr(y, FLAGS_START, "Boot"); @@ -2022,18 +2144,18 @@ void draw_partition(int i) (p_info[i].num >= 0 ? "Primary" : (p_info[i].num == PRI_OR_LOG ? "Pri/Log" : (p_info[i].num == PRIMARY ? "Primary" : "Logical")))))); - if (p_info[i].id == UNUSABLE) - mvaddstr(y, FSTYPE_START, "Unusable"); - else if (p_info[i].id == FREE_SPACE) - mvaddstr(y, FSTYPE_START, "Free Space"); - else if (partition_type[p_info[i].id]) - mvaddstr(y, FSTYPE_START, partition_type[p_info[i].id]); + + t = partition_type_text(i); + if (t) + mvaddstr(y, FSTYPE_START, t); else - mvprintw(y, FSTYPE_START, "Unknown (%02X)", p_info[i].id); + mvprintw(y, FSTYPE_START, "Unknown (%02X)", p_info[i].id); - if (p_info[i].dos_label[0]) { - int l = strlen(p_info[i].dos_label); - mvprintw(y, SIZE_START-5-l, " [%s] ", p_info[i].dos_label); + if (p_info[i].volume_label[0]) { + int l = strlen(p_info[i].volume_label); + int s = SIZE_START-5-l; + mvprintw(y, (s > LABEL_START) ? LABEL_START : s, + " [%s] ", p_info[i].volume_label); } size = p_info[i].last_sector - p_info[i].first_sector + 1; @@ -2056,6 +2178,7 @@ void init_const(void) FLAGS_START = (((float)FLAGS_START)/COLUMNS)*COLS; PTYPE_START = (((float)PTYPE_START)/COLUMNS)*COLS; FSTYPE_START = (((float)FSTYPE_START)/COLUMNS)*COLS; + LABEL_START = (((float)LABEL_START)/COLUMNS)*COLS; SIZE_START = (((float)SIZE_START)/COLUMNS)*COLS; COMMAND_LINE_X = (((float)COMMAND_LINE_X)/COLUMNS)*COLS; @@ -2101,8 +2224,9 @@ void draw_screen(void) mvaddstr(DISK_TABLE_START, NAME_START, "Name"); mvaddstr(DISK_TABLE_START, FLAGS_START, "Flags"); - mvaddstr(DISK_TABLE_START, PTYPE_START, "Part Type"); + mvaddstr(DISK_TABLE_START, PTYPE_START-1, "Part Type"); mvaddstr(DISK_TABLE_START, FSTYPE_START, "FS Type"); + mvaddstr(DISK_TABLE_START, LABEL_START+1, "[Label]"); if (display_units == SECTORS) mvaddstr(DISK_TABLE_START, SIZE_START, " Sectors"); else if (display_units == CYLINDERS) @@ -2178,6 +2302,8 @@ void do_curses_fdisk(void) }; curses_started = 1; initscr(); + init_const(); + old_SIGINT = signal(SIGINT, die); old_SIGTERM = signal(SIGTERM, die); #ifdef DEBUG @@ -2189,8 +2315,6 @@ void do_curses_fdisk(void) noecho(); nonl(); - init_const(); - fill_p_info(); draw_screen(); @@ -2353,6 +2477,8 @@ int main(int argc, char **argv) char c; int i, len; + setlocale(LC_CTYPE, ""); + while ((c = getopt(argc, argv, "ac:h:s:vzP:")) != EOF) switch (c) { case 'a': @@ -2429,5 +2555,6 @@ int main(int argc, char **argv) print_part_table(); } else do_curses_fdisk(); + return 0; } |