Beispiel #1
0
/*
 * Fetch disklabel for disk.
 * Use ioctl to get label unless -r flag is given.
 */
struct disklabel32 *
readlabel(int f)
{
	const char *msg;
	struct disklabel32 *lp;
	int r;

	if (rflag) {
		r = read(f, bootarea, BBSIZE);
		if (r < BBSIZE)
			err(4, "%s", specname);
		for (lp = (struct disklabel32 *)bootarea;
		    lp <= (struct disklabel32 *)(bootarea + BBSIZE - sizeof(*lp));
		    lp = (struct disklabel32 *)((char *)lp + 16)) {
			if (lp->d_magic == DISKMAGIC32 &&
			    lp->d_magic2 == DISKMAGIC32)
				break;
		}
		if (lp > (struct disklabel32 *)(bootarea+BBSIZE-sizeof(*lp)) ||
		    lp->d_magic != DISKMAGIC32 || lp->d_magic2 != DISKMAGIC32 ||
		    dkcksum32(lp) != 0) {
			errx(1, "bad pack magic number (label is damaged, "
				"or pack is unlabeled)");
		}
		if ((msg = fixlabel(f, lp, 0)) != NULL)
			errx(1, msg);
	} else {
		lp = &lab;
		if (ioctl(f, DIOCGDINFO32, lp) < 0) {
			l_perror("ioctl DIOCGDINFO32");
			exit(4);
		}
	}
	return (lp);
}
Beispiel #2
0
int
main(int argc, char *argv[])
{
	FILE *t;
	int ch, error, fd;
	const char *name;
	
	error = 0;
	name = NULL;

	while ((ch = getopt(argc, argv, "ABb:efm:nRrw")) != -1)
		switch (ch) {
			case 'A':
				allfields = 1;
				break;
			case 'B':
				++installboot;
				break;
			case 'b':
				xxboot = optarg;
				break;
			case 'f':
				is_file=1;
				break;
			case 'm':
				if (!strcmp(optarg, "i386") ||
				    !strcmp(optarg, "amd64") ||
				    !strcmp(optarg, "ia64") ||
				    !strcmp(optarg, "pc98")) {
					labelsoffset = 1;
					labeloffset = 0;
					bbsize = 8192;
				} else {
					errx(1, "Unsupported architecture");
				}
				break;
			case 'n':
				disable_write = 1;
				break;
			case 'R':
				if (op != UNSPEC)
					usage();
				op = RESTORE;
				break;
			case 'e':
				if (op != UNSPEC)
					usage();
				op = EDIT;
				break;
			case 'r':
				/*
				 * We accept and ignore -r for compatibility with
				 * historical disklabel usage.
				 */
				break;
			case 'w':
				if (op != UNSPEC)
					usage();
				op = WRITE;
				break;
			case '?':
			default:
				usage();
		}
	argc -= optind;
	argv += optind;

	if (argc < 1)
		usage();
	if (labelsoffset < 0 || labeloffset < 0)
		errx(1, "a -m <architecture> option must be specified");

	/* Figure out the names of the thing we're working on */
	if (is_file) {
		specname = argv[0];
	} else {
		specname = g_device_path(argv[0]);
		if (specname == NULL) {
			warn("unable to get correct path for %s", argv[0]);
			return(1);
		}
		fd = open(specname, O_RDONLY);
		if (fd < 0) {
			warn("error opening %s", specname);
			return(1);
		}
		pname = g_providername(fd);
		if (pname == NULL) {
			warn("error getting providername for %s", specname);
			close(fd);
			return(1);
		}
		close(fd);
	}

	if (installboot && op == UNSPEC)
		op = WRITEBOOT;
	else if (op == UNSPEC)
		op = READ;

	switch(op) {

	case UNSPEC:
		break;

	case EDIT:
		if (argc != 1)
			usage();
		readlabel(1);
		fixlabel(&lab);
		error = edit();
		break;

	case READ:
		if (argc != 1)
			usage();
		readlabel(1);
		display(stdout, NULL);
		error = checklabel(NULL);
		break;

	case RESTORE:
		if (argc != 2)
			usage();
		if (!(t = fopen(argv[1], "r")))
			err(4, "fopen %s", argv[1]);
		readlabel(0);
		if (!getasciilabel(t, &lab))
			exit(1);
		error = writelabel();
		break;

	case WRITE:
		if (argc == 2)
			name = argv[1];
		else if (argc == 1)
			name = "auto";
		else
			usage();
		readlabel(0);
		makelabel(name, &lab);
		fixlabel(&lab);
		if (checklabel(NULL) == 0)
			error = writelabel();
		break;

	case WRITEBOOT:

		readlabel(1);
		fixlabel(&lab);
		if (argc == 2)
			makelabel(argv[1], &lab);
		if (checklabel(NULL) == 0)
			error = writelabel();
		break;
	}
	exit(error);
}
Beispiel #3
0
int
writelabel(int f, const char *boot, struct disklabel32 *lp)
{
	const char *msg;
	int flag;
	int r;

	if (disable_write) {
		Warning("write to disk label suppressed - label was as follows:");
		display(stdout, lp);
		return (0);
	} else {
		/* make sure we are not overwriting our boot code */
		if (checkoldboot(f, boot))
			errx(4, "Will not overwrite old bootblocks w/ label, install new boot blocks first!");
		setbootflag(lp);
		lp->d_magic = DISKMAGIC32;
		lp->d_magic2 = DISKMAGIC32;
		lp->d_checksum = 0;
		lp->d_checksum = dkcksum32(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, DIOCSDINFO32, lp) < 0 &&
				errno != ENODEV && errno != ENOTTY) {
				l_perror("ioctl DIOCSDINFO32");
				return (1);
			}
			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)
				warn("ioctl DIOCWLABEL");
			msg = fixlabel(f, lp, 1);
			if (msg) {
				warn(msg);
				return (1);
			}
			r = write(f, boot, lp->d_bbsize);
			fixlabel(f, lp, 0);
			if (r != ((ssize_t)lp->d_bbsize)) {
				warn("write");
				return (1);
			}
#if NUMBOOT > 0
			/*
			 * Output the remainder of the disklabel
			 */
			if (bootbuf) {
				fixlabel(f, lp, 1);
				r = write(f, bootbuf, bootsize);
				fixlabel(f, lp, 0);
				if (r != bootsize) {
					warn("write");
					return(1);
				}
			}
#endif
			flag = 0;
			ioctl(f, DIOCWLABEL, &flag);
		} else if (ioctl(f, DIOCWDINFO32, lp) < 0) {
			l_perror("ioctl DIOCWDINFO32");
			return (1);
		}
	}
	return (0);
}