예제 #1
0
파일: mbr.c 프로젝트: enukane/openbsd-work
/*
 * Parse the MBR partition table into 'mbr', leaving the rest of 'mbr'
 * untouched.
 */
void
MBR_pcopy(struct disk *disk, struct mbr *mbr)
{
	int i, fd, error;
	struct dos_mbr dos_mbr;

	fd = DISK_open(disk->name, O_RDONLY);
	error = MBR_read(fd, 0, &dos_mbr);
	close(fd);

	if (error == -1)
		return;

	for (i = 0; i < NDOSPART; i++)
		PRT_parse(disk, &dos_mbr.dmbr_parts[i], 0, 0, &mbr->part[i]);
}
예제 #2
0
int
main(int argc, char *argv[])
{
	int ch, fd, error;
	int i_flag = 0, m_flag = 0, u_flag = 0;
	int c_arg = 0, h_arg = 0, s_arg = 0;
	struct disk disk;
	u_int32_t l_arg = 0;
#ifdef HAS_MBR
	char *mbrfile = _PATH_MBR;
#else
	char *mbrfile = NULL;
#endif
	struct mbr mbr;
	struct dos_mbr dos_mbr;

	while ((ch = getopt(argc, argv, "ieuf:c:h:s:l:y")) != -1) {
		const char *errstr;

		switch(ch) {
		case 'i':
			i_flag = 1;
			break;
		case 'u':
			u_flag = 1;
			break;
		case 'e':
			m_flag = 1;
			break;
		case 'f':
			mbrfile = optarg;
			break;
		case 'c':
			c_arg = strtonum(optarg, 1, 262144, &errstr);
			if (errstr)
				errx(1, "Cylinder argument %s [1..262144].",
				    errstr);
			break;
		case 'h':
			h_arg = strtonum(optarg, 1, 256, &errstr);
			if (errstr)
				errx(1, "Head argument %s [1..256].", errstr);
			break;
		case 's':
			s_arg = strtonum(optarg, 1, 63, &errstr);
			if (errstr)
				errx(1, "Sector argument %s [1..63].", errstr);
			break;
		case 'l':
			l_arg = strtonum(optarg, 64, UINT32_MAX, &errstr);
			if (errstr)
				errx(1, "Block argument %s [64..%u].", errstr,
				    UINT32_MAX);
			break;
		case 'y':
			y_flag = 1;
			break;
		default:
			usage();
		}
	}
	argc -= optind;
	argv += optind;

	memset(&disk, 0, sizeof(disk));

	/* Argument checking */
	if (argc != 1)
		usage();
	else
		disk.name = argv[0];

	/* Start with the disklabel geometry and get the sector size. */
	DISK_getlabelgeometry(&disk);

	if (c_arg | h_arg | s_arg) {
		/* Use supplied geometry if it is completely specified. */
		if (c_arg && h_arg && s_arg) {
			disk.cylinders = c_arg;
			disk.heads = h_arg;
			disk.sectors = s_arg;
			disk.size = c_arg * h_arg * s_arg;
		} else
			errx(1, "Please specify a full geometry with [-chs].");
	} else if (l_arg) {
		/* Use supplied size to calculate a geometry. */
		disk.cylinders = l_arg / 64;
		disk.heads = 1;
		disk.sectors = 64;
		disk.size = l_arg;
	}

	if (disk.size == 0 || disk.cylinders == 0 || disk.heads == 0 ||
	    disk.sectors == 0 || unit_types[SECTORS].conversion == 0)
		errx(1, "Can't get disk geometry, please use [-chs] "
		    "to specify.");

	/* Print out current MBRs on disk */
	if ((i_flag + u_flag + m_flag) == 0)
		exit(USER_print_disk(&disk));

	/* Parse mbr template, to pass on later */
	if (mbrfile != NULL && (fd = open(mbrfile, O_RDONLY)) == -1) {
		warn("%s", mbrfile);
		warnx("using builtin MBR");
		mbrfile = NULL;
	}
	if (mbrfile == NULL) {
		memcpy(&dos_mbr, builtin_mbr, sizeof(dos_mbr));
	} else {
		error = MBR_read(fd, 0, &dos_mbr);
		if (error == -1)
			err(1, "Unable to read MBR");
		close(fd);
	}
	MBR_parse(&disk, &dos_mbr, 0, 0, &mbr);

	/* Now do what we are supposed to */
	if (i_flag || u_flag)
		if (USER_init(&disk, &mbr, u_flag) == -1)
			err(1, "error initializing MBR");

	if (m_flag)
		USER_modify(&disk, &mbr, 0, 0);

	return (0);
}