📄 fdisk.c
字号:
hex = hex << 4 | hex_val(*line_ptr++); while (isxdigit(*line_ptr)); return hex; } }}/* * Print the message MESG, then read an integer in LOW..HIGH. * If the user hits Enter, DFLT is returned, provided that is in LOW..HIGH. * Answers like +10 are interpreted as offsets from BASE. * * There is no default if DFLT is not between LOW and HIGH. */unsigned intread_int(unsigned int low, unsigned int dflt, unsigned int high, unsigned int base, char *mesg){ unsigned int i; int default_ok = 1; static char *ms = NULL; static int mslen = 0; if (!ms || strlen(mesg)+100 > mslen) { mslen = strlen(mesg)+200; if (!(ms = realloc(ms,mslen))) fatal(out_of_memory); } if (dflt < low || dflt > high) default_ok = 0; if (default_ok) snprintf(ms, mslen, _("%s (%u-%u, default %u): "), mesg, low, high, dflt); else snprintf(ms, mslen, "%s (%u-%u): ", mesg, low, high); while (1) { int use_default = default_ok; /* ask question and read answer */ while (read_chars(ms) != '\n' && !isdigit(*line_ptr) && *line_ptr != '-' && *line_ptr != '+') continue; if (*line_ptr == '+' || *line_ptr == '-') { int minus = (*line_ptr == '-'); int absolute = 0; i = atoi(line_ptr+1); while (isdigit(*++line_ptr)) use_default = 0; switch (*line_ptr) { case 'c': case 'C': if (!display_in_cyl_units) i *= heads * sectors; break; case 'K': absolute = 1024; break; case 'k': absolute = 1000; break; case 'm': case 'M': absolute = 1000000; break; case 'g': case 'G': absolute = 1000000000; break; default: break; } if (absolute) { unsigned long long bytes; unsigned long unit; bytes = (unsigned long long) i * absolute; unit = sector_size * units_per_sector; bytes += unit/2; /* round */ bytes /= unit; i = bytes; } if (minus) i = -i; i += base; } else { i = atoi(line_ptr); while (isdigit(*line_ptr)) { line_ptr++; use_default = 0; } } if (use_default) printf(_("Using default value %u\n"), i = dflt); if (i >= low && i <= high) break; else printf(_("Value out of range.\n")); } return i;}intget_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) { if ((!sun_label && !sgi_label && !pe->part_table->sys_ind) || (sun_label && (!sunlabel->partitions[i].num_sectors || !sunlabel->infos[i].id)) || (sgi_label && (!sgi_get_num_sectors(i))) ) fprintf(stderr, _("Warning: partition %d has empty type\n"), i+1); } return i;}static intget_existing_partition(int warn, int max) { int pno = -1; int i; for (i = 0; i < max; i++) { struct pte *pe = &ptes[i]; struct partition *p = pe->part_table; if (p && !is_cleared_partition(p)) { if (pno >= 0) goto not_unique; pno = i; } } if (pno >= 0) { printf(_("Selected partition %d\n"), pno+1); return pno; } printf(_("No partition is defined yet!\n")); return -1; not_unique: return get_partition(warn, max);}static intget_nonexisting_partition(int warn, int max) { int pno = -1; int i; for (i = 0; i < max; i++) { struct pte *pe = &ptes[i]; struct partition *p = pe->part_table; if (p && is_cleared_partition(p)) { if (pno >= 0) goto not_unique; pno = i; } } if (pno >= 0) { printf(_("Selected partition %d\n"), pno+1); return pno; } printf(_("All primary partitions have been defined already!\n")); return -1; not_unique: return get_partition(warn, max);}char * conststr_units(int n) { /* n==1: use singular */ if (n == 1) return display_in_cyl_units ? _("cylinder") : _("sector"); else return display_in_cyl_units ? _("cylinders") : _("sectors");}void change_units(void){ display_in_cyl_units = !display_in_cyl_units; update_units(); printf(_("Changing display/entry units to %s\n"), str_units(PLURAL));}static voidtoggle_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); p->boot_ind = (p->boot_ind ? 0 : ACTIVE_FLAG); pe->changed = 1;}static voidtoggle_dos_compatibility_flag(void) { dos_compatible_flag = ~dos_compatible_flag; if (dos_compatible_flag) { sector_offset = sectors; printf(_("DOS Compatibility flag is set\n")); } else { sector_offset = 1; printf(_("DOS Compatibility flag is not set\n")); }}static voiddelete_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. */ if (warn_geometry()) return; /* C/H/S not set */ pe->changed = 1; if (sun_label) { sun_delete_partition(i); return; } if (sgi_label) { sgi_delete_partition(i); return; } if (i < 4) { if (IS_EXTENDED (p->sys_ind) && i == ext_index) { partitions = 4; ptes[ext_index].ext_pointer = NULL; extended_offset = 0; } clear_partition(p); return; } if (!q->sys_ind && i > 4) { /* the last one in the chain - just delete */ --partitions; --i; clear_partition(ptes[i].ext_pointer); ptes[i].changed = 1; } else { /* not the last one - further ones will be moved down */ if (i > 4) { /* delete this link in the chain */ p = ptes[i-1].ext_pointer; *p = *q; set_start_sect(p, get_start_sect(q)); set_nr_sects(p, get_nr_sects(q)); ptes[i-1].changed = 1; } else if (partitions > 5) { /* 5 will be moved to 4 */ /* the first logical in a longer chain */ 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--; while (i < partitions) { ptes[i] = ptes[i+1]; i++; } } else /* the only logical: clear only */ clear_partition(ptes[i].part_table); }}static voidchange_sysid(void) { char *temp; int i, sys, origsys; struct partition *p; /* If sgi_label then don't use get_existing_partition, let the user select a partition, since get_existing_partition() only works for Linux like partition tables. */ if (!sgi_label) { i = get_existing_partition(0, partitions); } else { i = get_partition(0, partitions); } if (i == -1) return; p = ptes[i].part_table; origsys = sys = get_sysid(i); /* if changing types T to 0 is allowed, then the reverse change must be allowed, too */ if (!sys && !sgi_label && !sun_label && !get_nr_sects(p)) printf(_("Partition %d does not exist yet!\n"), i + 1); else while (1) { sys = read_hex (get_sys_types()); if (!sys && !sgi_label && !sun_label) { printf(_("Type 0 means free space to many systems\n" "(but not to Linux). Having partitions of\n" "type 0 is probably unwise. You can delete\n" "a partition using the `d' command.\n")); /* break; */ } if (!sun_label && !sgi_label) { if (IS_EXTENDED (sys) != IS_EXTENDED (p->sys_ind)) { printf(_("You cannot change a partition into" " an extended one or vice versa\n" "Delete it first.\n")); break; } } if (sys < 256) { if (sun_label && i == 2 && sys != WHOLE_DISK) printf(_("Consider leaving partition 3 " "as Whole disk (5),\n" "as SunOS/Solaris expects it and " "even Linux likes it.\n\n")); if (sgi_label && ((i == 10 && sys != ENTIRE_DISK) || (i == 8 && sys != 0))) printf(_("Consider leaving partition 9 " "as volume header (0),\nand " "partition 11 as entire volume (6)" "as IRIX expects it.\n\n")); if (sys == origsys) break; if (sun_label) { sun_change_sysid(i, sys); } else if (sgi_label) { sgi_change_sysid(i, sys); } else p->sys_ind = sys; printf (_("Changed system type of partition %d " "to %x (%s)\n"), i + 1, sys, (temp = partition_type(sys)) ? temp : _("Unknown")); ptes[i].changed = 1; if (is_dos_partition(origsys) || is_dos_partition(sys)) dos_changed = 1; break; } }}/* check_consistency() and long2chs() added Sat Mar 6 12:28:16 1993, * faith@cs.unc.edu, based on code fragments from pfdisk by Gordon W. Ross, * Jan. 1990 (version 1.2.1 by Gordon W. Ross Aug. 1990; Modified by S. * Lubkin Oct. 1991). */static voidlong2chs(ulong ls, unsigned int *c, unsigned int *h, unsigned int *s) { int spc = heads * sectors; *c = ls / spc; ls = ls % spc; *h = ls / sectors; *s = ls % sectors + 1; /* sectors count from 1 */}static void check_consistency(struct partition *p, int partition) { unsigned int pbc, pbh, pbs; /* physical beginning c, h, s */ unsigned int pec, peh, pes; /* physical ending c, h, s */ unsigned int lbc, lbh, lbs; /* logical beginning c, h, s */ unsigned int lec, leh, les; /* logical ending c, h, s */ if (!heads || !sectors || (partition >= 4)) return; /* do not check extended partitions *//* physical beginning c, h, s */ pbc = (p->cyl & 0xff) | ((p->sector << 2) & 0x300); pbh = p->head; pbs = p->sector & 0x3f;/* physical ending c, h, s */ pec = (p->end_cyl & 0xff) | ((p->end_sector << 2) & 0x300); peh = p->end_head; pes = p->end_sector & 0x3f;/* compute logical beginning (c, h, s) */ long2chs(get_start_sect(p), &lbc, &lbh, &lbs);/* compute logical ending (c, h, s) */ long2chs(get_start_sect(p) + get_nr_sects(p) - 1, &lec, &leh, &les);/* Same physical / logical beginning? */ if (cylinders <= 1024 && (pbc != lbc || pbh != lbh || pbs != lbs)) { printf(_("Partition %d has different physical/logical " "beginnings (non-Linux?):\n"), partition + 1); printf(_(" phys=(%d, %d, %d) "), pbc, pbh, pbs); printf(_("logical=(%d, %d, %d)\n"),lbc, lbh, lbs); }/* Same physical / logical ending? */ if (cylinders <= 1024 && (pec != lec || peh != leh || pes != les)) { printf(_("Partition %d has different physical/logical " "endings:\n"), partition + 1); printf(_(" phys=(%d, %d, %d) "), pec, peh, pes); printf(_("logical=(%d, %d, %d)\n"),lec, leh, les); }#if 0/* Beginning on cylinder boundary? */ if (pbh != !pbc || pbs != 1) { printf(_("Partition %i does not start on cylinder " "boundary:\n"), partition + 1); printf(_(" phys=(%d, %d, %d) "), pbc, pbh, pbs); printf(_("should be (%d, %d, 1)\n"), pbc, !pbc); }#endif/* Ending on cylinder boundary? */ if (peh != (heads - 1) || pes != sectors) { printf(_("Partition %i does not end on cylinder boundary.\n"), partition + 1);#if 0 printf(_(" phys=(%d, %d, %d) "), pec, peh, pes); printf(_("should be (%d, %d, %d)\n"), pec, heads - 1, sectors);#endif }}static voidlist_disk_geometry(void) { long long bytes = (total_number_of_sectors << 9); long megabytes = bytes/1000000; if (megabytes < 10000) printf(_("\nDisk %s: %ld MB, %lld bytes\n"), disk_device, megabytes, bytes); else printf(_("\nDisk %s: %ld.%ld GB, %lld bytes\n"), disk_device, megabytes/1000, (megabytes/100)%10, bytes); printf(_("%d heads, %d sectors/track, %d cylinders"), heads, sectors, cylinders); if (units_per_sector == 1) printf(_(", total %llu sectors"), total_number_of_sectors / (sector_size/512)); printf("\n"); printf(_("Units = %s of %d * %d = %d bytes\n\n"), str_units(PLURAL), units_per_sector, sector_size, units_per_sector * sector_size);}/* * 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 intwrong_p_order(int *prev) { struct pte *pe; struct partition *p; unsigned int 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;}/* * Fix the chain of logicals. * extended_offset is unchanged, the set of sectors used is unchanged * The chain is sorted so that sectors increase, and so that * starting sectors increase. * * After this it may still be that cfdisk doesnt like the table. * (This is because cfdisk considers expanded parts, from link to * end of partition, and these may still overlap.) * Now * sfdisk /dev/hda > ohda; sfdisk /dev/hda < ohda * may help. */static voidfix_chain_of_logicals(void) { int j, oj, ojj, sj, sjj; struct partition *pj,*pjj,tmp; /* Stage 1: sort sectors but leave sector of part 4 */ /* (Its sector is the global extended_offset.) */ stage1: for (j = 5; j < partitions-1; j++) { oj = ptes[j].offset;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -