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

📄 disklabel.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
	case ESRCH:		fprintf(stderr, "No disk label on disk;\n");		fprintf(stderr,		    "use \"disklabel -r\" to install initial label\n");		break;	case EINVAL:		fprintf(stderr, "Label magic number or checksum is wrong!\n");		fprintf(stderr, "(disklabel or kernel is out of date?)\n");		break;	case EBUSY:		fprintf(stderr, "Open partition would move or shrink\n");		break;	case EXDEV:		fprintf(stderr,	"Labeled partition or 'a' partition must start at beginning of disk\n");		break;	default:		errno = saverrno;		perror((char *)NULL);		break;	}}/* * Fetch disklabel for disk. * Use ioctl to get label unless -r flag is given. */struct disklabel *readlabel(f)	int f;{	register struct disklabel *lp;	if (rflag) {		if (read(f, bootarea, BBSIZE) < BBSIZE)			Perror(specname);		for (lp = (struct disklabel *)bootarea;		    lp <= (struct disklabel *)(bootarea + BBSIZE - sizeof(*lp));		    lp = (struct disklabel *)((char *)lp + 16))			if (lp->d_magic == DISKMAGIC &&			    lp->d_magic2 == DISKMAGIC)				break;		if (lp > (struct disklabel *)(bootarea+BBSIZE-sizeof(*lp)) ||		    lp->d_magic != DISKMAGIC || lp->d_magic2 != DISKMAGIC ||		    dkcksum(lp) != 0) {			fprintf(stderr,	"Bad pack magic number (label is damaged, or pack is unlabeled)\n");			/* lp = (struct disklabel *)(bootarea + LABELOFFSET); */			exit (1);		}	} else {		lp = &lab;		if (ioctl(f, DIOCGDINFO, lp) < 0)			Perror("ioctl DIOCGDINFO");	}	return (lp);}/* * Construct a bootarea (d_bbsize bytes) in the specified buffer ``boot'' * Returns a pointer to the disklabel portion of the bootarea. */struct disklabel *makebootarea(boot, dp, f)	char *boot;	register struct disklabel *dp;	int f;{	struct disklabel *lp;	register char *p;	int b;#if NUMBOOT > 0	char *dkbasename;	struct stat sb;#endif	/* XXX */	if (dp->d_secsize == 0) {		dp->d_secsize = DEV_BSIZE;		dp->d_bbsize = BBSIZE;	}	lp = (struct disklabel *)		(boot + (LABELSECTOR * dp->d_secsize) + LABELOFFSET);	bzero((char *)lp, sizeof *lp);#if NUMBOOT > 0	/*	 * If we are not installing a boot program but we are installing a	 * label on disk then we must read the current bootarea so we don't	 * clobber the existing boot.	 */	if (!installboot) {		if (rflag) {			if (read(f, boot, BBSIZE) < BBSIZE)				Perror(specname);			bzero((char *)lp, sizeof *lp);		}		return (lp);	}	/*	 * We are installing a boot program.  Determine the name(s) and	 * read them into the appropriate places in the boot area.	 */	if (!xxboot || !bootxx) {		dkbasename = np;		if ((p = rindex(dkname, '/')) == NULL)			p = dkname;		else			p++;		while (*p && !isdigit(*p))			*np++ = *p++;		*np++ = '\0';		if (!xxboot) {			(void)sprintf(np, "%s/%sboot",				      _PATH_BOOTDIR, dkbasename);			if (access(np, F_OK) < 0 && dkbasename[0] == 'r')				dkbasename++;			xxboot = np;			(void)sprintf(xxboot, "%s/%sboot",				      _PATH_BOOTDIR, dkbasename);			np += strlen(xxboot) + 1;		}#if NUMBOOT > 1		if (!bootxx) {			(void)sprintf(np, "%s/boot%s",				      _PATH_BOOTDIR, dkbasename);			if (access(np, F_OK) < 0 && dkbasename[0] == 'r')				dkbasename++;			bootxx = np;			(void)sprintf(bootxx, "%s/boot%s",				      _PATH_BOOTDIR, dkbasename);			np += strlen(bootxx) + 1;		}#endif	}#ifdef DEBUG	if (debug)		fprintf(stderr, "bootstraps: xxboot = %s, bootxx = %s\n",			xxboot, bootxx ? bootxx : "NONE");#endif	/*	 * Strange rules:	 * 1. One-piece bootstrap (hp300/hp800)	 *	up to d_bbsize bytes of ``xxboot'' go in bootarea, the rest	 *	is remembered and written later following the bootarea.	 * 2. Two-piece bootstraps (vax/i386?/mips?)	 *	up to d_secsize bytes of ``xxboot'' go in first d_secsize	 *	bytes of bootarea, remaining d_bbsize-d_secsize filled	 *	from ``bootxx''.	 */	b = open(xxboot, O_RDONLY);	if (b < 0)		Perror(xxboot);#if NUMBOOT > 1	if (read(b, boot, (int)dp->d_secsize) < 0)		Perror(xxboot);	(void)close(b);	b = open(bootxx, O_RDONLY);	if (b < 0)		Perror(bootxx);	if (read(b, &boot[dp->d_secsize], (int)(dp->d_bbsize-dp->d_secsize)) < 0)		Perror(bootxx);#else	if (read(b, boot, (int)dp->d_bbsize) < 0)		Perror(xxboot);	(void)fstat(b, &sb);	bootsize = (int)sb.st_size - dp->d_bbsize;	if (bootsize > 0) {		/* XXX assume d_secsize is a power of two */		bootsize = (bootsize + dp->d_secsize-1) & ~(dp->d_secsize-1);		bootbuf = (char *)malloc((size_t)bootsize);		if (bootbuf == 0)			Perror(xxboot);		if (read(b, bootbuf, bootsize) < 0) {			free(bootbuf);			Perror(xxboot);		}	}#endif	(void)close(b);#endif	/*	 * Make sure no part of the bootstrap is written in the area	 * reserved for the label.	 */	for (p = (char *)lp; p < (char *)lp + sizeof(struct disklabel); p++)		if (*p) {			fprintf(stderr,			    "Bootstrap doesn't leave room for disk label\n");			exit(2);		}	return (lp);}display(f, lp)	FILE *f;	register struct disklabel *lp;{	register int i, j;	register struct partition *pp;	fprintf(f, "# %s:\n", specname);	if ((unsigned) lp->d_type < DKMAXTYPES)		fprintf(f, "type: %s\n", dktypenames[lp->d_type]);	else		fprintf(f, "type: %d\n", lp->d_type);	fprintf(f, "disk: %.*s\n", sizeof(lp->d_typename), lp->d_typename);	fprintf(f, "label: %.*s\n", sizeof(lp->d_packname), lp->d_packname);	fprintf(f, "flags:");	if (lp->d_flags & D_REMOVABLE)		fprintf(f, " removeable");	if (lp->d_flags & D_ECC)		fprintf(f, " ecc");	if (lp->d_flags & D_BADSECT)		fprintf(f, " badsect");	fprintf(f, "\n");	fprintf(f, "bytes/sector: %d\n", lp->d_secsize);	fprintf(f, "sectors/track: %d\n", lp->d_nsectors);	fprintf(f, "tracks/cylinder: %d\n", lp->d_ntracks);	fprintf(f, "sectors/cylinder: %d\n", lp->d_secpercyl);	fprintf(f, "cylinders: %d\n", lp->d_ncylinders);	fprintf(f, "rpm: %d\n", lp->d_rpm);	fprintf(f, "interleave: %d\n", lp->d_interleave);	fprintf(f, "trackskew: %d\n", lp->d_trackskew);	fprintf(f, "cylinderskew: %d\n", lp->d_cylskew);	fprintf(f, "headswitch: %d\t\t# milliseconds\n", lp->d_headswitch);	fprintf(f, "track-to-track seek: %d\t# milliseconds\n", lp->d_trkseek);	fprintf(f, "drivedata: ");	for (i = NDDATA - 1; i >= 0; i--)		if (lp->d_drivedata[i])			break;	if (i < 0)		i = 0;	for (j = 0; j <= i; j++)		fprintf(f, "%d ", lp->d_drivedata[j]);	fprintf(f, "\n\n%d partitions:\n", lp->d_npartitions);	fprintf(f,	    "#        size   offset    fstype   [fsize bsize   cpg]\n");	pp = lp->d_partitions;	for (i = 0; i < lp->d_npartitions; i++, pp++) {		if (pp->p_size) {			fprintf(f, "  %c: %8d %8d  ", 'a' + i,			   pp->p_size, pp->p_offset);			if ((unsigned) pp->p_fstype < FSMAXTYPES)				fprintf(f, "%8.8s", fstypenames[pp->p_fstype]);			else				fprintf(f, "%8d", pp->p_fstype);			switch (pp->p_fstype) {			case FS_UNUSED:				/* XXX */				fprintf(f, "    %5d %5d %5.5s ",				    pp->p_fsize, pp->p_fsize * pp->p_frag, "");				break;			case FS_BSDFFS:				fprintf(f, "    %5d %5d %5d ",				    pp->p_fsize, pp->p_fsize * pp->p_frag,				    pp->p_cpg);				break;			default:				fprintf(f, "%20.20s", "");				break;			}			fprintf(f, "\t# (Cyl. %4d",			    pp->p_offset / lp->d_secpercyl);			if (pp->p_offset % lp->d_secpercyl)			    putc('*', f);			else			    putc(' ', f);			fprintf(f, "- %d",			    (pp->p_offset + 			    pp->p_size + lp->d_secpercyl - 1) /			    lp->d_secpercyl - 1);			if (pp->p_size % lp->d_secpercyl)			    putc('*', f);			fprintf(f, ")\n");		}	}	fflush(f);}edit(lp, f)	struct disklabel *lp;	int f;{	register int c;	struct disklabel label;	FILE *fd;	char *mktemp();	(void) mktemp(tmpfil);	fd = fopen(tmpfil, "w");	if (fd == NULL) {		fprintf(stderr, "%s: Can't create\n", tmpfil);		return (1);	}	(void)fchmod(fileno(fd), 0600);	display(fd, lp);	fclose(fd);	for (;;) {		if (!editit())			break;		fd = fopen(tmpfil, "r");		if (fd == NULL) {			fprintf(stderr, "%s: Can't reopen for reading\n",				tmpfil);			break;		}		bzero((char *)&label, sizeof(label));		if (getasciilabel(fd, &label)) {			*lp = label;			if (writelabel(f, bootarea, lp) == 0) {				(void) unlink(tmpfil);				return (0);			}		}		printf("re-edit the label? [y]: "); fflush(stdout);		c = getchar();		if (c != EOF && c != (int)'\n')			while (getchar() != (int)'\n')				;		if  (c == (int)'n')			break;	}	(void) unlink(tmpfil);	return (1);}editit(){	register int pid, xpid;	int stat, omask;	extern char *getenv();	omask = sigblock(sigmask(SIGINT)|sigmask(SIGQUIT)|sigmask(SIGHUP));	while ((pid = fork()) < 0) {		extern int errno;		if (errno == EPROCLIM) {			fprintf(stderr, "You have too many processes\n");			return(0);		}		if (errno != EAGAIN) {			perror("fork");			return(0);		}		sleep(1);	}	if (pid == 0) {		register char *ed;		sigsetmask(omask);		setgid(getgid());		setuid(getuid());		if ((ed = getenv("EDITOR")) == (char *)0)			ed = DEFEDITOR;		execlp(ed, ed, tmpfil, 0);		perror(ed);		exit(1);	}	while ((xpid = wait(&stat)) >= 0)		if (xpid == pid)			break;	sigsetmask(omask);	return(!stat);}char *skip(cp)	register char *cp;{	while (*cp != '\0' && isspace(*cp))		cp++;	if (*cp == '\0' || *cp == '#')		return ((char *)NULL);	return (cp);}char *word(cp)	register char *cp;{	register char c;	while (*cp != '\0' && !isspace(*cp) && *cp != '#')		cp++;	if ((c = *cp) != '\0') {		*cp++ = '\0';		if (c != '#')			return (skip(cp));	}	return ((char *)NULL);}/* * Read an ascii label in from fd f, * in the same format as that put out by display(), * and fill in lp. */getasciilabel(f, lp)	FILE	*f;	register struct disklabel *lp;{	register char **cpp, *cp;	register struct partition *pp;	char *tp, *s, line[BUFSIZ];	int v, lineno = 0, errors = 0;	lp->d_bbsize = BBSIZE;				/* XXX */	lp->d_sbsize = SBSIZE;				/* XXX */	while (fgets(line, sizeof(line) - 1, f)) {		lineno++;		if (cp = index(line,'\n'))			*cp = '\0';		cp = skip(line);		if (cp == NULL)			continue;		tp = index(cp, ':');		if (tp == NULL) {			fprintf(stderr, "line %d: syntax error\n", lineno);			errors++;			continue;		}		*tp++ = '\0', tp = skip(tp);		if (streq(cp, "type")) {			if (tp == NULL)				tp = "unknown";			cpp = dktypenames;			for (; cpp < &dktypenames[DKMAXTYPES]; cpp++)				if ((s = *cpp) && streq(s, tp)) {					lp->d_type = cpp - dktypenames;					goto next;

⌨️ 快捷键说明

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