Beispiel #1
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 #2
0
/*
 * Write out the mbr to the specified file.
 */
static void
write_mbr(const char *fname, int flags, u_int8_t *mbr, int mbr_size)
{
	struct gctl_req *grq;
	const char *errmsg;
	char *pname;
	ssize_t n;
	int fd;

	fd = open(fname, O_WRONLY | flags, 0666);
	if (fd != -1) {
		n = write(fd, mbr, mbr_size);
		close(fd);
		if (n != mbr_size)
			errx(1, "%s: short write", fname);
		return;
	}

	/*
	 * If we're called to write to a backup file, don't try to
	 * write through GEOM.
	 */
	if (flags != 0)
		err(1, "can't open file %s to write backup", fname);

	/* Try open it read only. */
	fd = open(fname, O_RDONLY);
	if (fd == -1) {
		warn("error opening %s", fname);
		return;
	}

	pname = g_providername(fd);
	if (pname == NULL) {
		warn("error getting providername for %s", fname);
		return;
	}

	/* First check that GEOM_PART is available */
	if (geom_class_available("PART") != 0) {
		grq = gctl_get_handle();
		gctl_ro_param(grq, "class", -1, "PART");
		gctl_ro_param(grq, "arg0", -1, pname);
		gctl_ro_param(grq, "verb", -1, "bootcode");
		gctl_ro_param(grq, "bootcode", mbr_size, mbr);
		gctl_ro_param(grq, "flags", -1, "C");
		errmsg = gctl_issue(grq);
		if (errmsg != NULL && errmsg[0] != '\0')
			errx(1, "GEOM_PART: write bootcode to %s failed: %s",
			    fname, errmsg);
		gctl_free(grq);
	} else if (geom_class_available("MBR") != 0) {
		grq = gctl_get_handle();
		gctl_ro_param(grq, "verb", -1, "write MBR");
		gctl_ro_param(grq, "class", -1, "MBR");
		gctl_ro_param(grq, "geom", -1, pname);
		gctl_ro_param(grq, "data", mbr_size, mbr);
		errmsg = gctl_issue(grq);
		if (errmsg != NULL)
			err(1, "GEOM_MBR: write MBR to %s failed", fname);
		gctl_free(grq);
	} else
		errx(1, "can't write MBR to %s", fname);
	free(pname);
}