📄 fdisk.c
字号:
/* fdisk - partition a hard disk Author: Jakob Schripsema *//* Run this with: * * fdisk [-hheads] [-ssectors] [device] * * e.g., * * fdisk (to get the default) * fdisk -h4 -s17 /dev/hd0 (MINIX default) * fdisk -h4 -s17 c: (DOS default) * fdisk -h6 -s25 /dev/hd5 (second drive, probably RLL) * fdisk junkfile (to experiment safely) * * The device is opened in read-only mode if the file permissions do not * permit read-write mode, so it is convenient to use a login account with * only read permission to look at the partition table safely. * * Compile with: * * cc -i -o fdisk fdisk.c (MINIX) * cl -DDOS fdisk.c (DOS with MS C compiler) * * This was modified extensively by Bruce Evans 28 Dec 89. * The new version has not been tried with DOS. The open modes are suspect * (everyone should convert to use fcntl.h). * * Changed 18 Dec 92 by Kees J. Bot: Bootstrap code and geometry from device. * * modified 01 March 95 by asw: updated list of known partition types. Also * changed display format slightly to allow for partition type names of * up to 9 chars (previous format allowed for 7, but there were already * some 8 char names in the list).*/#include <sys/types.h>#include <ibm/partition.h>#include <minix/partition.h>#include <sys/ioctl.h>#include <sys/stat.h>#include <fcntl.h>#include <string.h>#include <stdlib.h>#include <unistd.h>#include <stdio.h>#include <errno.h>#ifdef DOS#include <dos.h>#define DEFAULT_DEV "c:"#define LOAD_OPEN_MODE 0x8000#define SAVE_CREAT_MODE 0644#else#define DEFAULT_DEV "/dev/hd0"#define LOAD_OPEN_MODE 0#define SAVE_CREAT_MODE 0644#define UNIX /* for MINIX */#endif/* Constants */#define DEFAULT_NHEAD 4 /* # heads */#define DEFAULT_NSEC 17 /* sectors / track */#define SECSIZE 512 /* sector size */#define OK 0#define ERR 1#define CYL_MASK 0xc0 /* mask to extract cyl bits from sec field */#define CYL_SHIFT 2 /* shift to extract cyl bits from sec field */#define SEC_MASK 0x3f /* mask to extract sec bits from sec field *//* Globals */char rawsecbuf[SECSIZE + sizeof(long)];char *secbuf;int badbases;int badsizes;int badorders;char *devname;int nhead;int nsec;int ncyl = 1024;int readonly;int override= 0;_PROTOTYPE(int main, (int argc, char *argv []));_PROTOTYPE(void getgeom, (void));_PROTOTYPE(int getboot, (char *buffer));_PROTOTYPE(int putboot, (char *buffer));_PROTOTYPE(int load_from_file, (void));_PROTOTYPE(int save_to_file, (void));_PROTOTYPE(int dpl_partitions, (int rawflag));_PROTOTYPE(int chk_table, (void));_PROTOTYPE(int sec_to_hst, (long logsec, unsigned char *hd, unsigned char *sec, unsigned char *cyl));_PROTOTYPE(int mark_partition, (struct part_entry *pe));_PROTOTYPE(int change_partition, (struct part_entry *entry));_PROTOTYPE(int get_a_char, (void));_PROTOTYPE(int print_menu, (void));_PROTOTYPE(void adj_base, (struct part_entry *pe));_PROTOTYPE(void adj_size, (struct part_entry *pe));_PROTOTYPE(struct part_entry *ask_partition, (void));_PROTOTYPE(void footnotes, (void));_PROTOTYPE(int get_an_int, (char *prompt, int *intptr));_PROTOTYPE(void list_part_types, (void));_PROTOTYPE(void mark_npartition, (struct part_entry *pe));_PROTOTYPE(int mygets, (char *buf, int length));_PROTOTYPE(char *systype, (int type));_PROTOTYPE(void toggle_active, (struct part_entry *pe));_PROTOTYPE(void usage, (void));/* One featureful master bootstrap. */char bootstrap[] = {0353,0001,0000,0061,0300,0216,0330,0216,0300,0372,0216,0320,0274,0000,0174,0373,0275,0276,0007,0211,0346,0126,0277,0000,0006,0271,0000,0001,0374,0363,0245,0352,0044,0006,0000,0000,0264,0002,0315,0026,0250,0010,0164,0033,0350,0071,0001,0174,0007,0060,0344,0315,0026,0242,0205,0007,0054,0060,0074,0012,0163,0363,0120,0350,0046,0001,0205,0007,0130,0353,0012,0240,0002,0006,0204,0300,0165,0003,0351,0147,0000,0230,0262,0005,0366,0362,0262,0200,0000,0302,0210,0340,0120,0350,0234,0000,0163,0003,0351,0147,0000,0130,0054,0001,0175,0003,0351,0141,0000,0276,0276,0175,0211,0357,0271,0040,0000,0363,0245,0200,0301,0004,0211,0356,0215,0174,0020,0070,0154,0004,0164,0016,0213,0135,0010,0053,0134,0010,0213,0135,0012,0033,0134,0012,0163,0014,0212,0044,0206,0144,0020,0210,0044,0106,0071,0376,0162,0364,0211,0376,0201,0376,0356,0007,0162,0326,0342,0322,0211,0356,0264,0020,0366,0344,0001,0306,0200,0174,0004,0001,0162,0026,0353,0021,0204,0322,0175,0041,0211,0356,0200,0174,0004,0000,0164,0013,0366,0004,0200,0164,0006,0350,0070,0000,0162,0053,0303,0203,0306,0020,0201,0376,0376,0007,0162,0346,0350,0215,0000,0211,0007,0376,0302,0204,0322,0174,0023,0315,0021,0321,0340,0321,0340,0200,0344,0003,0070,0342,0167,0355,0350,0011,0000,0162,0350,0303,0350,0003,0000,0162,0146,0303,0211,0356,0214,0134,0010,0214,0134,0012,0277,0003,0000,0122,0006,0127,0264,0010,0315,0023,0137,0007,0200,0341,0077,0376,0306,0210,0310,0366,0346,0211,0303,0213,0104,0010,0213,0124,0012,0367,0363,0222,0210,0325,0366,0361,0060,0322,0321,0352,0321,0352,0010,0342,0210,0321,0376,0301,0132,0210,0306,0273,0000,0174,0270,0001,0002,0315,0023,0163,0020,0200,0374,0200,0164,0011,0117,0174,0006,0060,0344,0315,0023,0163,0270,0371,0303,0201,0076,0376,0175,0125,0252,0165,0001,0303,0350,0013,0000,0243,0007,0353,0005,0350,0004,0000,0227,0007,0353,0376,0136,0255,0126,0211,0306,0254,0204,0300,0164,0011,0264,0016,0273,0001,0000,0315,0020,0353,0362,0303,0057,0144,0145,0166,0057,0150,0144,0077,0010,0000,0015,0012,0000,0116,0157,0156,0145,0040,0141,0143,0164,0151,0166,0145,0015,0012,0000,0122,0145,0141,0144,0040,0145,0162,0162,0157,0162,0040,0000,0116,0157,0164,0040,0142,0157,0157,0164,0141,0142,0154,0145,0040,0000,0000,};main(argc, argv)int argc;char *argv[];{ int argn; char *argp; int ch; /* Init */ nhead = DEFAULT_NHEAD; nsec = DEFAULT_NSEC; for (argn = 1; argn < argc && (argp = argv[argn])[0] == '-'; ++argn) { if (argp[1] == 'h') nhead = atoi(argp + 2); else if (argp[1] == 's') nsec = atoi(argp + 2); else usage(); override= 1; } if (argn == argc) devname = DEFAULT_DEV; else if (argn == argc - 1) devname = argv[argn]; else usage(); /* Align the sector buffer in such a way that the partition table is at * a mod 4 offset in memory. Some weird people add alignment checks to * their Minix! */ secbuf = rawsecbuf; while ((long)(secbuf + PART_TABLE_OFF) % sizeof(long) != 0) secbuf++; getgeom(); getboot(secbuf); chk_table(); do { putchar('\n'); dpl_partitions(0); printf( "\n(Enter 'h' for help. A null line will abort any operation) "); ch = get_a_char(); putchar('\n'); switch (ch) { case '+': footnotes(); break; case 'a': toggle_active(ask_partition()); break; case 'B': adj_base(ask_partition()); break; case 'c': change_partition(ask_partition()); break; case 'h': print_menu(); break; case 'l': load_from_file(); break; case 'm': mark_partition(ask_partition()); break; case 'n': mark_npartition(ask_partition()); break; case 'p': dpl_partitions(1); break; case 0: case 'q': exit(0); case 'S': adj_size(ask_partition()); break; case 's': save_to_file(); break; case 't': list_part_types(); break; case 'v': printf("Partition table is %svalid\n", chk_table() == OK ? "" : "in"); break; case 'w': if (readonly) printf("Write disabled\n"); else if(chk_table() == OK) { putboot(secbuf); printf( "Partition table has been updated and the file system synced.\n"); printf("Please reboot now.\n"); exit(0); } else printf("Not written\n"); break; default: printf(" %c ????\n", ch); break; } } while (1);}#ifdef UNIXvoid getgeom(){ struct partition geom; int fd, r; if (override) return; if ((fd= open(devname, O_RDONLY)) < 0) return; r = ioctl(fd, DIOCGETP, &geom); close(fd); if (r < 0) return; nhead = geom.heads; nsec = geom.sectors; ncyl = geom.cylinders; printf("Geometry of %s: %dx%dx%d\n", devname, ncyl, nhead, nsec);}static int devfd;getboot(buffer)char *buffer;{ devfd = open(devname, 2); if (devfd < 0) { printf("No write permission on %s\n", devname); readonly = 1; devfd = open(devname, 0); } if (devfd < 0) { printf("Cannot open device %s\n", devname); exit(1); } if (read(devfd, buffer, SECSIZE) != SECSIZE) { printf("Cannot read boot sector\n"); exit(1); } if (* (unsigned short *) &buffer[510] != 0xAA55) { printf("Invalid boot sector on %s.\n", devname); printf("Partition table reset and boot code installed.\n"); memset(buffer, 0, 512); memcpy(buffer, bootstrap, sizeof(bootstrap)); * (unsigned short *) &buffer[510] = 0xAA55; }}putboot(buffer)char *buffer;{ if (lseek(devfd, 0L, 0) < 0) { printf("Seek error during write\n"); exit(1); } if (write(devfd, buffer, SECSIZE) != SECSIZE) { printf("Write error\n"); exit(1); } sync();}#endifload_from_file(){/* Load buffer from file */ char file[80]; int fd; printf("Enter name of file to load from: "); if (!mygets(file, (int) sizeof file)) return; fd = open(file, LOAD_OPEN_MODE); if (fd < 0) { printf("Cannot open %s\n", file); return; } if (read(fd, secbuf, SECSIZE) != SECSIZE || close(fd) != 0) { printf("Read error\n"); exit(1); } printf("Loaded from %s OK\n", file); chk_table();}save_to_file(){/* Save to file */ char file[80]; int fd; printf("Enter name of file to save to: "); if (!mygets(file, (int) sizeof file)) return; if(chk_table() != OK) printf("Saving anyway\n"); fd = creat(file, SAVE_CREAT_MODE);#ifdef DOS if (fd < 0) { printf("Cannot creat %s\n", file); return; } close(fd); fd = open(file, 0x8001);#endif if (fd < 0) printf("Cannot open %s\n", file); else if (write(fd, secbuf, SECSIZE) != SECSIZE || close(fd) != 0) printf("Write error\n"); else printf("Saved to %s OK\n", file);}dpl_partitions(rawflag)int rawflag;{/* Display partition table */ char active[5]; char basefootnote; int cyl_mask; int devnum; char *format; int i; int i1; char orderfootnote; struct part_entry *pe; struct part_entry *pe1; int sec_mask; char sizefootnote; char type[10]; badbases = 0; badsizes = 0; badorders = 0; if (rawflag) { cyl_mask = 0; /* no contribution of cyl to sec */ sec_mask = 0xff; format ="%2d %3d%c %4s %-9s x%02x %3d x%02x x%02x %3d x%02x %7ld%c%7ld %7ld%c\n"; } else { cyl_mask = CYL_MASK; sec_mask = SEC_MASK; format ="%2d %3d%c %4s %-9s %4d %3d %3d %4d %3d %3d %7ld%c%7ld %7ld%c\n"; } printf(" ----first---- -----last---- --------sectors-------\n" ); printf("Num Sorted Act Type Cyl Head Sec Cyl Head Sec Base Last Size\n" ); pe = (struct part_entry *) &secbuf[PART_TABLE_OFF]; for (i = 1; i <= NR_PARTITIONS; i++, pe++) { if (rawflag) { sprintf(active, "0x%02x", pe->bootind); sprintf(type, "0x%02x", pe->sysind); } else { sprintf(active, "%s", pe->bootind == ACTIVE_FLAG ? "A " : ""); sprintf(type, "%s", systype(pe->sysind)); } /* Prepare warnings about confusing setups from old versions. */ basefootnote = orderfootnote = sizefootnote = ' '; if (pe->sysind == MINIX_PART && pe->lowsec & 1) { basefootnote = '+'; ++badbases; } if (pe->size & 1) { sizefootnote = '-'; ++badsizes; } /* Calculate the "device numbers" resulting from the misguided sorting * in the wini drivers. The drivers use this conditional for * swapping wn[j] > wn[j+1]: * * if ((wn[j].wn_low == 0 && wn[j+1].wn_low != 0) || * (wn[j].wn_low > wn[j+1].wn_low && wn[j+1].wn_low != 0)) { * * which simplifies to: * * if (wn[j+1].wn_low != 0 && * (wn[j].wn_low == 0 || wn[j].wn_low > wn[j+1].wn_low)) { */ devnum = 1; for (i1 = 1, pe1 = (struct part_entry *) &secbuf[PART_TABLE_OFF]; i1 <= NR_PARTITIONS; ++i1, ++pe1) if (pe1->lowsec == 0 && pe->lowsec == 0 && pe1 < pe || pe1->lowsec != 0 && (pe->lowsec == 0 || pe->lowsec > pe1->lowsec)) ++devnum; /* pe1 contents < pe contents */ if (devnum != i) { orderfootnote = '#'; ++badorders; } printf(format, i, devnum, orderfootnote, active, type, pe->start_cyl + ((pe->start_sec & cyl_mask) << CYL_SHIFT), pe->start_head, pe->start_sec & sec_mask, pe->last_cyl + ((pe->last_sec & cyl_mask) << CYL_SHIFT), pe->last_head, pe->last_sec & sec_mask, pe->lowsec, basefootnote, pe->lowsec + (pe->size == 0 ? 0 : pe->size - 1), pe->size, sizefootnote); }}int chk_table(){/* Check partition table */ int active; unsigned char cylinder; unsigned char head; int i; int i1; int maxhead; int maxsec; struct part_entry *pe; struct part_entry *pe1; unsigned char sector; int seenpart; int status; active = 0; maxhead = 0; maxsec = 0; pe = (struct part_entry *) &secbuf[PART_TABLE_OFF]; seenpart = 0; status = OK; for (i = 1; i <= NR_PARTITIONS; i++, ++pe) { if (pe->bootind == ACTIVE_FLAG) active++; sec_to_hst(pe->lowsec, &head, §or, &cylinder); if (pe->size == 0 && pe->lowsec == 0) sector = 0; if (head != pe->start_head || sector != pe->start_sec || cylinder != pe->start_cyl) { printf("Inconsistent base in partition %d.\n", i); printf("Suspect head and sector parameters.\n"); status = ERR; } if (pe->size != 0 || pe->lowsec != 0) sec_to_hst(pe->lowsec + pe->size - 1, &head, §or, &cylinder); if (head != pe->last_head || sector != pe->last_sec || cylinder != pe->last_cyl) { printf("Inconsistent size in partition %d.\n", i); printf("Suspect head and sector parameters.\n"); status = ERR; } if (pe->size == 0) continue; seenpart = 1; for (i1 = i + 1, pe1 = pe + 1; i1 <= NR_PARTITIONS; ++i1, ++pe1) { if (pe->lowsec >= pe1->lowsec && pe->lowsec < pe1->lowsec + pe1->size || pe->lowsec + pe->size - 1 >= pe1->lowsec && pe->lowsec + pe->size - 1 < pe1->lowsec + pe1->size) { printf("Overlap between partitions %d and %d\n", i, i1); status = ERR; } } if (pe->lowsec + pe->size < pe->lowsec) { printf("Overflow from preposterous size in partition %d.\n",
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -