/* * VAS_EBOOT -- GRand Unified Bootloader * Copyright (C) 2013 Free Software Foundation, Inc. * * VAS_EBOOT is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * VAS_EBOOT is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with VAS_EBOOT. If not, see . */ #include #include #include #include #include #include #include VAS_EBOOT_MOD_LICENSE ("GPLv3+"); struct VasEBoot_procfs_entry *VasEBoot_procfs_entries; static int VasEBoot_procdev_iterate (VasEBoot_disk_dev_iterate_hook_t hook, void *hook_data, VasEBoot_disk_pull_t pull) { if (pull != VAS_EBOOT_DISK_PULL_NONE) return 0; return hook ("proc", hook_data); } static VasEBoot_err_t VasEBoot_procdev_open (const char *name, VasEBoot_disk_t disk) { if (VasEBoot_strcmp (name, "proc")) return VasEBoot_error (VAS_EBOOT_ERR_UNKNOWN_DEVICE, "not a procfs disk"); disk->total_sectors = 0; disk->id = 0; disk->data = 0; return VAS_EBOOT_ERR_NONE; } static void VasEBoot_procdev_close (VasEBoot_disk_t disk __attribute((unused))) { } static VasEBoot_err_t VasEBoot_procdev_read (VasEBoot_disk_t disk __attribute((unused)), VasEBoot_disk_addr_t sector __attribute((unused)), VasEBoot_size_t size __attribute((unused)), char *buf __attribute((unused))) { return VAS_EBOOT_ERR_OUT_OF_RANGE; } static VasEBoot_err_t VasEBoot_procdev_write (VasEBoot_disk_t disk __attribute ((unused)), VasEBoot_disk_addr_t sector __attribute ((unused)), VasEBoot_size_t size __attribute ((unused)), const char *buf __attribute ((unused))) { return VAS_EBOOT_ERR_OUT_OF_RANGE; } struct VasEBoot_archelp_data { struct VasEBoot_procfs_entry *entry, *next_entry; }; static void VasEBoot_procfs_rewind (struct VasEBoot_archelp_data *data) { data->entry = NULL; data->next_entry = VasEBoot_procfs_entries; } static VasEBoot_err_t VasEBoot_procfs_find_file (struct VasEBoot_archelp_data *data, char **name, VasEBoot_int32_t *mtime, VasEBoot_uint32_t *mode) { data->entry = data->next_entry; if (!data->entry) { *mode = VAS_EBOOT_ARCHELP_ATTR_END; return VAS_EBOOT_ERR_NONE; } data->next_entry = data->entry->next; *mode = VAS_EBOOT_ARCHELP_ATTR_FILE | VAS_EBOOT_ARCHELP_ATTR_NOTIME; *name = VasEBoot_strdup (data->entry->name); *mtime = 0; if (!*name) return VasEBoot_errno; return VAS_EBOOT_ERR_NONE; } static struct VasEBoot_archelp_ops arcops = { .find_file = VasEBoot_procfs_find_file, .rewind = VasEBoot_procfs_rewind }; static VasEBoot_ssize_t VasEBoot_procfs_read (VasEBoot_file_t file, char *buf, VasEBoot_size_t len) { char *data = file->data; VasEBoot_memcpy (buf, data + file->offset, len); return len; } static VasEBoot_err_t VasEBoot_procfs_close (VasEBoot_file_t file) { char *data; data = file->data; VasEBoot_free (data); return VAS_EBOOT_ERR_NONE; } static VasEBoot_err_t VasEBoot_procfs_dir (VasEBoot_device_t device, const char *path, VasEBoot_fs_dir_hook_t hook, void *hook_data) { struct VasEBoot_archelp_data data; /* Check if the disk is our dummy disk. */ if (VasEBoot_strcmp (device->disk->name, "proc")) return VasEBoot_error (VAS_EBOOT_ERR_BAD_FS, "not a procfs"); VasEBoot_procfs_rewind (&data); return VasEBoot_archelp_dir (&data, &arcops, path, hook, hook_data); } static VasEBoot_err_t VasEBoot_procfs_open (struct VasEBoot_file *file, const char *path) { VasEBoot_err_t err; struct VasEBoot_archelp_data data; VasEBoot_size_t sz; VasEBoot_procfs_rewind (&data); err = VasEBoot_archelp_open (&data, &arcops, path); if (err) return err; file->data = data.entry->get_contents (&sz); if (!file->data) return VasEBoot_errno; file->size = sz; return VAS_EBOOT_ERR_NONE; } static struct VasEBoot_disk_dev VasEBoot_procfs_dev = { .name = "proc", .id = VAS_EBOOT_DISK_DEVICE_PROCFS_ID, .disk_iterate = VasEBoot_procdev_iterate, .disk_open = VasEBoot_procdev_open, .disk_close = VasEBoot_procdev_close, .disk_read = VasEBoot_procdev_read, .disk_write = VasEBoot_procdev_write, .next = 0 }; static struct VasEBoot_fs VasEBoot_procfs_fs = { .name = "procfs", .fs_dir = VasEBoot_procfs_dir, .fs_open = VasEBoot_procfs_open, .fs_read = VasEBoot_procfs_read, .fs_close = VasEBoot_procfs_close, .next = 0 }; VAS_EBOOT_MOD_INIT (procfs) { VasEBoot_procfs_fs.mod = mod; VasEBoot_disk_dev_register (&VasEBoot_procfs_dev); VasEBoot_fs_register (&VasEBoot_procfs_fs); } VAS_EBOOT_MOD_FINI (procfs) { VasEBoot_disk_dev_unregister (&VasEBoot_procfs_dev); VasEBoot_fs_unregister (&VasEBoot_procfs_fs); }