Newer
Older
vvd / src / vvd.c
@dd86k dd86k on 9 Nov 2019 3 KB INIT
/**
 * Main vvd operations
 */
#include <assert.h>
#include <string.h> // memcpy
#include <inttypes.h>
#include "vvd.h"
#include "utils.h"
#include "fs/mbr.h"

//
// vvd_info
//

int vvd_info(VDISK *vd) {
	switch (vd->format) {
	case VDISK_FORMAT_VDI:
		vdi_info(vd);
		break;
	case VDISK_FORMAT_VMDK:
		vmdk_info(vd);
		break;
	case VDISK_FORMAT_VHD:
		vhd_info(vd);
		break;
	case VDISK_FORMAT_RAW: break; // No header info
	default:
		fputs("vvd_info: Format not supported\n", stderr);
		return ECLIFORMAT;
	}

	mbr_info_auto(vd);
	return EVDOK;
}

//
// vvd_map
//

int vvd_map(VDISK *vd) { //TODO: Add column width
	char bsizestr[BIN_FLENGTH]; // If used
	uint64_t blocksize;
	uint32_t blocksn = vd->u32nblocks;
	uint32_t *blocks = vd->u32blocks;

	switch (vd->format) {
	case VDISK_FORMAT_VHD:
		if (vd->vhd.type != VHD_DISK_DYN) {
			fputs("vvd_map: VHD is not dynamic\n", stderr);
			return EVDTYPE;
		}
		blocksize = vd->vhddyn.blocksize;
		break;
	case VDISK_FORMAT_VDI:
		blocksize = vd->vdi.blocksize;
		blocksn = vd->vdi.totalblocks;
		break;
	default:
		fputs("vvd_map: Unsupported format\n", stderr);
		return EVDFORMAT;
	}

	fbins(blocksize, bsizestr);
	printf(
	"Allocation map (%u blocks at %s)\n"
	"          |        0 |        1 |        2 |        3 |"
	           "        4 |        5 |        6 |        7 |\n"
	"----------+----------+----------+----------+----------+"
	           "----------+----------+----------+----------+\n",
	blocksn, bsizestr
	);
	size_t i = 0;
	size_t bn = blocksn - 8;
	for (; i < bn; i += 8) {
		printf(
		" %8zu | %8X | %8X | %8X | %8X | %8X | %8X | %8X | %8X |\n",
		i,
		blocks[i],     blocks[i + 1],
		blocks[i + 2], blocks[i + 3],
		blocks[i + 4], blocks[i + 5],
		blocks[i + 6], blocks[i + 7]
		);
	}
	if (blocksn - i > 0) { // Left over
		printf(" %8zu |", i);
		for (; i < blocksn; ++i)
			printf(" %8X |", blocks[i]);
		putchar('\n');
	}
	return ECLIOK;
}

//
// vvd_new
//

int vvd_new(VDISK *vd, uint64_t vsize) {
	uint8_t *buffer;

	switch (vd->format) {
	case VDISK_FORMAT_VDI:
		vd->u32nblocks = vsize / vd->vdi.blocksize;
		if (vd->u32nblocks == 0)
			vd->u32nblocks = 1;
		uint32_t bsize = vd->u32nblocks << 2;
		if ((vd->u32blocks = malloc(bsize)) == NULL)
			return ECLIALLOC;
		vd->vdi.totalblocks = vd->u32nblocks;
		vd->vdi.disksize = vsize;
		switch (vd->vdi.type) {
		case VDI_DISK_DYN:
			for (size_t i = 0; i < vd->vdi.totalblocks; ++i)
				vd->u32blocks[i] = VDI_BLOCK_UNALLOCATED;
			break;
		case VDI_DISK_FIXED:
			if ((buffer = malloc(vd->vdi.blocksize)) == NULL)
				return ECLIALLOC;
			os_seek(vd->fd, vd->vdi.offData, SEEK_SET);
			for (size_t i = 0; i < vd->vdi.totalblocks; ++i) {
				vd->u32blocks[i] = VDI_BLOCK_FREE;
				os_write(vd->fd, buffer, vd->vdi.blocksize);
			}
			break;
		default:
			fputs("vvd_new: Type currently unsupported", stderr);
			return EVDTYPE;
		}
		break;
	default:
		fputs("vvd_new: Format currently unsupported", stderr);
		return EVDFORMAT;
	}

L_DISKEMPTY:
	if (vdisk_update_headers(vd)) {
		fputs("vvd_new: Could not write headers\n", stderr);
		return 1;
	}
	return 0;
}

//
// vvd_compact
//

int vvd_compact(VDISK *vd) {
	if (vd->u32nblocks == 0) {
		fputs("vvd_compact: No allocated blocks\n", stderr);
		return EVDMISC;
	}

	switch (vd->format) {
	case VDISK_FORMAT_VDI: return vdi_compact(vd);
	case VDISK_FORMAT_RAW:
		fputs("vvd_compact: RAW files/devices are not supported\n",
			stderr);
		return EVDFORMAT;
	default:
		fputs("vvd_compact: VDISK format not supported\n",
			stderr);
		return EVDFORMAT;
	}

	return 0;
}

//
// vvd_write (file)
//

int vvd_write(VDISK *vd, __OSFILE *fd) {
	
	
	return 0;
}