Beispiel #1
0
/*
 * Return the boot0 version with the minor revision in the low byte, and
 * the major revision in the next higher byte.
 */
static int
boot0version(const u_int8_t *bs)
{
    /* Check for old version, and return 0x100 if found. */
    int v = boot0bs(bs);
    if (v != 0)
        return v << 8;

    /* We have a newer boot0, so extract the version number and return it. */
    return *(const int *)(bs + OFF_VERSION) & 0xffff;
}
Beispiel #2
0
/*
 * Read in the MBR of the disk.  If it is boot0, then use the version to
 * read in all of it if necessary.  Use pointers to return a malloc'd
 * buffer containing the MBR and then return its size.
 */
static int
read_mbr(const char *disk, u_int8_t **mbr, int check_version)
{
    u_int8_t buf[MBRSIZE];
    int mbr_size, fd;
    int ver;
    ssize_t n;

    if ((fd = open(disk, O_RDONLY)) == -1)
        err(1, "open %s", disk);
    if ((n = read(fd, buf, MBRSIZE)) == -1)
        err(1, "read %s", disk);
    if (n != MBRSIZE)
        errx(1, "%s: short read", disk);
    if (cv2(buf + OFF_MAGIC) != 0xaa55)
        errx(1, "%s: bad magic", disk);

    if (! (ver = boot0bs(buf))) {
	if (check_version)
	    errx(1, "%s: unknown or incompatible boot code", disk);
    } else if (boot0version(buf) == 0x101) {
	mbr_size = 1024;
	if ((*mbr = malloc(mbr_size)) == NULL)
	    errx(1, "%s: unable to allocate read buffer", disk);
	if (lseek(fd, 0, SEEK_SET) == -1 ||
	    (n = read(fd, *mbr, mbr_size)) == -1)
	    err(1, "%s", disk);
	if (n != mbr_size)
	    errx(1, "%s: short read", disk);
	close(fd);
	return (mbr_size);
    }
    *mbr = malloc(sizeof(buf));
    if (*mbr == NULL)
	errx(1, "%s: unable to allocate MBR buffer", disk);
    memcpy(*mbr, buf, sizeof(buf));
    close(fd);

    return sizeof(buf);
}