static errval_t write_file(struct dirent *root, const char *path, uint8_t *data, size_t len) { errval_t err; assert(path != NULL); assert(root != NULL); // walk path, creating/locating directories as we go struct dirent *d = root; while (true) { // remove any leading / while (path[0] == '/') { path++; } char *nextsep = strchr(path, '/'); // no more /, we have the filename if (nextsep == NULL) { break; } // extract dirname, advance path size_t namelen = nextsep - path; char *dirname = malloc(namelen + 1); assert(dirname != NULL); memcpy(dirname, path, namelen); dirname[namelen] = '\0'; path += namelen; // does this directory exist? struct dirent *next; err = ramfs_lookup(d, dirname, &next); if (err_is_ok(err)) { free(dirname); d = next; continue; } else if (err_no(err) != FS_ERR_NOTFOUND) { free(dirname); return err; } // create the directory err = ramfs_mkdir(d, dirname, &next); if (err_is_fail(err)) { free(dirname); return err; } d = next; } // create the file! struct dirent *f; char *path_copy = strdup(path); assert(path_copy != NULL); err = ramfs_create(d, path_copy, &f); if (err_is_fail(err)) { free(path_copy); return err; } // allocate storage uint8_t *buf; err = ramfs_grow(f, 0, len, &buf); if (err_is_fail(err)) { ramfs_delete(f); return err; } // copy the payload memcpy(buf, data, len); return SYS_ERR_OK; }
static void populate_multiboot(struct dirent *root, struct bootinfo *bi) { lvaddr_t data; size_t len; errval_t err; assert(root != NULL); // create bootscript file struct dirent *bootscript_f; err = ramfs_create(root, BOOTSCRIPT_FILE_NAME, &bootscript_f); if (err_is_fail(err)) { USER_PANIC_ERR(err, "error creating bootscript file"); } debug_printf("pre-populating from boot image...\n"); for (int i = 0; i < bi->regions_length; i++) { struct mem_region *region = &bi->regions[i]; if (region->mr_type != RegionType_Module) { /* Not of module type */ continue; } const char *name = remove_prefix(multiboot_module_name(region)); // is this a ramfs image we should unpack? if (strstr(name, "_ramfs.cpio.gz") != NULL) { debug_printf("unpacking Gzipped CPIO %s\n", name); err = spawn_map_module(region, &len, &data, NULL); if (err_is_fail(err)) { USER_PANIC_ERR(err, "error in spawn_map_module"); } err = unpack_cpiogz(root, (void *)data, len); if (err_is_fail(err)) { USER_PANIC_ERR(err, "error unpacking ramfs image"); } // TODO: unmap } else if (strstr(name, "_ramfs.cpio") != NULL) { debug_printf("unpacking CPIO %s\n", name); err = spawn_map_module(region, &len, &data, NULL); if (err_is_fail(err)) { USER_PANIC_ERR(err, "error in spawn_map_module"); } err = unpack_cpio(root, (void *)data, len); if (err_is_fail(err)) { USER_PANIC_ERR(err, "error unpacking ramfs image"); } // TODO: unmap } else { // map the image err = getimage(region, &len, &data); if (err_is_fail(err)) { USER_PANIC_ERR(err, "error in getimage"); } // copy to ramfs err = write_file(root, name, (void *)data, len); if (err_is_fail(err)) { if (err_no(err) == FS_ERR_EXISTS) { debug_printf("%s already exists, skipping it\n", name); } else { USER_PANIC_ERR(err, "error in write_file"); } } // TODO: unmap // append line to bootscript const char *args = remove_prefix(multiboot_module_rawstring(region)); err = append_to_file(bootscript_f, args); if (err_is_fail(err)) { USER_PANIC_ERR(err, "error appending to bootscript"); } } } debug_printf("ready\n"); }
static int ramfs_mkdir(struct device_d *dev, const char *pathname) { return ramfs_create(dev, pathname, S_IFDIR | S_IRWXU | S_IRWXG | S_IRWXO); }