📄 sfdisk.c
字号:
} return R;}static voidget_cylindersize(char *dev, int fd, int silent) { struct geometry R; R = get_geometry(dev, fd, silent); B.heads = (U.heads ? U.heads : R.heads); B.sectors = (U.sectors ? U.sectors : R.sectors); B.cylinders = (U.cylinders ? U.cylinders : R.cylinders); B.cylindersize = B.heads * B.sectors; B.total_size = R.total_size; if (B.cylinders == 0 && B.cylindersize != 0) B.cylinders = B.total_size / B.cylindersize; if (R.start && !force) { warn( _("Warning: start=%lu - this looks like a partition rather than\n" "the entire disk. Using fdisk on it is probably meaningless.\n" "[Use the --force option if you really want this]\n"), R.start); exit(1); } if (R.heads && B.heads != R.heads) warn(_("Warning: HDIO_GETGEO says that there are %lu heads\n"), R.heads); if (R.sectors && B.sectors != R.sectors) warn(_("Warning: HDIO_GETGEO says that there are %lu sectors\n"), R.sectors); if (R.cylinders && B.cylinders != R.cylinders && B.cylinders < 65536 && R.cylinders < 65536) warn(_("Warning: BLKGETSIZE/HDIO_GETGEO says that there are %lu cylinders\n"), R.cylinders); if (B.sectors > 63) warn(_("Warning: unlikely number of sectors (%lu) - usually at most 63\n" "This will give problems with all software that uses C/H/S addressing.\n"), B.sectors); if (!silent) printf(_("\nDisk %s: %lu cylinders, %lu heads, %lu sectors/track\n"), dev, B.cylinders, B.heads, B.sectors);}typedef struct { unsigned char h,s,c; } PACKED chs; /* has some c bits in s */chs zero_chs = { 0,0,0 };typedef struct { unsigned long h,s,c; } longchs;longchs zero_longchs;static chslongchs_to_chs (longchs aa, struct geometry G) { chs a; if (aa.h < 256 && aa.s < 64 && aa.c < 1024) { a.h = aa.h; a.s = aa.s | ((aa.c >> 2) & 0xc0); a.c = (aa.c & 0xff); } else if (G.heads && G.sectors) { a.h = G.heads - 1; a.s = G.sectors | 0xc0; a.c = 0xff; } else a = zero_chs; return a;}static longchschs_to_longchs (chs a) { longchs aa; aa.h = a.h; aa.s = (a.s & 0x3f); aa.c = (a.s & 0xc0); aa.c = (aa.c << 2) + a.c; return aa;}static longchsulong_to_longchs (unsigned long sno, struct geometry G) { longchs aa; if (G.heads && G.sectors && G.cylindersize) { aa.s = 1 + sno % G.sectors; aa.h = (sno / G.sectors) % G.heads; aa.c = sno / G.cylindersize; return aa; } else { return zero_longchs; }}static chsulong_to_chs (unsigned long sno, struct geometry G) { return longchs_to_chs(ulong_to_longchs(sno, G), G);}#if 0static unsigned longlongchs_to_ulong (longchs aa, struct geometry G) { return (aa.c*G.cylindersize + aa.h*G.sectors + aa.s - 1);}static unsigned longchs_to_ulong (chs a, struct geometry G) { return longchs_to_ulong(chs_to_longchs(a), G);}#endifstatic intis_equal_chs (chs a, chs b) { return (a.h == b.h && a.s == b.s && a.c == b.c);}static intchs_ok (chs a, char *v, char *w) { longchs aa = chs_to_longchs(a); int ret = 1; if (is_equal_chs(a, zero_chs)) return 1; if (B.heads && aa.h >= B.heads) { warn(_("%s of partition %s has impossible value for head: " "%lu (should be in 0-%lu)\n"), w, v, aa.h, B.heads-1); ret = 0; } if (B.sectors && (aa.s == 0 || aa.s > B.sectors)) { warn(_("%s of partition %s has impossible value for sector: " "%lu (should be in 1-%lu)\n"), w, v, aa.s, B.sectors); ret = 0; } if (B.cylinders && aa.c >= B.cylinders) { warn(_("%s of partition %s has impossible value for cylinders: " "%lu (should be in 0-%lu)\n"), w, v, aa.c, B.cylinders-1); ret = 0; } return ret;}/* * D. About system Ids */#define EMPTY_PARTITION 0#define EXTENDED_PARTITION 5#define WIN98_EXTENDED 0x0f#define DM6_AUX1PARTITION 0x51#define DM6_AUX3PARTITION 0x53#define DM6_PARTITION 0x54#define EZD_PARTITION 0x55#define LINUX_SWAP 0x82#define LINUX_NATIVE 0x83#define LINUX_EXTENDED 0x85#define BSD_PARTITION 0xa5#define NETBSD_PARTITION 0xa9/* List of partition types now in i386_sys_types.c */static const char *sysname(unsigned char type) { struct systypes *s; for (s = i386_sys_types; s->name; s++) if (s->type == type) return _(s->name); return _("Unknown");}static voidlist_types(void) { struct systypes *s; printf(_("Id Name\n\n")); for (s = i386_sys_types; s->name; s++) printf("%2x %s\n", s->type, _(s->name));}static intis_extended(unsigned char type) { return (type == EXTENDED_PARTITION || type == LINUX_EXTENDED || type == WIN98_EXTENDED);}static intis_bsd(unsigned char type) { return (type == BSD_PARTITION || type == NETBSD_PARTITION);}/* * E. About partitions *//* MS/DOS partition */struct partition { unsigned char bootable; /* 0 or 0x80 */ chs begin_chs; unsigned char sys_type; chs end_chs; unsigned int start_sect; /* starting sector counting from 0 */ unsigned int nr_sects; /* nr of sectors in partition */} PACKED;/* Unfortunately, partitions are not aligned, and non-Intel machines are unhappy with non-aligned integers. So, we need a copy by hand. */static intcopy_to_int(unsigned char *cp) { unsigned int m; m = *cp++; m += (*cp++ << 8); m += (*cp++ << 16); m += (*cp++ << 24); return m;}static voidcopy_from_int(int m, char *cp) { *cp++ = (m & 0xff); m >>= 8; *cp++ = (m & 0xff); m >>= 8; *cp++ = (m & 0xff); m >>= 8; *cp++ = (m & 0xff);}static voidcopy_to_part(char *cp, struct partition *p) { p->bootable = *cp++; p->begin_chs.h = *cp++; p->begin_chs.s = *cp++; p->begin_chs.c = *cp++; p->sys_type = *cp++; p->end_chs.h = *cp++; p->end_chs.s = *cp++; p->end_chs.c = *cp++; p->start_sect = copy_to_int(cp); p->nr_sects = copy_to_int(cp+4);}static voidcopy_from_part(struct partition *p, char *cp) { *cp++ = p->bootable; *cp++ = p->begin_chs.h; *cp++ = p->begin_chs.s; *cp++ = p->begin_chs.c; *cp++ = p->sys_type; *cp++ = p->end_chs.h; *cp++ = p->end_chs.s; *cp++ = p->end_chs.c; copy_from_int(p->start_sect, cp); copy_from_int(p->nr_sects, cp+4);}/* Roughly speaking, Linux doesn't use any of the above fields except for partition type, start sector and number of sectors. (However, see also linux/drivers/scsi/fdomain.c.) The only way partition type is used (in the kernel) is the comparison for equality with EXTENDED_PARTITION (and these Disk Manager types). */struct part_desc { unsigned long start; unsigned long size; unsigned long sector, offset; /* disk location of this info */ struct partition p; struct part_desc *ep; /* extended partition containing this one */ int ptype;#define DOS_TYPE 0#define BSD_TYPE 1} zero_part_desc;static struct part_desc *outer_extended_partition(struct part_desc *p) { while (p->ep) p = p->ep; return p;}static intis_parent(struct part_desc *pp, struct part_desc *p) { while (p) { if (pp == p) return 1; p = p->ep; } return 0;}struct disk_desc { struct part_desc partitions[512]; int partno;} oldp, newp;/* determine where on the disk this information goes */static voidadd_sector_and_offset(struct disk_desc *z) { int pno; struct part_desc *p; for (pno = 0; pno < z->partno; pno++) { p = &(z->partitions[pno]); p->offset = 0x1be + (pno%4)*sizeof(struct partition); p->sector = (p->ep ? p->ep->start : 0); }}/* tell the kernel to reread the partition tables */static intreread_ioctl(int fd) { if (ioctl(fd, BLKRRPART)) { perror("BLKRRPART"); /* 2.6.8 returns EIO for a zero table */ if (errno == EBUSY) return -1; } return 0;}static intis_blockdev(int fd) { struct stat statbuf; return(fstat(fd, &statbuf) == 0 && S_ISBLK(statbuf.st_mode));}/* reread after writing */static voidreread_disk_partition(char *dev, int fd) { printf(_("Re-reading the partition table ...\n")); fflush(stdout); sync(); sleep(3); /* superfluous since 1.3.20 */ if (reread_ioctl(fd) && is_blockdev(fd)) do_warn(_("The command to re-read the partition table failed\n" "Reboot your system now, before using mkfs\n")); if (close(fd)) { perror(dev); do_warn(_("Error closing %s\n"), dev); } printf("\n");}/* find Linux name of this partition, assuming that it will have a name */static intindex_to_linux(int pno, struct disk_desc *z) { int i, ct = 1; struct part_desc *p = &(z->partitions[0]); for (i=0; i<pno; i++,p++) if (i < 4 || (p->size > 0 && !is_extended(p->p.sys_type))) ct++; return ct;}static intlinux_to_index(int lpno, struct disk_desc *z) { int i, ct = 0; struct part_desc *p = &(z->partitions[0]); for (i=0; i<z->partno && ct < lpno; i++,p++) if ((i < 4 || (p->size > 0 && !is_extended(p->p.sys_type))) && ++ct == lpno) return i; return -1;}static intasc_to_index(char *pnam, struct disk_desc *z) { int pnum, pno; if (*pnam == '#') { pno = atoi(pnam+1); } else { pnum = atoi(pnam); pno = linux_to_index(pnum, z); } if (!(pno >= 0 && pno < z->partno)) fatal(_("%s: no such partition\n"), pnam); return pno;}/* * List partitions - in terms of sectors, blocks or cylinders */#define F_SECTOR 1#define F_BLOCK 2#define F_CYLINDER 3#define F_MEGABYTE 4int default_format = F_MEGABYTE;int specified_format = 0;int show_extended = 0;int one_only = 0;int one_only_pno;int increment = 0;static voidset_format(char c) { switch(c) { default: do_warn(_("unrecognized format - using sectors\n")); case 'S': specified_format = F_SECTOR; break; case 'B': specified_format = F_BLOCK; break; case 'C': specified_format = F_CYLINDER; break; case 'M': specified_format = F_MEGABYTE; break; }}static unsigned longunitsize(int format) { default_format = (B.cylindersize ? F_CYLINDER : F_MEGABYTE); if (!format && !(format = specified_format)) format = default_format; switch(format) { default: case F_CYLINDER: if (B.cylindersize) return B.cylindersize; case F_SECTOR: return 1; case F_BLOCK: return 2; case F_MEGABYTE: return 2048; }}static unsigned longget_disksize(int format) { unsigned long cs = B.cylinders; if (cs && leave_last) cs--; return (cs * B.cylindersize) / unitsize(format);}static voidout_partition_header(char *dev, int format, struct geometry G) { if (dump) { printf(_("# partition table of %s\n"), dev); printf("unit: sectors\n\n"); return; } default_format = (G.cylindersize ? F_CYLINDER : F_MEGABYTE); if (!format && !(format = specified_format)) format = default_format; switch(format) { default: do_warn(_("unimplemented format - using %s\n"), G.cylindersize ? _("cylinders") : _("sectors")); case F_CYLINDER: if (G.cylindersize) { printf(_("Units = cylinders of %lu bytes, blocks of 1024 bytes" ", counting from %d\n\n"), G.cylindersize<<9, increment); printf(_(" Device Boot Start End #cyls #blocks Id System\n")); break; } /* fall through */ case F_SECTOR: printf(_("Units = sectors of 512 bytes, counting from %d\n\n"), increment); printf(_(" Device Boot Start End #sectors Id System\n")); break; case F_BLOCK: printf(_("Units = blocks of 1024 bytes, counting from %d\n\n"), increment); printf(_(" Device Boot Start End #blocks Id System\n")); break; case F_MEGABYTE: printf(_("Units = mebibytes of 1048576 bytes, blocks of 1024 bytes" ", counting from %d\n\n"), increment);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -