⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sfdisk.c

📁 Util-linux 软件包包含许多工具。其中比较重要的是加载、卸载、格式化、分区和管理硬盘驱动器
💻 C
📖 第 1 页 / 共 5 页
字号:
    z->partno = pno;}#define BSD_DISKMAGIC   (0x82564557UL)#define BSD_MAXPARTITIONS       16#define BSD_FS_UNUSED	   0typedef unsigned char u8;typedef unsigned short u16;typedef unsigned int u32;struct bsd_disklabel {	u32	d_magic;	char	d_junk1[4];	char    d_typename[16];	char    d_packname[16];	char	d_junk2[92];	u32	d_magic2;	char	d_junk3[2];	u16	d_npartitions;          /* number of partitions in following */	char	d_junk4[8];     struct  bsd_partition {         /* the partition table */                u32   p_size;         /* number of sectors in partition */                u32   p_offset;       /* starting sector */                u32   p_fsize;        /* filesystem basic fragment size */                u8    p_fstype;       /* filesystem type, see below */                u8    p_frag;         /* filesystem fragments per block */                u16   p_cpg;          /* filesystem cylinders per group */     } d_partitions[BSD_MAXPARTITIONS];      /* actually may be more */};static voidbsd_partition(char *dev, int fd, struct part_desc *ep, struct disk_desc *z) {	struct bsd_disklabel *l;	struct bsd_partition *bp, *bp0;	unsigned long start = ep->start;	struct sector *s;	struct part_desc *partitions = &(z->partitions[0]);	int pno = z->partno;	if (!(s = get_sector(dev,fd,start+1)))		return;	l = (struct bsd_disklabel *) (s->data);	if (l->d_magic != BSD_DISKMAGIC || l->d_magic2 != BSD_DISKMAGIC)		return;	bp = bp0 = &l->d_partitions[0];	while (bp - bp0 < BSD_MAXPARTITIONS && bp - bp0 < l->d_npartitions) {		if (pno+1 >= SIZE(z->partitions)) {			do_warn(_("too many partitions - ignoring those "			       "past nr (%d)\n"), pno-1);			break;		}		if (bp->p_fstype != BSD_FS_UNUSED) {			partitions[pno].start = bp->p_offset;			partitions[pno].size = bp->p_size;			partitions[pno].sector = start+1;			partitions[pno].offset = (char *)bp - (char *)bp0;			partitions[pno].ep = 0;			partitions[pno].ptype = BSD_TYPE;			pno++;		}		bp++;	}	z->partno = pno;}#define MAKE_VERSION(p,q,r)     (65536*(p) + 256*(q) + (r))static intlinux_version_code(void) {        struct utsname my_utsname;        int p, q, r;        if (uname(&my_utsname) == 0) {                p = atoi(strtok(my_utsname.release, "."));                q = atoi(strtok(NULL, "."));                r = atoi(strtok(NULL, "."));                return MAKE_VERSION(p,q,r);        }        return 0;}static intmsdos_partition(char *dev, int fd, unsigned long start, struct disk_desc *z) {    int i;    char *cp;    struct partition pt;    struct sector *s;    struct part_desc *partitions = &(z->partitions[0]);    int pno = z->partno;    int bsd_later = (linux_version_code() >= MAKE_VERSION(2,3,40));    if (!(s = get_sector(dev, fd, start)))	return 0;    if (!msdos_signature(s))	return 0;    cp = s->data + 0x1be;    copy_to_part(cp,&pt);    /* If I am not mistaken, recent kernels will hide this from us,	   so we will never actually see traces of a Disk Manager */    if (pt.sys_type == DM6_PARTITION	|| pt.sys_type == EZD_PARTITION	|| pt.sys_type == DM6_AUX1PARTITION	|| pt.sys_type == DM6_AUX3PARTITION) {	do_warn(_("detected Disk Manager - unable to handle that\n"));	return 0;    }    { unsigned int sig = *(unsigned short *)(s->data + 2);      if (sig <= 0x1ae	  && *(unsigned short *)(s->data + sig) == 0x55aa	  && (1 & *(unsigned char *)(s->data + sig + 2))) {	  do_warn(_("DM6 signature found - giving up\n"));	  return 0;      }    }    for (pno=0; pno<4; pno++,cp += sizeof(struct partition)) {	partitions[pno].sector = start;	partitions[pno].offset = cp - s->data;	copy_to_part(cp,&pt);	partitions[pno].start = start + pt.start_sect;	partitions[pno].size = pt.nr_sects;	partitions[pno].ep = 0;	partitions[pno].p = pt;    }    z->partno = pno;    for (i=0; i<4; i++) {	if (is_extended(partitions[i].p.sys_type)) {	    if (!partitions[i].size) {		do_warn(_("strange..., an extended partition of size 0?\n"));		continue;	    }	    extended_partition(dev, fd, &partitions[i], z);	}	if (!bsd_later && is_bsd(partitions[i].p.sys_type)) {	    if (!partitions[i].size) {		do_warn(_("strange..., a BSD partition of size 0?\n"));		continue;	    }	    bsd_partition(dev, fd, &partitions[i], z);	}    }    if (bsd_later) {	for (i=0; i<4; i++) {	    if (is_bsd(partitions[i].p.sys_type)) {		if (!partitions[i].size) {		    do_warn(_("strange..., a BSD partition of size 0?\n"));		    continue;		}		bsd_partition(dev, fd, &partitions[i], z);	    }	}    }	        return 1;}static intosf_partition(char *dev, int fd, unsigned long start, struct disk_desc *z) {	return 0;}static intsun_partition(char *dev, int fd, unsigned long start, struct disk_desc *z) {	return 0;}static intamiga_partition(char *dev, int fd, unsigned long start, struct disk_desc *z) {	return 0;}static voidget_partitions(char *dev, int fd, struct disk_desc *z) {    z->partno = 0;    if (!msdos_partition(dev, fd, 0, z)	&& !osf_partition(dev, fd, 0, z)	&& !sun_partition(dev, fd, 0, z)	&& !amiga_partition(dev, fd, 0, z)) {	do_warn(_(" %s: unrecognized partition table type\n"), dev);	return;    }}static intwrite_partitions(char *dev, int fd, struct disk_desc *z) {    struct sector *s;    struct part_desc *partitions = &(z->partitions[0]), *p;    int pno = z->partno;    if (no_write) {	do_warn(_("-n flag was given: Nothing changed\n"));	exit(0);    }    for (p = partitions; p < partitions+pno; p++) {	s = get_sector(dev, fd, p->sector);	if (!s) return 0;	s->to_be_written = 1;	if (p->ptype == DOS_TYPE) {	    copy_from_part(&(p->p), s->data + p->offset);	    s->data[510] = 0x55;	    s->data[511] = 0xaa;	}    }    if (save_sector_file) {	if (!save_sectors(dev, fd)) {	    fatal(_("Failed saving the old sectors - aborting\n"));	    return 0;	}    }    if (!write_sectors(dev, fd)) {	error(_("Failed writing the partition on %s\n"), dev);	return 0;    }    return 1;}/* *  F. The standard input *//* * Input format: * <start> <size> <type> <bootable> <c,h,s> <c,h,s> * Fields are separated by whitespace or comma or semicolon possibly * followed by whitespace; initial and trailing whitespace is ignored. * Numbers can be octal, decimal or hexadecimal, decimal is default * The <c,h,s> parts can (and probably should) be omitted. * Bootable is specified as [*|-], with as default not-bootable. * Type is given in hex, without the 0x prefix, or is [E|S|L|X], where * L (LINUX_NATIVE (83)) is the default, S is LINUX_SWAP (82), and E * is EXTENDED_PARTITION (5), X is LINUX_EXTENDED (85). * The default value of start is the first nonassigned sector/cylinder/... * The default value of size is as much as possible (until next * partition or end-of-disk). * .: end of chain of extended partitions. * * On interactive input an empty line means: all defaults. * Otherwise empty lines are ignored. */int eof, eob;struct dumpfld {    int fldno;    char *fldname;    int is_bool;} dumpflds[] = {    { 0, "start", 0 },    { 1, "size", 0 },    { 2, "Id", 0 },    { 3, "bootable", 1 },    { 4, "bh", 0 },    { 5, "bs", 0 },    { 6, "bc", 0 },    { 7, "eh", 0 },    { 8, "es", 0 },    { 9, "ec", 0 }};/* * Read a line, split it into fields * * (some primitive handwork, but a more elaborate parser seems *  unnecessary) */#define RD_EOF (-1)#define RD_CMD (-2)static intread_stdin(unsigned char **fields, unsigned char *line, int fieldssize, int linesize) {    unsigned char *lp, *ip;    int c, fno;    /* boolean true and empty string at start */    line[0] = '*';    line[1] = 0;    for (fno=0; fno < fieldssize; fno++)      fields[fno] = line + 1;    fno = 0;    /* read a line from stdin */    lp = fgets(line+2, linesize, stdin);    if (lp == NULL) {	eof = 1;	return RD_EOF;    }    if (!(lp = index(lp, '\n')))      fatal(_("long or incomplete input line - quitting\n"));    *lp = 0;    /* remove comments, if any */    if ((lp = index(line+2, '#')) != 0)      *lp = 0;    /* recognize a few commands - to be expanded */    if (!strcmp(line+2, "unit: sectors")) {	specified_format = F_SECTOR;	return RD_CMD;    }    /* dump style? - then bad input is fatal */    if ((ip = index(line+2, ':')) != 0) {	struct dumpfld *d;      nxtfld:	    ip++;	    while(isspace(*ip))	      ip++;	    if (*ip == 0)	      return fno;	    for(d = dumpflds; d-dumpflds < SIZE(dumpflds); d++) {		if (!strncmp(ip, d->fldname, strlen(d->fldname))) {		    ip += strlen(d->fldname);		    while(isspace(*ip))		      ip++;		    if (d->is_bool)			fields[d->fldno] = line;		    else if (*ip == '=') {			while(isspace(*++ip)) ;			fields[d->fldno] = ip;			while(isalnum(*ip)) 	/* 0x07FF */			  ip++;		    } else		      fatal(_("input error: `=' expected after %s field\n"),			    d->fldname);		    if (fno <= d->fldno)		      fno = d->fldno + 1;		    if (*ip == 0)		      return fno;		    if (*ip != ',' && *ip != ';')		      fatal(_("input error: unexpected character %c after %s field\n"),			    *ip, d->fldname);		    *ip = 0;		    goto nxtfld;		}	    }	    fatal(_("unrecognized input: %s\n"), ip);    }    /* split line into fields */    lp = ip = line+2;    fields[fno++] = lp;    while((c = *ip++) != 0) {	if (!lp[-1] && (c == '\t' || c == ' '))	  ;	else if (c == '\t' || c == ' ' || c == ',' || c == ';') {	    *lp++ = 0;	    if (fno < fieldssize)		fields[fno++] = lp;	    continue;	} else	  *lp++ = c;    }    if (lp == fields[fno-1])      fno--;    return fno;}/* read a number, use default if absent *//* a sign gives an offset from the default */static intget_ul(char *u, unsigned long *up, unsigned long def, int base) {    char *nu;    int sign = 0;    unsigned long val;    if (*u == '+') {	sign = 1;	u++;    } else if (*u == '-') {	sign = -1;	u++;    }    if (*u) {	errno = 0;	val = strtoul(u, &nu, base);	if (errno == ERANGE) {	    do_warn(_("number too big\n"));	    return -1;	}	if (*nu) {	    do_warn(_("trailing junk after number\n"));	    return -1;	}	if (sign == 1)		val = def + val;	else if (sign == -1)		val = def - val;	*up = val;    } else      *up = def;    return 0;}/* There are two common ways to structure extended partitions:   as nested boxes, and as a chain. Sometimes the partitions   must be given in order. Sometimes all logical partitions   must lie inside the outermost extended partition.NESTED: every partition is contained in the surrounding partitions   and is disjoint from all others.CHAINED: every data partition is contained in the surrounding partitions   and disjoint from all others, but extended partitions may lie outside   (insofar as allowed by all_logicals_inside_outermost_extended).ONESECTOR: all data partitions are mutually disjoint; extended partitions   each use one sector only (except perhaps for the outermost one).*/int partitions_in_order = 0;int all_logicals_inside_outermost_extended = 1;enum { NESTED, CHAINED, ONESECTOR } boxes = NESTED;/* find the default value for <start> - assuming entire units */static unsigned longfirst_free(int pno, int is_extended, struct part_desc *ep, int format,	   unsigned long mid, struct disk_desc *z) {    unsigned long ff, fff;    unsigned long unit = unitsize(format);    struct part_desc *partitions = &(z->partitions[0]), *pp = 0;    /* if containing ep undefined, look at its container */    if (ep && ep->p.sys_type == EMPTY_PARTITION)      ep = ep->ep;    if (ep) {	if (boxes == NESTED || (boxes == CHAINED && !is_extended))	  pp = ep;	else if (all_logicals_inside_outermost_extended)	  pp = outer_extended_partition(ep);    }#if 0    ff = pp ? (pp->start + unit - 1) / unit : 0;#else    /* rounding up wastes almost an entire cylinder - round down       and leave it to compute_start_sect() to fix the difference */    ff = pp ? pp->start / unit : 0;#endif    /* MBR and 1st sector of an extended partition are never free */    if (unit == 1)      ff++;  again:    for(pp = partitions; pp < partitions+pno; pp++) {	if (!is_parent(pp, ep) && pp->size > 0) {	    if ((partitions_in_order || pp->start / unit <= ff		                     || (mid && pp->start / unit <= mid))		&& (fff = (pp->start + pp->size + unit - 1) / unit) > ff) {		ff = fff;		goto again;	    }	}    }    return ff;}/* find the default value for <size> - assuming entire units */static unsigned longmax_length(int pno, int is_extended, struct part_desc *ep, int format,	   unsigned long start, struct disk_desc *z) {    unsigned long fu;    unsigned long unit = unitsize(format);    struct part_desc *partitions = &(z->partitions[0]), *pp = 0;    /* if containing ep undefined, look at its container */    if (ep && ep->p.sys_type == EMPTY_PARTITION)      ep = ep->ep;    if (ep) {	if (boxes == NESTED || (boxes == CHAINED && !is_extended))	  pp = ep;	else if (all_logicals_inside_outermost_extended)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -