fprintf(stderr, "using MBR partition %d: "
fprintf(stderr, "using MBR partition %ld: "
main(argc, argv)	int argc;	char *argv[];{	int	c;	int	devfd;	char	*protostore;	long	protosize;	struct stat sb;	struct disklabel dl;	struct dos_mbr mbr;	struct dos_partition *dp;	off_t startoff = 0;	int mib[4], size;	dev_t devno;	bios_diskinfo_t di;	nsectors = nheads = -1;	while ((c = getopt(argc, argv, "vnh:s:")) != -1) {		switch (c) {		case 'h':			nheads = atoi(optarg);			userspec = 1;			break;		case 's':			nsectors = atoi(optarg);			userspec = 1;			break;		case 'n':			/* Do not actually write the bootblock to disk */			nowrite = 1;			break;		case 'v':			/* Chat */			verbose = 1;			break;		default:			usage();		}	}	if (argc - optind < 3) {		usage();	}	boot = argv[optind];	proto = argv[optind + 1];	realdev = dev = argv[optind + 2];	/* Open and check raw disk device */	if ((devfd = opendev(dev, (nowrite? O_RDONLY:O_RDWR),			     OPENDEV_PART, &realdev)) < 0)		err(1, "open: %s", realdev);	if (verbose) {		fprintf(stderr, "boot: %s\n", boot);		fprintf(stderr, "proto: %s\n", proto);		fprintf(stderr, "device: %s\n", realdev);	}	if (ioctl(devfd, DIOCGDINFO, &dl) != 0)		err(1, "disklabel: %s", realdev);	/* check disklabel */	if (dl.d_magic != DISKMAGIC)		err(1, "bad disklabel magic=%0x8x", dl.d_magic);	/* warn on unknown disklabel types */	if (dl.d_type == 0)		warnx("disklabel type unknown");	/* Load proto blocks into core */	if ((protostore = loadprotoblocks(proto, &protosize)) == NULL)		exit(1);	/* XXX - Paranoia: Make sure size is aligned! */	if (protosize & (DEV_BSIZE - 1))		err(1, "proto bootblock bad size=%ld", protosize);	/* Write patched proto bootblocks into the superblock */	if (protosize > SBSIZE - DEV_BSIZE)		errx(1, "proto bootblocks too big");	if (fstat(devfd, &sb) < 0)		err(1, "stat: %s", realdev);	if (!S_ISCHR(sb.st_mode))		errx(1, "%s: Not a character device", realdev);	if (nheads == -1 || nsectors == -1) {		mib[0] = CTL_MACHDEP;		mib[1] = CPU_CHR2BLK;		mib[2] = sb.st_rdev;		size = sizeof(devno);		if(sysctl(mib, 3, &devno, &size, NULL, 0) >= 0) {			devno = MAKEBOOTDEV(major(devno), 0, 0,			    DISKUNIT(devno), RAW_PART);			mib[0] = CTL_MACHDEP;			mib[1] = CPU_BIOS;			mib[2] = BIOS_DISKINFO;			mib[3] = devno;			size = sizeof(di);			if(sysctl(mib, 4, &di, &size, NULL, 0) >= 0) {				nheads = di.bios_heads;				nsectors = di.bios_sectors;			}		}	}	if (nheads == -1 || nsectors == -1)		errx(1, "Unable to get BIOS geometry, must specify -h and -s");	/* Extract and load block numbers */	if (loadblocknums(boot, devfd, &dl) != 0)		exit(1);	/* Sync filesystems (to clean in-memory superblock?) */	sync(); sleep(1);	if (dl.d_type != 0 && dl.d_type != DTYPE_FLOPPY &&	    dl.d_type != DTYPE_VND) {		if (lseek(devfd, (off_t)DOSBBSECTOR, SEEK_SET) < 0 ||		    read(devfd, &mbr, sizeof(mbr)) < sizeof(mbr))			err(4, "can't read master boot record");		if (mbr.dmbr_sign != DOSMBR_SIGNATURE)			errx(1, "broken MBR");		/* Find OpenBSD partition. */		for (dp = mbr.dmbr_parts; dp < &mbr.dmbr_parts[NDOSPART]; dp++) {			if (dp->dp_size && dp->dp_typ == DOSPTYP_OPENBSD) {				startoff = (off_t)dp->dp_start * dl.d_secsize;				fprintf(stderr, "using MBR partition %d: "					"type %d (0x%02x) offset %d (0x%x)\n",					dp - mbr.dmbr_parts,					dp->dp_typ, dp->dp_typ,					dp->dp_start, dp->dp_start);				break;			}		}		/* don't check for old part number, that is ;-p */		if (dp >= &mbr.dmbr_parts[NDOSPART])			errx(1, "no OpenBSD partition");	}	if (!nowrite) {		if (lseek(devfd, startoff, SEEK_SET) < 0 ||		    write(devfd, protostore, protosize) != protosize)			err(1, "write bootstrap");	}	(void)close(devfd);	return 0;}