static int open_maybe_packaged(BootVolume& volume, const char* path, int openMode) { if (strncmp(path, kSystemDirectoryPrefix, strlen(kSystemDirectoryPrefix)) == 0) { path += strlen(kSystemDirectoryPrefix); return open_from(volume.SystemDirectory(), path, openMode); } return open_from(volume.RootDirectory(), path, openMode); }
status_t load_driver_settings(stage2_args* /*args*/, Directory* volume) { int fd = open_from(volume, "home/config/settings/kernel/drivers", O_RDONLY); if (fd < B_OK) return fd; Directory* settings = (Directory*)get_node_from(fd); if (settings == NULL) return B_ENTRY_NOT_FOUND; void* cookie; if (settings->Open(&cookie, O_RDONLY) == B_OK) { char name[B_FILE_NAME_LENGTH]; while (settings->GetNextEntry(cookie, name, sizeof(name)) == B_OK) { if (!strcmp(name, ".") || !strcmp(name, "..")) continue; status_t status = load_driver_settings_file(settings, name); if (status != B_OK) dprintf("Could not load \"%s\" error %ld\n", name, status); } settings->Close(cookie); } return B_OK; }
Node * Directory::Lookup(const char *name, bool traverseLinks) { off_t id; if (fTree.Find((uint8 *)name, strlen(name), &id) < B_OK) return NULL; Node *node = Stream::NodeFactory(fStream.GetVolume(), id); if (!node) return NULL; if (S_ISLNK(node->Type())) { // the node is a symbolic link, so we have to resolve the path char linkPath[B_PATH_NAME_LENGTH]; ((Link *)node)->ReadLink(linkPath, sizeof(linkPath)); delete node; // we don't need this one anymore int fd = open_from(this, linkPath, O_RDONLY); if (fd >= 0) { node = get_node_from(fd); if (node != NULL) node->Acquire(); close(fd); return node; } return NULL; } return node; }
static status_t load_modules_from(Directory *volume, const char *path) { // we don't have readdir() & co. (yet?)... int fd = open_from(volume, path, O_RDONLY); if (fd < B_OK) return fd; Directory *modules = (Directory *)get_node_from(fd); if (modules == NULL) return B_ENTRY_NOT_FOUND; void *cookie; if (modules->Open(&cookie, O_RDONLY) == B_OK) { char name[B_FILE_NAME_LENGTH]; while (modules->GetNextEntry(cookie, name, sizeof(name)) == B_OK) { if (!strcmp(name, ".") || !strcmp(name, "..")) continue; status_t status = elf_load_image(modules, name); if (status != B_OK) dprintf("Could not load \"%s\" error %ld\n", name, status); } modules->Close(cookie); } return B_OK; }
::Node* TarFS::Directory::Lookup(const char* name, bool traverseLinks) { TarFS::Entry* entry = LookupEntry(name); if (!entry) return NULL; Node* node = entry->ToNode(); if (traverseLinks) { if (S_ISLNK(node->Type())) { Symlink* symlink = static_cast<Symlink*>(node); int fd = open_from(this, symlink->LinkPath(), O_RDONLY); if (fd >= 0) { node = get_node_from(fd); close(fd); } } } if (node) node->Acquire(); return node; }
status_t load_kernel(stage2_args *args, Directory *volume) { int fd = open_from(volume, KERNEL_PATH, O_RDONLY); if (fd < B_OK) return fd; dprintf("load kernel...\n"); elf_init(); status_t status = elf_load_image(fd, &gKernelArgs.kernel_image); close(fd); if (status < B_OK) { dprintf("loading kernel failed: %lx!\n", status); return status; } status = elf_relocate_image(&gKernelArgs.kernel_image); if (status < B_OK) { dprintf("relocating kernel failed: %lx!\n", status); return status; } gKernelArgs.kernel_image.name = kernel_args_strdup(KERNEL_IMAGE); return B_OK; }
static status_t load_module(Directory *volume, const char *name) { char moduleName[B_FILE_NAME_LENGTH]; if (strlcpy(moduleName, name, sizeof(moduleName)) > sizeof(moduleName)) return B_NAME_TOO_LONG; for (int32 i = 0; sAddonPaths[i]; i++) { // get base path int baseFD = open_from(volume, sAddonPaths[i], O_RDONLY); if (baseFD < B_OK) continue; Directory *base = (Directory *)get_node_from(baseFD); if (base == NULL) { close(baseFD); continue; } while (true) { int fd = open_from(base, moduleName, O_RDONLY); if (fd >= B_OK) { struct stat stat; if (fstat(fd, &stat) != 0 || !S_ISREG(stat.st_mode)) return B_BAD_VALUE; status_t status = elf_load_image(base, moduleName); close(fd); close(baseFD); return status; } // cut off last name element (or stop trying if there are no more) char *last = strrchr(moduleName, '/'); if (last != NULL) last[0] = '\0'; else break; } close(baseFD); } return B_OK; }
static status_t save_previous_syslog_to_volume(Directory* directory) { // find an unused name char name[16]; bool found = false; for (int i = 0; i < 99; i++) { snprintf(name, sizeof(name), "SYSLOG%02d.TXT", i); Node* node = directory->Lookup(name, false); if (node == NULL) { found = true; break; } node->Release(); } if (!found) { printf("Failed to find an unused name for the syslog file!\n"); return B_ERROR; } printf("Writing syslog to file \"%s\" ...\n", name); int fd = open_from(directory, name, O_RDWR | O_CREAT | O_EXCL, 0644); if (fd < 0) { printf("Failed to create syslog file!\n"); return fd; } ring_buffer* syslogBuffer = (ring_buffer*)gKernelArgs.debug_output.Pointer(); iovec vecs[2]; int32 vecCount = ring_buffer_get_vecs(syslogBuffer, vecs); if (vecCount > 0) { size_t toWrite = ring_buffer_readable(syslogBuffer); ssize_t written = writev(fd, vecs, vecCount); if (written < 0 || (size_t)written != toWrite) { printf("Failed to write to the syslog file \"%s\"!\n", name); close(fd); return errno; } } close(fd); printf("Successfully wrote syslog file.\n"); return B_OK; }
static int find_kernel(Directory *volume, const char **name = NULL) { for (int32 i = 0; sKernelPaths[i][0] != NULL; i++) { int fd = open_from(volume, sKernelPaths[i][0], O_RDONLY); if (fd >= 0) { if (name) *name = sKernelPaths[i][1]; return fd; } } return B_ENTRY_NOT_FOUND; }
bool is_bootable(Directory *volume) { if (volume->IsEmpty()) return false; // check for the existance of a kernel (for our platform) int fd = open_from(volume, KERNEL_PATH, O_RDONLY); if (fd < B_OK) return false; close(fd); return true; }
status_t elf_load_image(Directory *directory, const char *path) { preloaded_image *image; TRACE(("elf_load_image(directory = %p, \"%s\")\n", directory, path)); int fd = open_from(directory, path, O_RDONLY); if (fd < 0) return fd; // check if this file has already been loaded struct stat stat; if (fstat(fd, &stat) < 0) return errno; image = gKernelArgs.preloaded_images; for (; image != NULL; image = image->next) { if (image->inode == stat.st_ino) { // file has already been loaded, no need to load it twice! close(fd); return B_OK; } } // we still need to load it, so do it image = (preloaded_image *)kernel_args_malloc(sizeof(preloaded_image)); if (image == NULL) { close(fd); return B_NO_MEMORY; } status_t status = elf_load_image(fd, image); if (status == B_OK) { image->name = kernel_args_strdup(path); image->inode = stat.st_ino; // insert to kernel args image->next = gKernelArgs.preloaded_images; gKernelArgs.preloaded_images = image; } else kernel_args_free(image); close(fd); return status; }
/*static*/ PackageSettingsItem* PackageSettingsItem::Load(::Directory* systemDirectory, const char* name) { // open the driver settings file const char* settingsFilePath = kSystemSettingsDirectory "/packages" + strlen(kSystemDirectory) + 1; int fd = open_from(systemDirectory, settingsFilePath, B_READ_ONLY, 0); if (fd < 0) return NULL; FileDescriptorCloser fdCloser(fd); // load the driver settings void* settingsHandle = load_driver_settings_file(fd); if (settingsHandle == NULL) return NULL; CObjectDeleter<void, status_t> settingsDeleter(settingsHandle, &unload_driver_settings); const driver_settings* settings = get_driver_settings(settingsHandle); for (int i = 0; i < settings->parameter_count; i++) { const driver_parameter& parameter = settings->parameters[i]; if (strcmp(parameter.name, "Package") != 0 || parameter.value_count < 1 || strcmp(parameter.values[0], name) != 0) { continue; } PackageSettingsItem* settingsItem = new(std::nothrow) PackageSettingsItem; if (settingsItem == NULL || settingsItem->Init(parameter) != B_OK) { delete settingsItem; return NULL; } return settingsItem; } return NULL; }
static status_t load_driver_settings_file(Directory* directory, const char* name) { int fd = open_from(directory, name, O_RDONLY); if (fd < 0) return fd; struct stat stat; if (fstat(fd, &stat) < 0) return errno; char* buffer = (char*)kernel_args_malloc(stat.st_size + 1); if (buffer == NULL) return B_NO_MEMORY; if (read(fd, buffer, stat.st_size) != stat.st_size) return B_IO_ERROR; driver_settings_file* file = (driver_settings_file*)kernel_args_malloc( sizeof(driver_settings_file)); if (file == NULL) { kernel_args_free(buffer); return B_NO_MEMORY; } buffer[stat.st_size] = '\0'; // null terminate the buffer strlcpy(file->name, name, sizeof(file->name)); file->buffer = buffer; file->size = stat.st_size; // add it to the list file->next = gKernelArgs.driver_settings; gKernelArgs.driver_settings = file; return B_OK; }