src/sbin/pdisk/file_media.c

366 lines
12 KiB
C

/* $OpenBSD: file_media.c,v 1.48 2016/01/30 17:21:10 krw Exp $ */
/*
* file_media.c -
*
* Written by Eryk Vershen
*/
/*
* Copyright 1997,1998 by Apple Computer, Inc.
* All Rights Reserved
*
* Permission to use, copy, modify, and distribute this software and
* its documentation for any purpose and without fee is hereby granted,
* provided that the above copyright notice appears in all copies and
* that both the copyright notice and this permission notice appear in
* supporting documentation.
*
* APPLE COMPUTER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL APPLE COMPUTER BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
* NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/param.h> /* DEV_BSIZE */
#include <sys/queue.h>
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "partition_map.h"
#include "file_media.h"
struct ddmap_ondisk {
uint8_t ddBlock[4];
uint8_t ddSize[2];
uint8_t ddType[2];
};
struct block0_ondisk {
uint8_t sbSig[2];
uint8_t sbBlkSize[2];
uint8_t sbBlkCount[4];
uint8_t sbDevType[2];
uint8_t sbDevId[2];
uint8_t sbData[4];
uint8_t sbDrvrCount[2];
uint8_t sbDDMap[64]; /* ddmap_ondisk[8] */
uint8_t reserved[430];
};
struct dpme_ondisk {
uint8_t dpme_signature[2];
uint8_t dpme_reserved_1[2];
uint8_t dpme_map_entries[4];
uint8_t dpme_pblock_start[4];
uint8_t dpme_pblocks[4];
uint8_t dpme_name[DPISTRLEN];
uint8_t dpme_type[DPISTRLEN];
uint8_t dpme_lblock_start[4];
uint8_t dpme_lblocks[4];
uint8_t dpme_flags[4];
uint8_t dpme_boot_block[4];
uint8_t dpme_boot_bytes[4];
uint8_t dpme_load_addr[4];
uint8_t dpme_reserved_2[4];
uint8_t dpme_goto_addr[4];
uint8_t dpme_reserved_3[4];
uint8_t dpme_checksum[4];
uint8_t dpme_processor_id[16];
uint8_t dpme_reserved_4[376];
};
static int read_block(int, uint64_t, void *);
static int write_block(int, uint64_t, void *);
static int
read_block(int fd, uint64_t sector, void *address)
{
ssize_t off;
off = pread(fd, address, DEV_BSIZE, sector * DEV_BSIZE);
if (off == DEV_BSIZE)
return 1;
if (off == 0)
fprintf(stderr, "end of file encountered");
else if (off == -1)
warn("reading file failed");
else
fprintf(stderr, "short read");
return 0;
}
static int
write_block(int fd, uint64_t sector, void *address)
{
ssize_t off;
off = pwrite(fd, address, DEV_BSIZE, sector * DEV_BSIZE);
if (off == DEV_BSIZE)
return 1;
warn("writing to file failed");
return 0;
}
int
read_block0(int fd, struct partition_map *map)
{
struct block0_ondisk *block0_ondisk;
struct ddmap_ondisk ddmap_ondisk;
int i;
block0_ondisk = malloc(sizeof(struct block0_ondisk));
if (block0_ondisk == NULL)
errx(1, "No memory to read block0");
if (read_block(fd, 0, block0_ondisk) == 0)
return 0;
memcpy(&map->sbSig, block0_ondisk->sbSig,
sizeof(map->sbSig));
map->sbSig = betoh16(map->sbSig);
memcpy(&map->sbBlkSize, block0_ondisk->sbBlkSize,
sizeof(map->sbBlkSize));
map->sbBlkSize = betoh16(map->sbBlkSize);
memcpy(&map->sbBlkCount, block0_ondisk->sbBlkCount,
sizeof(map->sbBlkCount));
map->sbBlkCount = betoh32(map->sbBlkCount);
memcpy(&map->sbDevType, block0_ondisk->sbDevType,
sizeof(map->sbDevType));
map->sbDevType = betoh16(map->sbDevType);
memcpy(&map->sbDevId, block0_ondisk->sbDevId,
sizeof(map->sbDevId));
map->sbDevId = betoh16(map->sbDevId);
memcpy(&map->sbData, block0_ondisk->sbData,
sizeof(map->sbData));
map->sbData = betoh32(map->sbData);
memcpy(&map->sbDrvrCount, block0_ondisk->sbDrvrCount,
sizeof(map->sbDrvrCount));
map->sbDrvrCount = betoh16(map->sbDrvrCount);
for (i = 0; i < 8; i++) {
memcpy(&ddmap_ondisk,
map->sbDDMap+i*sizeof(struct ddmap_ondisk),
sizeof(ddmap_ondisk));
memcpy(&map->sbDDMap[i].ddBlock, &ddmap_ondisk.ddBlock,
sizeof(map->sbDDMap[i].ddBlock));
map->sbDDMap[i].ddBlock =
betoh32(map->sbDDMap[i].ddBlock);
memcpy(&map->sbDDMap[i].ddSize, &ddmap_ondisk.ddSize,
sizeof(map->sbDDMap[i].ddSize));
map->sbDDMap[i].ddSize = betoh16(map->sbDDMap[i].ddSize);
memcpy(&map->sbDDMap[i].ddType, &ddmap_ondisk.ddType,
sizeof(map->sbDDMap[i].ddType));
map->sbDDMap[i].ddType = betoh32(map->sbDDMap[i].ddType);
}
free(block0_ondisk);
return 1;
}
int
write_block0(int fd, struct partition_map *map)
{
struct block0_ondisk *block0_ondisk;
struct ddmap_ondisk ddmap_ondisk;
int i, rslt;
uint32_t tmp32;
uint16_t tmp16;
block0_ondisk = malloc(sizeof(struct block0_ondisk));
if (block0_ondisk == NULL)
errx(1, "No memory to write block 0");
tmp16 = htobe16(map->sbSig);
memcpy(block0_ondisk->sbSig, &tmp16,
sizeof(block0_ondisk->sbSig));
tmp16 = htobe16(map->sbBlkSize);
memcpy(block0_ondisk->sbBlkSize, &tmp16,
sizeof(block0_ondisk->sbBlkSize));
tmp32 = htobe32(map->sbBlkCount);
memcpy(block0_ondisk->sbBlkCount, &tmp32,
sizeof(block0_ondisk->sbBlkCount));
tmp16 = htobe16(map->sbDevType);
memcpy(block0_ondisk->sbDevType, &tmp16,
sizeof(block0_ondisk->sbDevType));
tmp16 = htobe16(map->sbDevId);
memcpy(block0_ondisk->sbDevId, &tmp16,
sizeof(block0_ondisk->sbDevId));
tmp32 = htobe32(map->sbData);
memcpy(block0_ondisk->sbData, &tmp32,
sizeof(block0_ondisk->sbData));
tmp16 = htobe16(map->sbDrvrCount);
memcpy(block0_ondisk->sbDrvrCount, &tmp16,
sizeof(block0_ondisk->sbDrvrCount));
for (i = 0; i < 8; i++) {
tmp32 = htobe32(map->sbDDMap[i].ddBlock);
memcpy(ddmap_ondisk.ddBlock, &tmp32,
sizeof(ddmap_ondisk.ddBlock));
tmp16 = htobe16(map->sbDDMap[i].ddSize);
memcpy(&ddmap_ondisk.ddSize, &tmp16,
sizeof(ddmap_ondisk.ddSize));
tmp16 = betoh32(map->sbDDMap[i].ddType);
memcpy(&ddmap_ondisk.ddType, &tmp16,
sizeof(ddmap_ondisk.ddType));
memcpy(map->sbDDMap+i*sizeof(struct ddmap_ondisk),
&ddmap_ondisk, sizeof(ddmap_ondisk));
}
rslt = write_block(fd, 0, block0_ondisk);
free(block0_ondisk);
return rslt;
}
int
read_dpme(int fd, uint64_t sector, struct entry *entry)
{
struct dpme_ondisk *dpme_ondisk;
dpme_ondisk = malloc(sizeof(struct dpme_ondisk));
if (dpme_ondisk == NULL)
errx(1, "No memory to read dpme");
if (read_block(fd, sector, dpme_ondisk) == 0)
return 0;
memcpy(&entry->dpme_signature, dpme_ondisk->dpme_signature,
sizeof(entry->dpme_signature));
memcpy(&entry->dpme_map_entries, dpme_ondisk->dpme_map_entries,
sizeof(entry->dpme_map_entries));
memcpy(&entry->dpme_pblock_start, dpme_ondisk->dpme_pblock_start,
sizeof(entry->dpme_pblock_start));
memcpy(&entry->dpme_pblocks, dpme_ondisk->dpme_pblocks,
sizeof(entry->dpme_pblocks));
memcpy(&entry->dpme_lblock_start, dpme_ondisk->dpme_lblock_start,
sizeof(entry->dpme_lblock_start));
memcpy(&entry->dpme_lblocks, dpme_ondisk->dpme_lblocks,
sizeof(entry->dpme_lblocks));
memcpy(&entry->dpme_flags, dpme_ondisk->dpme_flags,
sizeof(entry->dpme_flags));
memcpy(&entry->dpme_boot_block, dpme_ondisk->dpme_boot_block,
sizeof(entry->dpme_boot_block));
memcpy(&entry->dpme_boot_bytes, dpme_ondisk->dpme_boot_bytes,
sizeof(entry->dpme_boot_bytes));
memcpy(&entry->dpme_load_addr, dpme_ondisk->dpme_load_addr,
sizeof(entry->dpme_load_addr));
memcpy(&entry->dpme_goto_addr, dpme_ondisk->dpme_goto_addr,
sizeof(entry->dpme_goto_addr));
memcpy(&entry->dpme_checksum, dpme_ondisk->dpme_checksum,
sizeof(entry->dpme_checksum));
entry->dpme_signature = betoh16(entry->dpme_signature);
entry->dpme_map_entries = betoh32(entry->dpme_map_entries);
entry->dpme_pblock_start = betoh32(entry->dpme_pblock_start);
entry->dpme_pblocks = betoh32(entry->dpme_pblocks);
entry->dpme_lblock_start = betoh32(entry->dpme_lblock_start);
entry->dpme_lblocks = betoh32(entry->dpme_lblocks);
entry->dpme_flags = betoh32(entry->dpme_flags);
entry->dpme_boot_block = betoh32(entry->dpme_boot_block);
entry->dpme_boot_bytes = betoh32(entry->dpme_boot_bytes);
entry->dpme_load_addr = betoh32(entry->dpme_load_addr);
entry->dpme_goto_addr = betoh32(entry->dpme_goto_addr);
entry->dpme_checksum = betoh32(entry->dpme_checksum);
memcpy(entry->dpme_reserved_1, dpme_ondisk->dpme_reserved_1,
sizeof(entry->dpme_reserved_1));
memcpy(entry->dpme_reserved_2, dpme_ondisk->dpme_reserved_2,
sizeof(entry->dpme_reserved_2));
memcpy(entry->dpme_reserved_3, dpme_ondisk->dpme_reserved_3,
sizeof(entry->dpme_reserved_3));
memcpy(entry->dpme_reserved_4, dpme_ondisk->dpme_reserved_4,
sizeof(entry->dpme_reserved_4));
strlcpy(entry->dpme_name, dpme_ondisk->dpme_name,
sizeof(entry->dpme_name));
strlcpy(entry->dpme_type, dpme_ondisk->dpme_type,
sizeof(entry->dpme_type));
strlcpy(entry->dpme_processor_id, dpme_ondisk->dpme_processor_id,
sizeof(entry->dpme_processor_id));
free(dpme_ondisk);
return 1;
}
int
write_dpme(int fd, uint64_t sector, struct entry *entry)
{
struct dpme_ondisk *dpme_ondisk;
int rslt;
uint32_t tmp32;
uint16_t tmp16;
dpme_ondisk = malloc(sizeof(struct dpme_ondisk));
if (dpme_ondisk == NULL)
errx(1, "No memory to write dpme");
memcpy(dpme_ondisk->dpme_name, entry->dpme_name,
sizeof(dpme_ondisk->dpme_name));
memcpy(dpme_ondisk->dpme_type, entry->dpme_type,
sizeof(dpme_ondisk->dpme_type));
memcpy(dpme_ondisk->dpme_processor_id, entry->dpme_processor_id,
sizeof(dpme_ondisk->dpme_processor_id));
memcpy(dpme_ondisk->dpme_reserved_1, entry->dpme_reserved_1,
sizeof(dpme_ondisk->dpme_reserved_1));
memcpy(dpme_ondisk->dpme_reserved_2, entry->dpme_reserved_2,
sizeof(dpme_ondisk->dpme_reserved_2));
memcpy(dpme_ondisk->dpme_reserved_3, entry->dpme_reserved_3,
sizeof(dpme_ondisk->dpme_reserved_3));
memcpy(dpme_ondisk->dpme_reserved_4, entry->dpme_reserved_4,
sizeof(dpme_ondisk->dpme_reserved_4));
tmp16 = htobe16(entry->dpme_signature);
memcpy(dpme_ondisk->dpme_signature, &tmp16,
sizeof(dpme_ondisk->dpme_signature));
tmp32 = htobe32(entry->dpme_map_entries);
memcpy(dpme_ondisk->dpme_map_entries, &tmp32,
sizeof(dpme_ondisk->dpme_map_entries));
tmp32 = htobe32(entry->dpme_pblock_start);
memcpy(dpme_ondisk->dpme_pblock_start, &tmp32,
sizeof(dpme_ondisk->dpme_pblock_start));
tmp32 = htobe32(entry->dpme_pblocks);
memcpy(dpme_ondisk->dpme_pblocks, &tmp32,
sizeof(dpme_ondisk->dpme_pblocks));
tmp32 = htobe32(entry->dpme_lblock_start);
memcpy(dpme_ondisk->dpme_lblock_start, &tmp32,
sizeof(dpme_ondisk->dpme_lblock_start));
tmp32 = betoh32(entry->dpme_lblocks);
memcpy(dpme_ondisk->dpme_lblocks, &tmp32,
sizeof(dpme_ondisk->dpme_lblocks));
tmp32 = betoh32(entry->dpme_flags);
memcpy(dpme_ondisk->dpme_flags, &tmp32,
sizeof(dpme_ondisk->dpme_flags));
tmp32 = htobe32(entry->dpme_boot_block);
memcpy(dpme_ondisk->dpme_boot_block, &tmp32,
sizeof(dpme_ondisk->dpme_boot_block));
tmp32 = htobe32(entry->dpme_boot_bytes);
memcpy(dpme_ondisk->dpme_boot_bytes, &tmp32,
sizeof(dpme_ondisk->dpme_boot_bytes));
tmp32 = betoh32(entry->dpme_load_addr);
memcpy(dpme_ondisk->dpme_load_addr, &tmp32,
sizeof(dpme_ondisk->dpme_load_addr));
tmp32 = betoh32(entry->dpme_goto_addr);
memcpy(dpme_ondisk->dpme_goto_addr, &tmp32,
sizeof(dpme_ondisk->dpme_goto_addr));
tmp32 = betoh32(entry->dpme_checksum);
memcpy(dpme_ondisk->dpme_checksum, &tmp32,
sizeof(dpme_ondisk->dpme_checksum));
rslt = write_block(fd, sector, dpme_ondisk);
free(dpme_ondisk);
return rslt;
}