aboutsummaryrefslogtreecommitdiff
path: root/tools/depmod.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/depmod.c')
-rw-r--r--tools/depmod.c231
1 files changed, 161 insertions, 70 deletions
diff --git a/tools/depmod.c b/tools/depmod.c
index 3f31cdf..364b7d4 100644
--- a/tools/depmod.c
+++ b/tools/depmod.c
@@ -51,8 +51,9 @@ static int verbose = DEFAULT_VERBOSE;
static const char CFG_BUILTIN_KEY[] = "built-in";
static const char CFG_EXTERNAL_KEY[] = "external";
static const char *default_cfg_paths[] = {
- "/run/depmod.d",
SYSCONFDIR "/depmod.d",
+ "/run/depmod.d",
+ "/usr/local/lib/depmod.d",
"/lib/depmod.d",
NULL
};
@@ -457,6 +458,11 @@ struct cfg_external {
char path[];
};
+struct cfg_exclude {
+ struct cfg_exclude *next;
+ char exclude_dir[];
+};
+
struct cfg {
const char *kversion;
char dirname[PATH_MAX];
@@ -468,6 +474,7 @@ struct cfg {
struct cfg_override *overrides;
struct cfg_search *searches;
struct cfg_external *externals;
+ struct cfg_exclude *excludes;
};
static enum search_type cfg_define_search_type(const char *path)
@@ -579,6 +586,30 @@ static void cfg_external_free(struct cfg_external *ext)
free(ext);
}
+static int cfg_exclude_add(struct cfg *cfg, const char *path)
+{
+ struct cfg_exclude *exc;
+ size_t len = strlen(path);
+
+ exc = malloc(sizeof(struct cfg_exclude) + len + 1);
+ if (exc == NULL) {
+ ERR("exclude add: out of memory\n");
+ return -ENOMEM;
+ }
+ memcpy(exc->exclude_dir, path, len + 1);
+
+ DBG("exclude add: %s\n", path);
+
+ exc->next = cfg->excludes;
+ cfg->excludes = exc;
+ return 0;
+}
+
+static void cfg_exclude_free(struct cfg_exclude *exc)
+{
+ free(exc);
+}
+
static int cfg_kernel_matches(const struct cfg *cfg, const char *pattern)
{
regex_t re;
@@ -656,6 +687,11 @@ static int cfg_file_parse(struct cfg *cfg, const char *filename)
}
cfg_external_add(cfg, dir);
+ } else if (streq(cmd, "exclude")) {
+ const char *sp;
+ while ((sp = strtok_r(NULL, "\t ", &saveptr)) != NULL) {
+ cfg_exclude_add(cfg, sp);
+ }
} else if (streq(cmd, "include")
|| streq(cmd, "make_map_files")) {
INF("%s:%u: command %s not implemented yet\n",
@@ -856,6 +892,12 @@ static void cfg_free(struct cfg *cfg)
cfg->externals = cfg->externals->next;
cfg_external_free(tmp);
}
+
+ while (cfg->excludes) {
+ struct cfg_exclude *tmp = cfg->excludes;
+ cfg->excludes = cfg->excludes->next;
+ cfg_exclude_free(tmp);
+ }
}
@@ -1228,6 +1270,25 @@ add:
return 0;
}
+static bool should_exclude_dir(const struct cfg *cfg, const char *name)
+{
+ struct cfg_exclude *exc;
+
+ if (name[0] == '.' && (name[1] == '\0' ||
+ (name[1] == '.' && name[2] == '\0')))
+ return true;
+
+ if (streq(name, "build") || streq(name, "source"))
+ return true;
+
+ for (exc = cfg->excludes; exc != NULL; exc = exc->next) {
+ if (streq(name, exc->exclude_dir))
+ return true;
+ }
+
+ return false;
+}
+
static int depmod_modules_search_dir(struct depmod *depmod, DIR *d, size_t baselen, struct scratchbuf *s_path)
{
struct dirent *de;
@@ -1239,11 +1300,9 @@ static int depmod_modules_search_dir(struct depmod *depmod, DIR *d, size_t basel
size_t namelen;
uint8_t is_dir;
- if (name[0] == '.' && (name[1] == '\0' ||
- (name[1] == '.' && name[2] == '\0')))
- continue;
- if (streq(name, "build") || streq(name, "source"))
+ if (should_exclude_dir(depmod->cfg, name))
continue;
+
namelen = strlen(name);
if (scratchbuf_alloc(s_path, baselen + namelen + 2) < 0) {
err = -ENOMEM;
@@ -2345,6 +2404,103 @@ static int output_builtin_bin(struct depmod *depmod, FILE *out)
return 0;
}
+static int flush_stream(FILE *in, int endchar)
+{
+ size_t i = 0;
+ int c;
+
+ for (c = fgetc(in);
+ c != EOF && c != endchar && c != '\0';
+ c = fgetc(in))
+ ;
+
+ return c == endchar ? i : 0;
+}
+
+static int flush_stream_to(FILE *in, int endchar, char *dst, size_t dst_sz)
+{
+ size_t i = 0;
+ int c;
+
+ for (c = fgetc(in);
+ c != EOF && c != endchar && c != '\0' && i < dst_sz;
+ c = fgetc(in))
+ dst[i++] = c;
+
+ if (i == dst_sz) {
+ WRN("Could not flush stream: %d. Partial content: %.*s\n",
+ ENOSPC, (int) dst_sz, dst);
+ i--;
+ }
+
+ return c == endchar ? i : 0;
+}
+
+static int output_builtin_alias_bin(struct depmod *depmod, FILE *out)
+{
+ FILE *in;
+ struct index_node *idx;
+ int ret;
+
+ if (out == stdout)
+ return 0;
+
+ in = dfdopen(depmod->cfg->dirname, "modules.builtin.modinfo", O_RDONLY, "r");
+ if (in == NULL)
+ return 0;
+
+ idx = index_create();
+ if (idx == NULL) {
+ fclose(in);
+ return -ENOMEM;
+ }
+
+ /* format: modname.key=value\0 */
+ while (!feof(in) && !ferror(in)) {
+ char alias[PATH_MAX];
+ char modname[PATH_MAX];
+ char value[PATH_MAX];
+ size_t len;
+
+ len = flush_stream_to(in, '.', modname, sizeof(modname));
+ modname[len] = '\0';
+ if (!len)
+ continue;
+
+ len = flush_stream_to(in, '=', value, sizeof(value));
+ value[len] = '\0';
+ if (!streq(value, "alias")) {
+ flush_stream(in, '\0');
+ continue;
+ }
+
+ len = flush_stream_to(in, '\0', value, sizeof(value));
+ value[len] = '\0';
+ if (!len)
+ continue;
+
+ alias[0] = '\0';
+ if (alias_normalize(value, alias, NULL) < 0) {
+ WRN("Unmatched bracket in %s\n", value);
+ continue;
+ }
+
+ index_insert(idx, alias, modname, 0);
+ }
+
+ if (ferror(in)) {
+ ret = -EINVAL;
+ } else {
+ index_write(idx, out);
+ ret = 0;
+ }
+
+ index_destroy(idx);
+ fclose(in);
+
+ return ret;
+}
+
static int output_devname(struct depmod *depmod, FILE *out)
{
size_t i;
@@ -2402,71 +2558,6 @@ static int output_devname(struct depmod *depmod, FILE *out)
return 0;
}
-static int output_builtin_alias_bin(struct depmod *depmod, FILE *out)
-{
- int ret = 0, count = 0;
- struct index_node *idx;
- struct kmod_list *l, *builtin = NULL;
-
- if (out == stdout)
- return 0;
-
- idx = index_create();
- if (idx == NULL)
- return -ENOMEM;
-
- ret = kmod_module_get_builtin(depmod->ctx, &builtin);
- if (ret < 0) {
- if (ret == -ENOENT)
- ret = 0;
- goto out;
- }
-
- kmod_list_foreach(l, builtin) {
- struct kmod_list *ll, *info_list = NULL;
- struct kmod_module *mod = l->data;
- const char *modname = kmod_module_get_name(mod);
-
- ret = kmod_module_get_info(mod, &info_list);
- if (ret < 0)
- goto out;
-
- kmod_list_foreach(ll, info_list) {
- char alias[PATH_MAX];
- const char *key = kmod_module_info_get_key(ll);
- const char *value = kmod_module_info_get_value(ll);
-
- if (!streq(key, "alias"))
- continue;
-
- alias[0] = '\0';
- if (alias_normalize(value, alias, NULL) < 0) {
- WRN("Unmatched bracket in %s\n", value);
- continue;
- }
-
- index_insert(idx, alias, modname, 0);
- }
-
- kmod_module_info_free_list(info_list);
-
- index_insert(idx, modname, modname, 0);
- count++;
- }
-
-out:
- /* do not bother writing the index if we are going to discard it */
- if (!ret)
- index_write(idx, out);
-
- if (builtin)
- kmod_module_unref_list(builtin);
-
- index_destroy(idx);
-
- return ret;
-}
-
static int depmod_output(struct depmod *depmod, FILE *out)
{
static const struct depfile {