/* Fills in list of modules if this is the line we want. */ static int add_modules_dep_line(char *line, const char *name, struct list_head *list, const char *dirname) { char *ptr; int len; char *modname, *fullpath; /* Ignore lines without : or which start with a # */ ptr = strchr(line, ':'); if (ptr == NULL || line[strspn(line, "\t ")] == '#') return 0; /* Is this the module we are looking for? */ *ptr = '\0'; modname = my_basename(line); len = strlen(modname); if (strchr(modname, '.')) len = strchr(modname, '.') - modname; if (!modname_equal(modname, name, len)) return 0; /* Create the list. */ if ('/' == line[0]) { /* old style deps - absolute path specified */ add_module(line, ptr - line, list); } else { nofail_asprintf(&fullpath, "%s/%s", dirname, line); add_module(fullpath, strlen(dirname) + 1 + (ptr - line), list); free(fullpath); } ptr++; for (;;) { char *dep_start; ptr += strspn(ptr, " \t"); if (*ptr == '\0') break; dep_start = ptr; ptr += strcspn(ptr, " \t"); if ('/' == dep_start[0]) { /* old style deps */ add_module(dep_start, ptr - dep_start, list); } else { nofail_asprintf(&fullpath, "%s/%s", dirname, dep_start); add_module(fullpath, strlen(dirname) + 1 + (ptr - dep_start), list); free(fullpath); } } return 1; }
static void read_depends(const char *dirname, const char *start_name, struct list_head *list) { char *modules_dep_name; char *line; FILE *modules_dep; int done = 0; if (use_binary_indexes) if (read_depends_file(dirname, start_name, list)) return; nofail_asprintf(&modules_dep_name, "%s/%s", dirname, "modules.dep"); modules_dep = fopen(modules_dep_name, "r"); if (!modules_dep) fatal("Could not load %s: %s\n", modules_dep_name, strerror(errno)); /* Stop at first line, as we can have duplicates (eg. symlinks from boot/ */ while (!done && (line = getline_wrapped(modules_dep, NULL)) != NULL) { done = add_modules_dep_line(line, start_name, list, dirname); free(line); } fclose(modules_dep); free(modules_dep_name); }
static int read_depends_file(const char *dirname, const char *start_name, struct list_head *list) { char *modules_dep_name; char *line; struct index_file *modules_dep; nofail_asprintf(&modules_dep_name, "%s/%s", dirname, "modules.dep.bin"); modules_dep = index_file_open(modules_dep_name); if (!modules_dep) { free(modules_dep_name); return 0; } line = index_search(modules_dep, start_name); if (line) { /* Value is standard dependency line format */ if (!add_modules_dep_line(line, start_name, list, dirname)) fatal("Module index is inconsistent\n"); free(line); } index_file_close(modules_dep); free(modules_dep_name); return 1; }
static struct elf_file *grab_module(const char *name, const char *kernel, const char *basedir) { char *data; unsigned long size; struct utsname buf; char *depname, *p, *moddir; struct elf_file *module; if (strchr(name, '.') || strchr(name, '/')) { module = grab_elf_file(name); if (!module) error("modinfo: could not open %s: %s\n", name, strerror(errno)); return module; } if (!kernel) { uname(&buf); kernel = buf.release; } if (strlen(basedir)) nofail_asprintf(&moddir, "%s/%s/%s", basedir, MODULE_DIR, kernel); else nofail_asprintf(&moddir, "%s/%s", MODULE_DIR, kernel); /* Search for it in modules.dep. */ nofail_asprintf(&depname, "%s/%s", moddir, "modules.dep"); data = grab_file(depname, &size); if (!data) { error("modinfo: could not open %s\n", depname); free(depname); return NULL; } free(depname); for (p = data; p < data + size; p = next_line(p, data + size)) { if (name_matches(p, data + size, name)) { int namelen = strcspn(p, ":"); const char *dir; char *filename; if ('/' == p[0]) dir = basedir; /* old style deps - abs. path */ else dir = moddir; /* new style - relative path */ if (strlen(dir)) { nofail_asprintf(&filename, "%s/%s", dir, p); filename[namelen + strlen(dir) + 1] = '\0'; } else { filename = strndup(p, namelen); } release_file(data, size); module = grab_elf_file(filename); if (!module) error("modinfo: could not open %s: %s\n", filename, strerror(errno)); free(filename); return module; } } release_file(data, size); error("modinfo: could not find module %s\n", name); return NULL; }