static int kmod_config_parse_kcmdline(struct kmod_config *config) { char buf[KCMD_LINE_SIZE]; int fd, err; char *p, *modname, *param = NULL, *value = NULL; fd = open("/proc/cmdline", O_RDONLY|O_CLOEXEC); if (fd < 0) { err = -errno; DBG(config->ctx, "could not open '/proc/cmdline' for reading: %m\n"); return err; } err = read_str_safe(fd, buf, sizeof(buf)); close(fd); if (err < 0) { ERR(config->ctx, "could not read from '/proc/cmdline': %s\n", strerror(-err)); return err; } for (p = buf, modname = buf; *p != '\0' && *p != '\n'; p++) { switch (*p) { case ' ': *p = '\0'; kcmdline_parse_result(config, modname, param, value); param = value = NULL; modname = p + 1; break; case '.': if (param == NULL) { *p = '\0'; param = p + 1; } break; case '=': if (param != NULL) value = p + 1; break; } } *p = '\0'; kcmdline_parse_result(config, modname, param, value); return 0; }
int read_str_ulong(int fd, unsigned long *value, int base) { char buf[32], *end; long v; int err; *value = 0; err = read_str_safe(fd, buf, sizeof(buf)); if (err < 0) return err; errno = 0; v = strtoul(buf, &end, base); if (end == buf || !isspace(*end)) return -EINVAL; *value = v; return 0; }
struct kmod_file *kmod_file_open(const struct kmod_ctx *ctx, const char *filename) { struct kmod_file *file = calloc(1, sizeof(struct kmod_file)); const struct comp_type *itr; size_t magic_size_max = 0; int err; if (file == NULL) return NULL; file->fd = open(filename, O_RDONLY|O_CLOEXEC); if (file->fd < 0) { err = -errno; goto error; } for (itr = comp_types; itr->ops.load != NULL; itr++) { if (magic_size_max < itr->magic_size) magic_size_max = itr->magic_size; } file->direct = false; if (magic_size_max > 0) { char *buf = alloca(magic_size_max + 1); ssize_t sz; if (buf == NULL) { err = -errno; goto error; } sz = read_str_safe(file->fd, buf, magic_size_max + 1); lseek(file->fd, 0, SEEK_SET); if (sz != (ssize_t)magic_size_max) { if (sz < 0) err = sz; else err = -EINVAL; goto error; } for (itr = comp_types; itr->ops.load != NULL; itr++) { if (memcmp(buf, itr->magic_bytes, itr->magic_size) == 0) break; } if (itr->ops.load != NULL) file->ops = &itr->ops; } if (file->ops == NULL) file->ops = ®_ops; err = file->ops->load(file); file->ctx = ctx; error: if (err < 0) { if (file->fd >= 0) close(file->fd); free(file); errno = -err; return NULL; } return file; }