int mib[4], size;
int mib[4]; size_t		size;
loadblocknums(boot, devfd, dl)	char	*boot;	int	devfd;	struct disklabel *dl;{	int		i, fd;	struct stat	statbuf, sb;	struct statfs	statfsbuf;	struct partition *pl;	struct fs	*fs;	char		*buf;	daddr_t		blk, *ap;	struct dinode	*ip;	int		ndb;	u_int8_t	*bt;	struct exec	eh;	int mib[4], size;	dev_t dev;	/*	 * Open 2nd-level boot program and record the block numbers	 * it occupies on the filesystem represented by `devfd'.	 */	/* Make sure the (probably new) boot file is on disk. */	sync(); sleep(1);	if ((fd = open(boot, O_RDONLY)) < 0)		err(1, "open: %s", boot);	if (fstatfs(fd, &statfsbuf) != 0)		err(1, "statfs: %s", boot);	if (strncmp(statfsbuf.f_fstypename, "ffs", MFSNAMELEN) &&	    strncmp(statfsbuf.f_fstypename, "ufs", MFSNAMELEN) ) {		errx(1, "%s: must be on an FFS filesystem", boot);	}	if (read(fd, &eh, sizeof(eh)) != sizeof(eh)) {		errx(1, "read: %s", boot);	}	if (N_GETMAGIC(eh) != ZMAGIC) {		errx(1, "%s: bad magic: 0x%x", boot, eh.a_midmag);	}	if (fsync(fd) != 0)		err(1, "fsync: %s", boot);	if (fstat(fd, &statbuf) != 0)		err(1, "fstat: %s", boot);	if (fstat(devfd, &sb) != 0)		err(1, "fstat: %s", realdev);	/* check devices */	mib[0] = CTL_MACHDEP;	mib[1] = CPU_CHR2BLK;	mib[2] = sb.st_rdev;	size = sizeof(dev);	if (sysctl(mib, 3, &dev, &size, NULL, 0) >= 0)		if (statbuf.st_dev / MAXPARTITIONS != dev / MAXPARTITIONS)			errx(1, "cross-device install");	pl = &dl->d_partitions[DISKPART(statbuf.st_dev)];	close(fd);	/* Read superblock */	devread(devfd, sblock, pl->p_offset + SBLOCK, SBSIZE, "superblock");	fs = (struct fs *)sblock;	/* Sanity-check super-block. */	if (fs->fs_magic != FS_MAGIC)		errx(1, "Bad magic number in superblock");	if (fs->fs_inopb <= 0)		err(1, "Bad inopb=%d in superblock", fs->fs_inopb);	/* Read inode */	if ((buf = malloc(fs->fs_bsize)) == NULL)		errx(1, "No memory for filesystem block");	blk = fsbtodb(fs, ino_to_fsba(fs, statbuf.st_ino));	devread(devfd, buf, pl->p_offset + blk, fs->fs_bsize, "inode");	ip = (struct dinode *)(buf) + ino_to_fsbo(fs, statbuf.st_ino);	/*	 * Have the inode.  Figure out how many blocks we need.	 */	ndb = howmany(ip->di_size, fs->fs_bsize);	if (ndb <= 0)		errx(1, "No blocks to load");	if (verbose)		fprintf(stderr, "Will load %d blocks of size %d each.\n",			ndb, fs->fs_bsize);	if ((dl->d_type != 0 && dl->d_type != DTYPE_FLOPPY &&	    dl->d_type != DTYPE_VND) || userspec ) {		/* adjust disklabel w/ synthetic geometry */		dl->d_nsectors = nsectors;		dl->d_secpercyl = dl->d_nsectors * nheads;	}	if (verbose)		fprintf(stderr, "Using disk geometry of %u sectors and %u heads.\n",			dl->d_nsectors, dl->d_secpercyl/dl->d_nsectors);	/*	 * Get the block numbers; we don't handle fragments	 */	ap = ip->di_db;	bt = block_table_p;	for (i = 0; i < NDADDR && *ap && ndb; i++, ap++, ndb--) {		bt += record_block(bt, pl->p_offset + fsbtodb(fs, *ap),					    fs->fs_bsize / 512, dl);		if ((bt - block_table_p) / 4 > maxblocknum)			errx(1, "Too many blocks");	}	if (ndb != 0) {		/*		 * Just one level of indirections; there isn't much room		 * for more in the 2nd-level /boot anyway.		 */		blk = fsbtodb(fs, ip->di_ib[0]);		devread(devfd, buf, pl->p_offset + blk, fs->fs_bsize,			"indirect block");		ap = (daddr_t *)buf;		for (; i < NINDIR(fs) && *ap && ndb; i++, ap++, ndb--) {			bt += record_block(bt, pl->p_offset + fsbtodb(fs, *ap),					   fs->fs_bsize / 512, dl);			if ((bt - block_table_p) / 4 > maxblocknum)				errx(1, "Too many blocks");		}	}	/* write out remaining piece */	bt += record_block(bt, 0, 0, dl);	/* and again */	bt += record_block(bt, 0, 0, dl);	*block_count_p = (bt - block_table_p) / 4;	if (*block_count_p > maxblocknum)		errx(1, "Too many blocks");	if (verbose)		fprintf(stderr, "%s: %d entries total\n",			boot, *block_count_p);	return 0;}