📄 sfdisk.c
字号:
printf(_(" Device Boot Start End MiB #blocks Id System\n")); break; }}static voidout_rounddown(int width, unsigned long n, unsigned long unit, int inc) { printf("%*lu", width, inc + n/unit); if (unit != 1) putchar((n % unit) ? '+' : ' '); putchar(' ');}static voidout_roundup(int width, unsigned long n, unsigned long unit, int inc) { if (n == (unsigned long)(-1)) printf("%*s", width, "-"); else printf("%*lu", width, inc + n/unit); if (unit != 1) putchar(((n+1) % unit) ? '-' : ' '); putchar(' ');}static voidout_roundup_size(int width, unsigned long n, unsigned long unit) { printf("%*lu", width, (n+unit-1)/unit); if (unit != 1) putchar((n % unit) ? '-' : ' '); putchar(' ');}static struct geometryget_fdisk_geometry_one(struct part_desc *p) { struct geometry G; chs b = p->p.end_chs; longchs bb = chs_to_longchs(b); G.heads = bb.h+1; G.sectors = bb.s; G.cylindersize = G.heads*G.sectors; G.cylinders = G.start = 0; return G;}static intget_fdisk_geometry(struct disk_desc *z) { struct part_desc *p; int pno, agree; struct geometry G0, G; agree = 0; G0.heads = G0.sectors = 0; for (pno=0; pno < z->partno; pno++) { p = &(z->partitions[pno]); if (p->size != 0 && p->p.sys_type != 0) { G = get_fdisk_geometry_one(p); if (!G0.heads) { G0 = G; agree = 1; } else if (G.heads != G0.heads || G.sectors != G0.sectors) { agree = 0; break; } } } F = (agree ? G0 : B); return (F.sectors != B.sectors || F.heads != B.heads);}static voidout_partition(char *dev, int format, struct part_desc *p, struct disk_desc *z, struct geometry G) { unsigned long start, end, size; int pno, lpno; if (!format && !(format = specified_format)) format = default_format; pno = p - &(z->partitions[0]); /* our index */ lpno = index_to_linux(pno, z); /* name of next one that has a name */ if (pno == linux_to_index(lpno, z)) /* was that us? */ printf("%s", partname(dev, lpno, 10)); /* yes */ else if (show_extended) printf(" - "); else return; putchar(dump ? ':' : ' '); start = p->start; end = p->start + p->size - 1; size = p->size; if (dump) { printf(" start=%9lu", start); printf(", size=%9lu", size); if (p->ptype == DOS_TYPE) { printf(", Id=%2x", p->p.sys_type); if (p->p.bootable == 0x80) printf(", bootable"); } printf("\n"); return; } if (p->ptype != DOS_TYPE || p->p.bootable == 0) printf(" "); else if (p->p.bootable == 0x80) printf(" * "); else printf(" ? "); /* garbage */ switch(format) { case F_CYLINDER: if (G.cylindersize) { out_rounddown(6, start, G.cylindersize, increment); out_roundup(6, end, G.cylindersize, increment); out_roundup_size(6, size, G.cylindersize); out_rounddown(9, size, 2, 0); break; } /* fall through */ default: case F_SECTOR: out_rounddown(9, start, 1, increment); out_roundup(9, end, 1, increment); out_rounddown(10, size, 1, 0); break; case F_BLOCK:#if 0 printf("%8lu,%3lu ", p->sector/2, ((p->sector & 1) ? 512 : 0) + p->offset);#endif out_rounddown(8, start, 2, increment); out_roundup(8, end, 2, increment); out_rounddown(9, size, 2, 0); break; case F_MEGABYTE: out_rounddown(5, start, 2048, increment); out_roundup(5, end, 2048, increment); out_roundup_size(5, size, 2048); out_rounddown(9, size, 2, 0); break; } if (p->ptype == DOS_TYPE) { printf(" %2x %s\n", p->p.sys_type, sysname(p->p.sys_type)); } else { printf("\n"); } /* Is chs as we expect? */ if (!quiet && p->ptype == DOS_TYPE) { chs a, b; longchs aa, bb; a = (size ? ulong_to_chs(start,G) : zero_chs); b = p->p.begin_chs; aa = chs_to_longchs(a); bb = chs_to_longchs(b); if (a.s && !is_equal_chs(a, b)) do_warn(_("\t\tstart: (c,h,s) expected (%ld,%ld,%ld) found (%ld,%ld,%ld)\n"), aa.c, aa.h, aa.s, bb.c, bb.h, bb.s); a = (size ? ulong_to_chs(end,G) : zero_chs); b = p->p.end_chs; aa = chs_to_longchs(a); bb = chs_to_longchs(b); if (a.s && !is_equal_chs(a, b)) do_warn(_("\t\tend: (c,h,s) expected (%ld,%ld,%ld) found (%ld,%ld,%ld)\n"), aa.c, aa.h, aa.s, bb.c, bb.h, bb.s); if (G.cylinders && G.cylinders < 1024 && bb.c > G.cylinders) do_warn(_("partition ends on cylinder %ld, beyond the end of the disk\n"), bb.c); }}static voidout_partitions(char *dev, struct disk_desc *z) { int pno, format = 0; if (z->partno == 0) do_warn(_("No partitions found\n")); else { if (get_fdisk_geometry(z) && !dump) { do_warn( _("Warning: The partition table looks like it was made\n" " for C/H/S=*/%ld/%ld (instead of %ld/%ld/%ld).\n" "For this listing I'll assume that geometry.\n"), F.heads, F.sectors, B.cylinders, B.heads, B.sectors); } out_partition_header(dev, format, F); for(pno=0; pno < z->partno; pno++) { out_partition(dev, format, &(z->partitions[pno]), z, F); if (show_extended && pno%4==3) printf("\n"); } }}static intdisj(struct part_desc *p, struct part_desc *q) { return ((p->start + p->size <= q->start) || (is_extended(p->p.sys_type) && q->start + q->size <= p->start + p->size));}static char *pnumber(struct part_desc *p, struct disk_desc *z) { static char buf[20]; int this, next; struct part_desc *p0 = &(z->partitions[0]); this = index_to_linux(p-p0, z); next = index_to_linux(p-p0+1, z); if (next > this) sprintf(buf, "%d", this); else sprintf(buf, "[%d]", this); return buf;}static intpartitions_ok(struct disk_desc *z) { struct part_desc *partitions = &(z->partitions[0]), *p, *q; int partno = z->partno;#define PNO(p) pnumber(p, z) /* Have at least 4 partitions been defined? */ if (partno < 4) { if (!partno) fatal(_("no partition table present.\n")); else fatal(_("strange, only %d partitions defined.\n"), partno); return 0; } /* Are the partitions of size 0 marked empty? And do they have start = 0? And bootable = 0? */ for (p = partitions; p - partitions < partno; p++) if (p->size == 0) { if (p->p.sys_type != EMPTY_PARTITION) warn(_("Warning: partition %s has size 0 but is not marked Empty\n"), PNO(p)); else if (p->p.bootable != 0) warn(_("Warning: partition %s has size 0 and is bootable\n"), PNO(p)); else if (p->p.start_sect != 0) warn(_("Warning: partition %s has size 0 and nonzero start\n"), PNO(p)); /* all this is probably harmless, no error return */ } /* Are the logical partitions contained in their extended partitions? */ for (p = partitions+4; p < partitions+partno; p++) if (p->ptype == DOS_TYPE) if (p->size && !is_extended(p->p.sys_type)) { q = p->ep; if (p->start < q->start || p->start + p->size > q->start + q->size) { warn(_("Warning: partition %s "), PNO(p)); warn(_("is not contained in partition %s\n"), PNO(q)); return 0; } } /* Are the data partitions mutually disjoint? */ for (p = partitions; p < partitions+partno; p++) if (p->size && !is_extended(p->p.sys_type)) for (q = p+1; q < partitions+partno; q++) if (q->size && !is_extended(q->p.sys_type)) if (!((p->start > q-> start) ? disj(q,p) : disj(p,q))) { warn(_("Warning: partitions %s "), PNO(p)); warn(_("and %s overlap\n"), PNO(q)); return 0; } /* Are the data partitions and the extended partition table sectors disjoint? */ for (p = partitions; p < partitions+partno; p++) if (p->size && !is_extended(p->p.sys_type)) for (q = partitions; q < partitions+partno; q++) if (is_extended(q->p.sys_type)) if (p->start <= q->start && p->start + p->size > q->start) { warn(_("Warning: partition %s contains part of " "the partition table (sector %lu),\n" "and will destroy it when filled\n"), PNO(p), q->start); return 0; } /* Do they start past zero and end before end-of-disk? */ { unsigned long ds = get_disksize(F_SECTOR); for (p = partitions; p < partitions+partno; p++) if (p->size) { if (p->start == 0) { warn(_("Warning: partition %s starts at sector 0\n"), PNO(p)); return 0; } if (p->size && p->start + p->size > ds) { warn(_("Warning: partition %s extends past end of disk\n"), PNO(p)); return 0; } } } /* At most one chain of DOS extended partitions ? */ /* It seems that the OS/2 fdisk has the additional requirement that the extended partition must be the fourth one */ { int ect = 0; for (p = partitions; p < partitions+4; p++) if (p->p.sys_type == EXTENDED_PARTITION) ect++; if (ect > 1 && !Linux) { warn(_("Among the primary partitions, at most one can be extended\n" " (although this is not a problem under Linux)\n")); return 0; } } /* * Do all partitions start at a cylinder boundary ? * (this is not required for Linux) * The first partition starts after MBR. * Logical partitions start slightly after the containing extended partn. */ if (B.cylindersize) { for(p = partitions; p < partitions+partno; p++) if (p->size) { if (p->start % B.cylindersize != 0 && (!p->ep || p->start / B.cylindersize != p->ep->start / B.cylindersize) && (p->p.start_sect >= B.cylindersize)) { warn(_("Warning: partition %s does not start " "at a cylinder boundary\n"), PNO(p)); if (!Linux) return 0; } if ((p->start + p->size) % B.cylindersize) { warn(_("Warning: partition %s does not end " "at a cylinder boundary\n"), PNO(p)); if (!Linux) return 0; } } } /* Usually, one can boot only from primary partitions. */ /* In fact, from a unique one only. */ /* do not warn about bootable extended partitions - often LILO is there */ { int pno = -1; for(p = partitions; p < partitions+partno; p++) if (p->p.bootable) { if (pno == -1) pno = p - partitions; else if (p - partitions < 4) { warn(_("Warning: more than one primary partition is marked " "bootable (active)\n" "This does not matter for LILO, but the DOS MBR will " "not boot this disk.\n")); break; } if (p - partitions >= 4) { warn(_("Warning: usually one can boot from primary partitions " "only\nLILO disregards the `bootable' flag.\n")); break; } } if (pno == -1 || pno >= 4) warn(_("Warning: no primary partition is marked bootable (active)\n" "This does not matter for LILO, but the DOS MBR will " "not boot this disk.\n")); } /* Is chs as we expect? */ for(p = partitions; p < partitions+partno; p++) if (p->ptype == DOS_TYPE) { chs a, b; longchs aa, bb; a = p->size ? ulong_to_chs(p->start,B) : zero_chs; b = p->p.begin_chs; aa = chs_to_longchs(a); bb = chs_to_longchs(b); if (!chs_ok(b, PNO(p), _("start"))) return 0; if (a.s && !is_equal_chs(a, b)) warn(_("partition %s: start: (c,h,s) expected (%ld,%ld,%ld) found (%ld,%ld,%ld)\n"), PNO(p), aa.c, aa.h, aa.s, bb.c, bb.h, bb.s); a = p->size ? ulong_to_chs(p->start + p->size - 1, B) : zero_chs; b = p->p.end_chs; aa = chs_to_longchs(a); bb = chs_to_longchs(b); if (!chs_ok(b, PNO(p), _("end"))) return 0; if (a.s && !is_equal_chs(a, b)) warn(_("partition %s: end: (c,h,s) expected (%ld,%ld,%ld) found (%ld,%ld,%ld)\n"), PNO(p), aa.c, aa.h, aa.s, bb.c, bb.h, bb.s); if (B.cylinders && B.cylinders < 1024 && bb.c > B.cylinders) warn(_("partition %s ends on cylinder %ld, beyond the end of the disk\n"), PNO(p), bb.c); } return 1;#undef PNO}static voidextended_partition(char *dev, int fd, struct part_desc *ep, struct disk_desc *z) { char *cp; struct sector *s; unsigned long start, here, next; int i, moretodo = 1; struct partition p; struct part_desc *partitions = &(z->partitions[0]); int pno = z->partno; here = start = ep->start; if (B.cylindersize && start % B.cylindersize) { /* This is BAD */ if (DOS_extended) { here = start -= (start % B.cylindersize); do_warn(_("Warning: shifted start of the extd partition " "from %ld to %ld\n" "(For listing purposes only. " "Do not change its contents.)\n"), ep->start, start); } else { do_warn(_("Warning: extended partition does not start at a " "cylinder boundary.\n" "DOS and Linux will interpret the contents differently.\n")); } } while (moretodo) { moretodo = 0; if (!(s = get_sector(dev, fd, here))) break; if (!msdos_signature(s)) break; cp = s->data + 0x1be; if (pno+4 >= SIZE(z->partitions)) { do_warn(_("too many partitions - ignoring those past nr (%d)\n"), pno-1); break; } next = 0; for (i=0; i<4; i++,cp += sizeof(struct partition)) { partitions[pno].sector = here; partitions[pno].offset = cp - s->data; partitions[pno].ep = ep; copy_to_part(cp,&p); if (is_extended(p.sys_type)) { partitions[pno].start = start + p.start_sect; if (next) do_warn(_("tree of partitions?\n")); else next = partitions[pno].start; /* follow `upper' branch */ moretodo = 1; } else { partitions[pno].start = here + p.start_sect; } partitions[pno].size = p.nr_sects; partitions[pno].ptype = DOS_TYPE; partitions[pno].p = p; pno++; } here = next; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -