📄 fdisk.c
字号:
i); status = ERR; } if (maxhead < pe->start_head) maxhead = pe->start_head; if (maxhead < pe->last_head) maxhead = pe->last_head; if (maxsec < (pe->start_sec & SEC_MASK)) maxsec = (pe->start_sec & SEC_MASK); if (maxsec < (pe->last_sec & SEC_MASK)) maxsec = (pe->last_sec & SEC_MASK); } if (seenpart) { if (maxhead + 1 != nhead || maxsec != nsec) { printf( "Disk appears to have mis-specified number of heads or sectors.\n"); printf("Try fdisk -h%d -s%d %s instead of\n", maxhead + 1, maxsec, devname); printf(" fdisk -h%d -s%d %s\n", nhead, nsec, devname); seenpart = 0; } } else { printf( "Empty table - skipping test on number of heads and sectors.\n"); printf("Assuming %d heads and %d sectors.\n", nhead, nsec); } if (!seenpart) printf("Do not write the table if you are not sure!.\n"); if (active > 1) { printf("%d active partitions\n", active); status = ERR; } return(status);}sec_to_hst(logsec, hd, sec, cyl)long logsec;unsigned char *hd, *sec, *cyl;{/* Convert a logical sector number to head / sector / cylinder */ int bigcyl; bigcyl = logsec / (nhead * nsec); *sec = (logsec % nsec) + 1 + ((bigcyl >> CYL_SHIFT) & CYL_MASK); *cyl = bigcyl; *hd = (logsec % (nhead * nsec)) / nsec;}mark_partition(pe)struct part_entry *pe;{/* Mark a partition as being of type MINIX. */ if (pe != NULL) { pe->sysind = MINIX_PART; printf("Partition type is now MINIX\n"); }}change_partition(entry)struct part_entry *entry;{/* Get partition info : first & last cylinder */ int first, last; long low, high; int ch; if (entry == NULL) return; while (1) { if (!get_an_int("\tEnter first cylinder (an integer >= 0): ", &first)) return; if (first >= 0) break; printf("\t\tThat looks like %d which is negative\n", first); } while (1) { if (!get_an_int( "\tEnter last cylinder (an integer >= the first cylinder): ", &last)) return; if (last >= first) break; printf("\t\tThat looks like %d which is too small\n", last); } if (first == 0 && last == 0) { entry->bootind = 0; entry->start_head = 0; entry->start_sec = 0; entry->start_cyl = 0; entry->sysind = NO_PART; entry->last_head = 0; entry->last_sec = 0; entry->last_cyl = 0; entry->lowsec = 0; entry->size = 0; printf("Partition deleted\n"); return; } low = first & 0xffff; low = low * nsec * nhead; if (low == 0) low = 1; /* sec0 is master boot record */ high = last & 0xffff; high = (high + 1) * nsec * nhead - 1; entry->lowsec = low; entry->size = high - low + 1; if (entry->size & 1) { /* Adjust size to even since Minix works with blocks of 2 sectors. */ --high; --entry->size; printf("Size reduced by 1 to make it even\n"); } sec_to_hst(low, &entry->start_head, &entry->start_sec, &entry->start_cyl); sec_to_hst(high, &entry->last_head, &entry->last_sec, &entry->last_cyl); printf("Base of partition changed to %ld, size changed to %ld\n", entry->lowsec, entry->size); /* Accept the MINIX partition type. Usually ignore foreign types, so this * fdisk can be used on foreign partitions. Don't allow NO_PART, because * many DOS fdisks crash on it. */ if (entry->sysind == NO_PART) { entry->sysind = MINIX_PART; printf("Partition type changed from None to MINIX\n"); } else if (entry->sysind == MINIX_PART) printf("Leaving partition type as MINIX\n"); else while (1) { printf("\tChange partition type from %s to MINIX? (y/n) ", systype(entry->sysind)); ch = get_a_char(); if (ch == 0 || ch == 'n') { printf("Leaving partition type as %s\n", systype(entry->sysind)); break; } else if (ch == 'y') { entry->sysind = MINIX_PART; printf("Partition type changed from %s to MINIX\n", systype(entry->sysind)); break; } } if (entry->bootind == ACTIVE_FLAG) printf("Leaving partition active\n"); else while (1) { printf("\tChange partition to active? (y/n) "); ch = get_a_char(); if (ch == 0 || ch == 'n') { printf("Leaving partition inactive\n"); break; } else if (ch == 'y') { toggle_active(entry); break; } }}get_a_char(){/* Read 1 character and discard rest of line */ char buf[80]; int ch; if (!mygets(buf, (int) sizeof buf)) return(0); return(*buf);}print_menu(){ printf("Type a command letter, then a carriage return:\n"); printf(" + - explain any footnotes (+, -, #)\n"); printf(" a - toggle an active flag\n"); printf(" B - adjust a base sector\n"); printf(" c - change a partition\n"); printf(" l - load boot block (including partition table) from a file\n"); printf(" m - mark a partition as a MINIX partition\n"); printf(" n - mark a partition as a non-MINIX partition\n"); printf(" p - print raw partition table\n"); printf(" q - quit without making any changes\n"); printf(" S - adjust a size (by changing the last sector)\n"); printf(" s - save boot block (including partition table) on a file\n"); printf(" t - print known partition types\n"); printf(" v - verify partition table\n"); if (readonly) printf(" w - write (disabled)\n"); else printf(" w - write changed partition table back to disk and exit\n");}/* Here are the DOS routines for reading and writing the boot sector. */#ifdef DOSunion REGS regs;struct SREGS sregs;int drivenum;getboot(buffer)char *buffer;{/* Read boot sector */ segread(&sregs); /* get ds */ if (devname[1] != ':') { printf("Invalid drive %s\n", devname); exit(1); } if (*devname >= 'a') *devname += 'A' - 'a'; drivenum = (*devname - 'C') & 0xff; if (drivenum < 0 || drivenum > 7) { printf("Funny drive number %d\n", drivenum); exit(1); } regs.x.ax = 0x201; /* read 1 sectors */ regs.h.ch = 0; /* cylinder */ regs.h.cl = 1; /* first sector = 1 */ regs.h.dh = 0; /* head = 0 */ regs.h.dl = 0x80 + drivenum; /* drive = 0 */ sregs.es = sregs.ds; /* buffer address */ regs.x.bx = (int) buffer; int86x(0x13, ®s, ®s, &sregs); if (regs.x.cflag) { printf("Cannot read boot sector\n"); exit(1); }}putboot(buffer)char *buffer;{/* Write boot sector */ regs.x.ax = 0x301; /* read 1 sectors */ regs.h.ch = 0; /* cylinder */ regs.h.cl = 1; /* first sector = 1 */ regs.h.dh = 0; /* head = 0 */ regs.h.dl = 0x80 + drivenum; /* drive = 0 */ sregs.es = sregs.ds; /* buffer address */ regs.x.bx = (int) buffer; int86x(0x13, ®s, ®s, &sregs); if (regs.x.cflag) { printf("Cannot write boot sector\n"); exit(1); }}#endifvoid adj_base(pe)struct part_entry *pe;{/* Adjust base sector of partition, usually to make it even. */ int adj; if (pe == NULL) return; while (1) { if (!get_an_int("\tEnter adjustment to base (an integer): ", &adj)) return; if (pe->lowsec + adj < 1) printf( "\t\tThat would make the base %d and too small\n", pe->lowsec + adj); else if (pe->size - adj < 1) printf( "\t\tThat would make the size %d and too small\n", pe->size - adj); else break; } pe->lowsec += adj; pe->size -= adj; sec_to_hst(pe->lowsec, &pe->start_head, &pe->start_sec, &pe->start_cyl); printf("Base of partition adjusted to %ld, size adjusted to %ld\n", pe->lowsec, pe->size);}void adj_size(pe)struct part_entry *pe;{/* Adjust size of partition by reducing high sector. */ int adj; if (pe == NULL) return; while (1) { if (!get_an_int("\tEnter adjustment to size (an integer): ", &adj)) return; if (pe->size + adj >= 1) break; printf("\t\tThat would make the size %d and too small \n", pe->size + adj); } pe->size += adj; sec_to_hst(pe->lowsec + pe->size - 1, &pe->last_head, &pe->last_sec, &pe->last_cyl); printf("Size of partition adjusted to %ld\n", pe->size);}struct part_entry *ask_partition(){/* Ask for a valid partition number and return its entry. */ int num; while (1) { if (!get_an_int("Enter partition number (1 to 4): ", &num)) return(NULL); if (num >= 1 && num <= NR_PARTITIONS) break; printf("\tThat does not look like 1 to 4\n"); } printf("Partition %d\n", num); return((struct part_entry *) &secbuf[PART_TABLE_OFF] + (num - 1));}void footnotes(){/* Explain the footnotes. */ if (badbases != 0) { printf("+ The old Minix wini drivers (before V1.5) discarded odd base sectors.\n"); printf(" This causes some old (Minix) file systems to be offset by 1 sector.\n"); printf(" To use these with the new drivers, increase the base by 1 using 'B'.\n"); } if (badsizes != 0) { if (badbases != 0) putchar('\n'); printf("- Minix cannot access the last sector on an odd-sized partition. This\n"); printf(" causes trouble for programs like dosread. This program will by default\n"); printf(" only create partitions with even sizes. If possible, the current odd\n"); printf(" sizes should be decreased by 1 using 'S'. This is safe for all Minix\n"); printf(" partitions, and may be safe for other partitions which are about to be\n"); printf(" reformatted.\n"); } if (badorders!= 0 ) { if (badbases != 0 || badsizes != 0) putchar('\n'); printf("# The partitions are in a funny order. This is normal if they were created\n"); printf(" by DOS fdisks prior to DOS 3.3. The Minix wini drivers further confuse\n"); printf(" the order by sorting the partitions on their base. Be careful if the\n"); printf(" device numbers of unchanged partitions have changed.\n"); }}int get_an_int(prompt, intptr)char *prompt;int *intptr;{/* Read an int from the start of line of stdin, discard rest of line. */ char buf[80]; while (1) { printf("%s", prompt); if (!mygets(buf, (int) sizeof buf)) return(0); if ((sscanf(buf, "%d", intptr)) == 1) return(1); printf("\t\tThat does not look like an integer\n"); }}void list_part_types(){/* Print all known partition types. */ int column; int type; for (column = 0, type = 0; type < 0x100; ++type) if (strcmp(systype(type), "Unknown") != 0) { printf("0x%02x: %-9s", type, systype(type)); column += 16; if (column < 80) putchar(' '); else { putchar('\n'); column = 0; } } if (column != 0) putchar('\n');}void mark_npartition(pe)struct part_entry *pe;{/* Mark a partition with arbitrary type. */ char buf[80]; unsigned type; if (pe == NULL) return; printf("\nKnown partition types are:\n\n"); list_part_types(); while (1) { printf("\nEnter partition type (in 2-digit hex): "); if (!mygets(buf, (int) sizeof buf)) return; if (sscanf(buf, "%x", &type) != 1) printf("Invalid hex number\n"); else if (type >= 0x100) printf("Hex number too large\n"); else break; } pe->sysind = type; printf("Partition type changed to 0x%02x (%s)\n", type, systype(type));}int mygets(buf, length)char *buf;int length; /* as for fgets(), but must be >= 2 */{/* Get a non-empty line of maximum length 'length'. */ while (1) { fflush(stdout); if (fgets(buf, length, stdin) == NULL) { putchar('\n'); return(0); } if (strrchr(buf, '\n') != NULL) *strrchr(buf, '\n') = 0; if (*buf != 0) return(1); printf("Use the EOF character to create a null line.\n"); printf("Otherwise, please type something before the newline: "); }}char *systype(type)int type;{/* Convert system indicator into system name. *//* asw 01.03.95: added types based on info in kjb's part.c and output * from Linux (1.0.8) fdisk. Note comments here, there are disagreements.*/ switch(type) { case NO_PART: return("None"); case 1: return("DOS-12"); case 2: return("XENIX"); case 3: return("XENIX usr"); case 4: return("DOS-16"); case 5: return("DOS-EXT"); case 6: return("DOS-BIG"); case 7: return("HPFS"); case 8: return("AIX"); case 9: return("COHERENT"); /* LINUX says AIX bootable */ case 0x0a: return("OS/2"); /* LINUX says OPUS */ case 0x10: return("OPUS"); case 0x40: return("VENIX286"); case 0x51: return("NOVELL?"); case 0x52: return("MICROPORT"); case 0x63: return("386/IX"); /*LINUX calls this GNU HURD */ case 0x64: return("NOVELL286"); case 0x65: return("NOVELL386"); case 0x75: return("PC/IX"); case OLD_MINIX_PART: return("MINIX old"); /* 0x80 */ case MINIX_PART: return("MINIX"); /* 0x81 */ case 0x82: return("LINUXswap"); case 0x83: return("LINUX"); case 0x93: return("AMOEBA"); case 0x94: return("AMOEBAbad"); case 0xa5: return("386BSD"); case 0xb7: return("BSDI"); case 0xb8: return("BSDIswap"); case 0xc7: return("Syrinx"); case 0xDB: return("CP/M"); case 0xe1: return("DOS acc"); case 0xe3: return("DOS r/o"); case 0xf2: return("DOS 2ary"); case 0xFF: return("Badblocks"); default: return("Unknown"); }}void toggle_active(pe)struct part_entry *pe;{/* Toggle active flag of a partition. */ if (pe == NULL) return; pe->bootind = (pe->bootind == ACTIVE_FLAG) ? 0 : ACTIVE_FLAG; printf("Partition changed to %sactive\n", pe->bootind ? "" : "in");}void usage(){/* Print usage message and exit. */ printf("Usage: fdisk [-hheads] [-ssectors] [device]\n"); exit(1);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -