📄 sfdisk.c
字号:
pp = outer_extended_partition(ep); } fu = pp ? (pp->start + pp->size) / unit : get_disksize(format); for(pp = partitions; pp < partitions+pno; pp++) if (!is_parent(pp, ep) && pp->size > 0 && pp->start / unit >= start && pp->start / unit < fu) fu = pp->start / unit; return (fu > start) ? fu - start : 0;}/* compute starting sector of a partition inside an extended one *//* return 0 on failure *//* ep is 0 or points to surrounding extended partition */static intcompute_start_sect(struct part_desc *p, struct part_desc *ep) { unsigned long base; int inc = (DOS && B.sectors) ? B.sectors : 1; int delta; if (ep && p->start + p->size >= ep->start + 1) delta = p->start - ep->start - inc; else if (p->start == 0 && p->size > 0) delta = -inc; else delta = 0; if (delta < 0) { p->start -= delta; p->size += delta; if (is_extended(p->p.sys_type) && boxes == ONESECTOR) p->size = inc; else if ((int)(p->size) <= 0) { warn(_("no room for partition descriptor\n")); return 0; } } base = (!ep ? 0 : (is_extended(p->p.sys_type) ? outer_extended_partition(ep) : ep)->start); p->ep = ep; if (p->p.sys_type == EMPTY_PARTITION && p->size == 0) { p->p.start_sect = 0; p->p.begin_chs = zero_chs; p->p.end_chs = zero_chs; } else { p->p.start_sect = p->start - base; p->p.begin_chs = ulong_to_chs(p->start,B); p->p.end_chs = ulong_to_chs(p->start + p->size - 1,B); } p->p.nr_sects = p->size; return 1;} /* build the extended partition surrounding a given logical partition */static intbuild_surrounding_extended(struct part_desc *p, struct part_desc *ep, struct disk_desc *z) { int inc = (DOS && B.sectors) ? B.sectors : 1; int format = F_SECTOR; struct part_desc *p0 = &(z->partitions[0]), *eep = ep->ep; if (boxes == NESTED) { ep->start = first_free(ep-p0, 1, eep, format, p->start, z); ep->size = max_length(ep-p0, 1, eep, format, ep->start, z); if (ep->start > p->start || ep->start + ep->size < p->start + p->size) { warn(_("cannot build surrounding extended partition\n")); return 0; } } else { ep->start = p->start; if (boxes == CHAINED) ep->size = p->size; else ep->size = inc; } ep->p.nr_sects = ep->size; ep->p.bootable = 0; ep->p.sys_type = EXTENDED_PARTITION; if (!compute_start_sect(ep, eep) || !compute_start_sect(p, ep)) { ep->p.sys_type = EMPTY_PARTITION; ep->size = 0; return 0; } return 1;}static intread_line(int pno, struct part_desc *ep, char *dev, int interactive, struct disk_desc *z) { unsigned char line[1000]; unsigned char *fields[11]; int fno, pct = pno%4; struct part_desc p, *orig; unsigned long ff, ff1, ul, ml, ml1, def; int format, lpno, is_extd; if (eof || eob) return -1; lpno = index_to_linux(pno, z); if (interactive) { if (pct == 0 && (show_extended || pno == 0)) warn("\n"); warn("%s:", partname(dev, lpno, 10)); } /* read input line - skip blank lines when reading from a file */ do { fno = read_stdin(fields, line, SIZE(fields), SIZE(line)); } while(fno == RD_CMD || (fno == 0 && !interactive)); if (fno == RD_EOF) { return -1; } else if (fno > 10 && *(fields[10]) != 0) { do_warn(_("too many input fields\n")); return 0; } if (fno == 1 && !strcmp(fields[0], ".")) { eob = 1; return -1; } /* use specified format, but round to cylinders if F_MEGABYTE specified */ format = 0; if (B.cylindersize && specified_format == F_MEGABYTE) format = F_CYLINDER; orig = (one_only ? &(oldp.partitions[pno]) : 0); p = zero_part_desc; p.ep = ep; /* first read the type - we need to know whether it is extended */ /* stop reading when input blank (defaults) and all is full */ is_extd = 0; if (fno == 0) { /* empty line */ if (orig && is_extended(orig->p.sys_type)) is_extd = 1; ff = first_free(pno, is_extd, ep, format, 0, z); ml = max_length(pno, is_extd, ep, format, ff, z); if (ml == 0 && is_extd == 0) { is_extd = 1; ff = first_free(pno, is_extd, ep, format, 0, z); ml = max_length(pno, is_extd, ep, format, ff, z); } if (ml == 0 && pno >= 4) { /* no free blocks left - don't read any further */ warn(_("No room for more\n")); return -1; } } if (fno < 3 || !*(fields[2])) ul = orig ? orig->p.sys_type : (is_extd || (pno > 3 && pct == 1 && show_extended)) ? EXTENDED_PARTITION : LINUX_NATIVE; else if (!strcmp(fields[2], "L")) ul = LINUX_NATIVE; else if (!strcmp(fields[2], "S")) ul = LINUX_SWAP; else if (!strcmp(fields[2], "E")) ul = EXTENDED_PARTITION; else if (!strcmp(fields[2], "X")) ul = LINUX_EXTENDED; else if (get_ul(fields[2], &ul, LINUX_NATIVE, 16)) return 0; if (ul > 255) { warn(_("Illegal type\n")); return 0; } p.p.sys_type = ul; is_extd = is_extended(ul); /* find start */ ff = first_free(pno, is_extd, ep, format, 0, z); ff1 = ff * unitsize(format); def = orig ? orig->start : (pno > 4 && pct > 1) ? 0 : ff1; if (fno < 1 || !*(fields[0])) p.start = def; else { if (get_ul(fields[0], &ul, def / unitsize(0), 0)) return 0; p.start = ul * unitsize(0); p.start -= (p.start % unitsize(format)); } /* find length */ ml = max_length(pno, is_extd, ep, format, p.start / unitsize(format), z); ml1 = ml * unitsize(format); def = orig ? orig->size : (pno > 4 && pct > 1) ? 0 : ml1; if (fno < 2 || !*(fields[1])) p.size = def; else { if (get_ul(fields[1], &ul, def / unitsize(0), 0)) return 0; p.size = ul * unitsize(0) + unitsize(format) - 1; p.size -= (p.size % unitsize(format)); } if (p.size > ml1) { 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; } if (p.size == 0 && pno >= 4 && (fno < 2 || !*(fields[1]))) { warn(_("Warning: empty partition\n")); if (!force) return 0; } p.p.nr_sects = p.size; if (p.size == 0 && !orig) { if (fno < 1 || !*(fields[0])) p.start = 0; if (fno < 3 || !*(fields[2])) p.p.sys_type = EMPTY_PARTITION; } if (p.start < ff1 && p.size > 0) { warn(_("Warning: bad partition start (earliest %lu)\n"), (ff1 + unitsize(0) - 1) / unitsize(0)); if (!force) return 0; } if (fno < 4 || !*(fields[3])) ul = (orig ? orig->p.bootable : 0); else if (!strcmp(fields[3], "-")) ul = 0; else if (!strcmp(fields[3], "*") || !strcmp(fields[3], "+")) ul = 0x80; else { warn(_("unrecognized bootable flag - choose - or *\n")); return 0; } p.p.bootable = ul; if (ep && ep->p.sys_type == EMPTY_PARTITION) { if (!build_surrounding_extended(&p, ep, z)) return 0; } else if (!compute_start_sect(&p, ep)) return 0; { longchs aa = chs_to_longchs(p.p.begin_chs), bb; if (fno < 5) { bb = aa; } else if (fno < 7) { warn(_("partial c,h,s specification?\n")); return 0; } else if (get_ul(fields[4], &bb.c, aa.c, 0) || get_ul(fields[5], &bb.h, aa.h, 0) || get_ul(fields[6], &bb.s, aa.s, 0)) return 0; p.p.begin_chs = longchs_to_chs(bb,B); } { longchs aa = chs_to_longchs(p.p.end_chs), bb; if (fno < 8) { bb = aa; } else if (fno < 10) { warn(_("partial c,h,s specification?\n")); return 0; } else if (get_ul(fields[7], &bb.c, aa.c, 0) || get_ul(fields[8], &bb.h, aa.h, 0) || get_ul(fields[9], &bb.s, aa.s, 0)) return 0; p.p.end_chs = longchs_to_chs(bb, B); } if (pno > 3 && p.size && show_extended && p.p.sys_type != EMPTY_PARTITION && (is_extended(p.p.sys_type) != (pct == 1))) { warn(_("Extended partition not where expected\n")); if (!force) return 0; } z->partitions[pno] = p; if (pno >= z->partno) z->partno += 4; /* reqd for out_partition() */ if (interactive) out_partition(dev, 0, &(z->partitions[pno]), z, B); return 1;}/* ep either points to the extended partition to contain this one, or to the empty partition that may become extended or is 0 */static intread_partition(char *dev, int interactive, int pno, struct part_desc *ep, struct disk_desc *z) { struct part_desc *p = &(z->partitions[pno]); int i; if (one_only) { *p = oldp.partitions[pno]; if (one_only_pno != pno) goto ret; } else if (!show_extended && pno > 4 && pno%4) goto ret; while (!(i = read_line(pno, ep, dev, interactive, z))) if (!interactive) fatal(_("bad input\n")); if (i < 0) { p->ep = ep; return 0; } ret: p->ep = ep; if (pno >= z->partno) z->partno += 4; return 1;}static voidread_partition_chain(char *dev, int interactive, struct part_desc *ep, struct disk_desc *z) { int i, base; eob = 0; while (1) { base = z->partno; if (base+4 > SIZE(z->partitions)) { do_warn(_("too many partitions\n")); break; } for (i=0; i<4; i++) if (!read_partition(dev, interactive, base+i, ep, z)) return; for (i=0; i<4; i++) { ep = &(z->partitions[base+i]); if (is_extended(ep->p.sys_type) && ep->size) break; } if (i == 4) { /* nothing found - maybe an empty partition is going to be extended */ if (one_only || show_extended) break; ep = &(z->partitions[base+1]); if (ep->size || ep->p.sys_type != EMPTY_PARTITION) break; } }}static voidread_input(char *dev, int interactive, struct disk_desc *z) { int i; struct part_desc *partitions = &(z->partitions[0]), *ep; for (i=0; i < SIZE(z->partitions); i++) partitions[i] = zero_part_desc; z->partno = 0; if (interactive) warn(_("Input in the following format; absent fields get a default value.\n" "<start> <size> <type [E,S,L,X,hex]> <bootable [-,*]> <c,h,s> <c,h,s>\n" "Usually you only need to specify <start> and <size> (and perhaps <type>).\n")); eof = 0; for (i=0; i<4; i++) read_partition(dev, interactive, i, 0, z); for (i=0; i<4; i++) { ep = partitions+i; if (is_extended(ep->p.sys_type) && ep->size) read_partition_chain(dev, interactive, ep, z); } add_sector_and_offset(z);}/* * G. The command line */static void version(void) { printf("%s %s %s (aeb@cwi.nl, %s)\n", PROGNAME, _("version"), VERSION, DATE);}static voidusage(void) { version(); printf(_("Usage: %s [options] device ...\n"), PROGNAME); puts (_("device: something like /dev/hda or /dev/sda")); puts (_("useful options:")); puts (_(" -s [or --show-size]: list size of a partition")); puts (_(" -c [or --id]: print or change partition Id")); puts (_(" -l [or --list]: list partitions of each device")); puts (_(" -d [or --dump]: idem, but in a format suitable for later input")); puts (_(" -i [or --increment]: number cylinders etc. from 1 instead of from 0")); puts (_(" -uS, -uB, -uC, -uM: accept/report in units of sectors/blocks/cylinders/MB")); puts (_(" -T [or --list-types]:list the known partition types")); puts (_(" -D [or --DOS]: for DOS-compatibility: waste a little space")); puts (_(" -R [or --re-read]: make kernel reread partition table")); puts (_(" -N# : change only the partition with number #")); puts (_(" -n : do not actually write to disk")); puts (_(" -O file : save the sectors that will be overwritten to file")); puts (_(" -I file : restore these sectors again")); puts (_(" -v [or --version]: print version")); puts (_(" -? [or --help]: print this message")); puts (_("dangerous options:")); puts (_(" -g [or --show-geometry]: print the kernel's idea of the geometry")); puts (_(" -x [or --show-extended]: also list extended partitions on output\n" " or expect descriptors for them on input")); puts (_(" -L [or --Linux]: do not complain about things irrelevant for Linux")); puts (_(" -q [or --quiet]: suppress warning messages")); puts (_(" You can override the detected geometry using:")); puts (_(" -C# [or --cylinders #]:set the number of cylinders to use")); puts (_(" -H# [or --heads #]: set the number of heads to use")); puts (_(" -S# [or --sectors #]: set the number of sectors to use")); puts (_("You can disable all consistency checking with:")); puts (_(" -f [or --force]: do what I say, even if it is stupid")); exit(1);}static voidactivate_usage(char *progn) { puts (_("Usage:")); printf(_("%s device list active partitions on device\n"), progn); printf(_("%s device n1 n2 ... activate partitions n1 ..., inactivate the rest\n"), progn); printf(_("%s -An device activate partition n, inactivate the other ones\n"), PROGNAME); exit(1);}static voidunhide_usage(char *progn) { exit(1);}static char short_opts[] = "cdfgilnqsu:vx?1A::C:DH:I:LN:O:RS:TU::V";#define PRINT_ID 0400#define CHANGE_ID 01000static const struct option long_opts[] = { { "change-id", no_argument, NULL, 'c' + CHANGE_ID }, { "print-id", no_argument, NULL, 'c' + PRINT_ID }, { "id", no_argument, NULL, 'c' }, { "dump", no_argument, NULL, 'd' }, { "force", no_argument, NULL, 'f' }, { "show-geometry", no_argument, NULL, 'g' }, { "increment", no_argument, NULL, 'i' }, { "list", no_argument, NULL, 'l' }, { "quiet", no_argument, NULL, 'q' }, { "show-size", no_argument, NULL, 's' }, { "unit", required_argument, NULL, 'u' }, { "version", no_argument, NULL, 'v' }, { "show-extended", no_argument, NULL, 'x' }, { "help", no_argument, NULL, '?' }, { "one-only", no_argument, NULL, '1' }, { "cylinders", required_argument, NULL, 'C' }, { "heads", required_argument, NULL, 'H' }, { "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' }, { "unhide", optional_argument, NULL, 'U' }, { "no-reread", no_argument, NULL, 160 }, { "IBM", no_argument, NULL, 161 }, { "leave-last", no_argument, NULL, 161 },/* undocumented flags - not all completely implemented */ { "in-order", no_argument, NULL, 128 }, { "not-in-order", no_argument, NULL, 129 }, { "inside-outer", no_argument, NULL, 130 }, { "not-inside-outer", no_argument, NULL, 131 }, { "nested", no_argument, NULL, 132 }, { "chaine
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -