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

📄 disklabel.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * Copyright (c) 1987, 1993 *	The Regents of the University of California.  All rights reserved. * * This code is derived from software contributed to Berkeley by * Symmetric Computer Systems. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by the University of *	California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */#ifndef lintstatic char copyright[] ="@(#) Copyright (c) 1987, 1993\n\	The Regents of the University of California.  All rights reserved.\n";#endif /* not lint */#ifndef lintstatic char sccsid[] = "@(#)disklabel.c	8.2 (Berkeley) 1/7/94";/* from static char sccsid[] = "@(#)disklabel.c	1.2 (Symmetric) 11/28/85"; */#endif /* not lint */#include <sys/param.h>#include <sys/signal.h>#include <sys/errno.h>#include <sys/file.h>#include <sys/ioctl.h>#include <sys/stat.h>#define DKTYPENAMES#include <sys/disklabel.h>#include <ufs/ffs/fs.h>#include <unistd.h>#include <string.h>#include <stdio.h>#include <ctype.h>#include "pathnames.h"/* * Disklabel: read and write disklabels. * The label is usually placed on one of the first sectors of the disk. * Many machines also place a bootstrap in the same area, * in which case the label is embedded in the bootstrap. * The bootstrap source must leave space at the proper offset * for the label on such machines. */#ifdef tahoe#define RAWPARTITION	'a'#else#define RAWPARTITION	'c'#endif#ifndef BBSIZE#define	BBSIZE	8192			/* size of boot area, with label */#endif#ifdef tahoe#define	NUMBOOT	0#else#if defined(hp300) || defined(hp800)#define	NUMBOOT	1#else#define	NUMBOOT	2#endif#endif#define	DEFEDITOR	_PATH_VI#define	streq(a,b)	(strcmp(a,b) == 0)char	*dkname;char	*specname;char	tmpfil[] = _PATH_TMP;extern	int errno;char	namebuf[BBSIZE], *np = namebuf;struct	disklabel lab;struct	disklabel *readlabel(), *makebootarea();char	bootarea[BBSIZE];#if NUMBOOT > 0int	installboot;	/* non-zero if we should install a boot program */char	*bootbuf;	/* pointer to buffer with remainder of boot prog */int	bootsize;	/* size of remaining boot program */char	*xxboot;	/* primary boot */char	*bootxx;	/* secondary boot */char	boot0[MAXPATHLEN];char	boot1[MAXPATHLEN];#endifenum	{	UNSPEC, EDIT, NOWRITE, READ, RESTORE, WRITE, WRITEABLE, WRITEBOOT} op = UNSPEC;int	rflag;#ifdef DEBUGint	debug;#define OPTIONS	"BNRWb:ders:w"#else#define OPTIONS	"BNRWb:ers:w"#endifmain(argc, argv)	int argc;	char *argv[];{	extern char *optarg;	extern int optind;	register struct disklabel *lp;	FILE *t;	int ch, f, flag, error = 0;	char *name = 0;	while ((ch = getopt(argc, argv, OPTIONS)) != EOF)		switch (ch) {#if NUMBOOT > 0			case 'B':				++installboot;				break;			case 'b':				xxboot = optarg;				break;#if NUMBOOT > 1			case 's':				bootxx = optarg;				break;#endif#endif			case 'N':				if (op != UNSPEC)					usage();				op = NOWRITE;				break;			case 'R':				if (op != UNSPEC)					usage();				op = RESTORE;				break;			case 'W':				if (op != UNSPEC)					usage();				op = WRITEABLE;				break;			case 'e':				if (op != UNSPEC)					usage();				op = EDIT;				break;			case 'r':				++rflag;				break;			case 'w':				if (op != UNSPEC)					usage();				op = WRITE;				break;#ifdef DEBUG			case 'd':				debug++;				break;#endif			case '?':			default:				usage();		}	argc -= optind;	argv += optind;#if NUMBOOT > 0	if (installboot) {		rflag++;		if (op == UNSPEC)			op = WRITEBOOT;	} else {		if (op == UNSPEC)			op = READ;		xxboot = bootxx = 0;	}#else	if (op == UNSPEC)		op = READ;#endif	if (argc < 1)		usage();	dkname = argv[0];	if (dkname[0] != '/') {		(void)sprintf(np, "%sr%s%c", _PATH_DEV, dkname, RAWPARTITION);		specname = np;		np += strlen(specname) + 1;	} else		specname = dkname;	f = open(specname, op == READ ? O_RDONLY : O_RDWR);	if (f < 0 && errno == ENOENT && dkname[0] != '/') {		(void)sprintf(specname, "%sr%s", _PATH_DEV, dkname);		np = namebuf + strlen(specname) + 1;		f = open(specname, op == READ ? O_RDONLY : O_RDWR);	}	if (f < 0)		Perror(specname);	switch(op) {	case EDIT:		if (argc != 1)			usage();		lp = readlabel(f);		error = edit(lp, f);		break;	case NOWRITE:		flag = 0;		if (ioctl(f, DIOCWLABEL, (char *)&flag) < 0)			Perror("ioctl DIOCWLABEL");		break;	case READ:		if (argc != 1)			usage();		lp = readlabel(f);		display(stdout, lp);		error = checklabel(lp);		break;	case RESTORE:#if NUMBOOT > 0		if (installboot && argc == 3) {			makelabel(argv[2], 0, &lab);			argc--;		}#endif		if (argc != 2)			usage();		lp = makebootarea(bootarea, &lab, f);		if (!(t = fopen(argv[1], "r")))			Perror(argv[1]);		if (getasciilabel(t, lp))			error = writelabel(f, bootarea, lp);		break;	case WRITE:		if (argc == 3) {			name = argv[2];			argc--;		}		if (argc != 2)			usage();		makelabel(argv[1], name, &lab);		lp = makebootarea(bootarea, &lab, f);		*lp = lab;		if (checklabel(lp) == 0)			error = writelabel(f, bootarea, lp);		break;	case WRITEABLE:		flag = 1;		if (ioctl(f, DIOCWLABEL, (char *)&flag) < 0)			Perror("ioctl DIOCWLABEL");		break;#if NUMBOOT > 0	case WRITEBOOT:	{		struct disklabel tlab;		lp = readlabel(f);		tlab = *lp;		if (argc == 2)			makelabel(argv[1], 0, &lab);		lp = makebootarea(bootarea, &lab, f);		*lp = tlab;		if (checklabel(lp) == 0)			error = writelabel(f, bootarea, lp);		break;	}#endif	}	exit(error);}/* * Construct a prototype disklabel from /etc/disktab.  As a side * effect, set the names of the primary and secondary boot files * if specified. */makelabel(type, name, lp)	char *type, *name;	register struct disklabel *lp;{	register struct disklabel *dp;	char *strcpy();	dp = getdiskbyname(type);	if (dp == NULL) {		fprintf(stderr, "%s: unknown disk type\n", type);		exit(1);	}	*lp = *dp;#if NUMBOOT > 0	/*	 * Set bootstrap name(s).	 * 1. If set from command line, use those,	 * 2. otherwise, check if disktab specifies them (b0 or b1),	 * 3. otherwise, makebootarea() will choose ones based on the name	 *    of the disk special file. E.g. /dev/ra0 -> raboot, bootra	 */	if (!xxboot && lp->d_boot0) {		if (*lp->d_boot0 != '/')			(void)sprintf(boot0, "%s/%s",				      _PATH_BOOTDIR, lp->d_boot0);		else			(void)strcpy(boot0, lp->d_boot0);		xxboot = boot0;	}#if NUMBOOT > 1	if (!bootxx && lp->d_boot1) {		if (*lp->d_boot1 != '/')			(void)sprintf(boot1, "%s/%s",				      _PATH_BOOTDIR, lp->d_boot1);		else			(void)strcpy(boot1, lp->d_boot1);		bootxx = boot1;	}#endif#endif	/* d_packname is union d_boot[01], so zero */	bzero(lp->d_packname, sizeof(lp->d_packname));	if (name)		(void)strncpy(lp->d_packname, name, sizeof(lp->d_packname));}writelabel(f, boot, lp)	int f;	char *boot;	register struct disklabel *lp;{	register int i;	int flag;	setbootflag(lp);	lp->d_magic = DISKMAGIC;	lp->d_magic2 = DISKMAGIC;	lp->d_checksum = 0;	lp->d_checksum = dkcksum(lp);	if (rflag) {		/*		 * First set the kernel disk label,		 * then write a label to the raw disk.		 * If the SDINFO ioctl fails because it is unimplemented,		 * keep going; otherwise, the kernel consistency checks		 * may prevent us from changing the current (in-core)		 * label.		 */		if (ioctl(f, DIOCSDINFO, lp) < 0 &&		    errno != ENODEV && errno != ENOTTY) {			l_perror("ioctl DIOCSDINFO");			return (1);		}		(void)lseek(f, (off_t)0, SEEK_SET);		/*		 * write enable label sector before write (if necessary),		 * disable after writing.		 */		flag = 1;		if (ioctl(f, DIOCWLABEL, &flag) < 0)			perror("ioctl DIOCWLABEL");		if (write(f, boot, lp->d_bbsize) != lp->d_bbsize) {			perror("write");			return (1);		}#if NUMBOOT > 0		/*		 * Output the remainder of the disklabel		 */		if (bootbuf && write(f, bootbuf, bootsize) != bootsize) {			perror("write");			return(1);		}#endif		flag = 0;		(void) ioctl(f, DIOCWLABEL, &flag);	} else if (ioctl(f, DIOCWDINFO, lp) < 0) {		l_perror("ioctl DIOCWDINFO");		return (1);	}#ifdef vax	if (lp->d_type == DTYPE_SMD && lp->d_flags & D_BADSECT) {		daddr_t alt;		alt = lp->d_ncylinders * lp->d_secpercyl - lp->d_nsectors;		for (i = 1; i < 11 && i < lp->d_nsectors; i += 2) {			(void)lseek(f, (off_t)((alt + i) * lp->d_secsize),			    SEEK_SET);			if (write(f, boot, lp->d_secsize) < lp->d_secsize) {				int oerrno = errno;				fprintf(stderr, "alternate label %d ", i/2);				errno = oerrno;				perror("write");			}		}	}#endif	return (0);}l_perror(s)	char *s;{	int saverrno = errno;	fprintf(stderr, "disklabel: %s: ", s);	switch (saverrno) {

⌨️ 快捷键说明

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