#include "tar.h" #include #include #include size_t getsize(const char *in) { size_t size = 0; size_t j; size_t count = 1; for (j = 11; j > 0; j--, count *= 8) { size += ((in[j - 1] - '0') * count); } return size; } int tar_init(struct tar *tar, uintptr_t base) { memset(tar, 0x0, sizeof *tar); tar->tar_entries = (struct tar_bin_header *)base; return 0; } int tar_open(struct tar *tar, const char *path, struct tar_file *out) { while (*path == '/') { path++; } if (*path == '\0') { return -1; } struct tar_bin_header *bin_header = tar->tar_entries; struct tar_header header; for (size_t i = 0;; i++) { tar_header_decode(bin_header, &header); if (bin_header->filename[0] == 0) { break; } char *s = (char *)bin_header; s += sizeof *bin_header; if (!strcmp(bin_header->filename, path)) { out->f_header = header; out->f_data = s; return 0; } s += header.size; s += ((sizeof *bin_header) - ((uintptr_t)s % (sizeof *bin_header))); bin_header = (struct tar_bin_header *)s; } return -1; } int tar_file_create_vm_object(const struct tar_file *file, kern_handle_t *out) { const void *data = file->f_data; size_t len = file->f_header.size; kern_handle_t vmo = KERN_HANDLE_INVALID; kern_status_t status = vm_object_create( NULL, 0, file->f_header.size, VM_PROT_READ | VM_PROT_EXEC | VM_PROT_USER, &vmo); if (status != KERN_OK) { return -1; } size_t nr_written = 0; status = vm_object_write(vmo, data, 0, len, &nr_written); if (status != KERN_OK || nr_written != len) { kern_handle_close(vmo); return -1; } *out = vmo; return 0; } int tar_header_decode(const struct tar_bin_header *in, struct tar_header *out) { memcpy(out->filename, in->filename, sizeof out->filename); out->size = getsize(in->size); return 0; }