return alias->modname;
}
+const char *kmod_option_get_options(const struct kmod_list *l) {
+ const struct kmod_options *alias = l->data;
+ return alias->options;
+}
+
+const char *kmod_option_get_modname(const struct kmod_list *l) {
+ const struct kmod_options *alias = l->data;
+ return alias->modname;
+}
+
+const char *kmod_command_get_command(const struct kmod_list *l) {
+ const struct kmod_command *alias = l->data;
+ return alias->command;
+}
+
+const char *kmod_command_get_modname(const struct kmod_list *l) {
+ const struct kmod_command *alias = l->data;
+ return alias->modname;
+}
+
static int kmod_config_add_command(struct kmod_config *config,
const char *modname,
const char *command,
struct kmod_ctx *ctx;
char *path;
struct kmod_list *dep;
- int refcount;
+ char *options;
+ char *install_commands;
+ char *remove_commands;
int n_dep;
+ int refcount;
struct {
bool dep : 1;
+ bool options : 1;
+ bool install_commands : 1;
+ bool remove_commands : 1;
} init;
char name[];
};
kmod_module_unref_list(mod->dep);
kmod_unref(mod->ctx);
+ free(mod->options);
+ free(mod->install_commands);
+ free(mod->remove_commands);
free(mod->path);
free(mod);
return NULL;
list = kmod_list_remove(list);
}
}
+
+KMOD_EXPORT const char *kmod_module_get_options(const struct kmod_module *mod)
+{
+ if (mod == NULL)
+ return NULL;
+
+ if (!mod->init.options) {
+ /* lazy init */
+ struct kmod_module *m = (struct kmod_module *)mod;
+ const struct kmod_list *l, *ctx_options;
+ char *opts = NULL;
+ size_t optslen = 0;
+ ctx_options = kmod_get_options(mod->ctx);
+ kmod_list_foreach(l, ctx_options) {
+ const char *modname = kmod_option_get_modname(l);
+ const char *str;
+ size_t len;
+ void *tmp;
+
+ if (strcmp(modname, mod->name) != 0)
+ continue;
+
+ str = kmod_option_get_options(l);
+ len = strlen(str);
+ if (len < 1)
+ continue;
+
+ tmp = realloc(opts, optslen + len + 2);
+ if (tmp == NULL) {
+ free(opts);
+ goto failed;
+ }
+ opts = tmp;
+ if (optslen > 0) {
+ opts[optslen] = ' ';
+ optslen++;
+ }
+ memcpy(opts + optslen, str, len);
+ optslen += len;
+ opts[optslen] = '\0';
+ }
+ m->init.options = true;
+ m->options = opts;
+ }
+
+ return mod->options;
+
+failed:
+ ERR(mod->ctx, "out of memory\n");
+ return NULL;
+}
+
+KMOD_EXPORT const char *kmod_module_get_install_commands(const struct kmod_module *mod)
+{
+ if (mod == NULL)
+ return NULL;
+
+ if (!mod->init.install_commands) {
+ /* lazy init */
+ struct kmod_module *m = (struct kmod_module *)mod;
+ const struct kmod_list *l, *ctx_install_commands;
+ char *cmds = NULL;
+ size_t cmdslen = 0;
+ ctx_install_commands = kmod_get_install_commands(mod->ctx);
+ kmod_list_foreach(l, ctx_install_commands) {
+ const char *modname = kmod_command_get_modname(l);
+ const char *str;
+ size_t len;
+ void *tmp;
+
+ if (strcmp(modname, mod->name) != 0)
+ continue;
+
+ str = kmod_command_get_command(l);
+ len = strlen(str);
+ if (len < 1)
+ continue;
+
+ tmp = realloc(cmds, cmdslen + len + 2);
+ if (tmp == NULL) {
+ free(cmds);
+ goto failed;
+ }
+ cmds = tmp;
+ if (cmdslen > 0) {
+ cmds[cmdslen] = ';';
+ cmdslen++;
+ }
+ memcpy(cmds + cmdslen, str, len);
+ cmdslen += len;
+ cmds[cmdslen] = '\0';
+ }
+ m->init.install_commands = true;
+ m->install_commands = cmds;
+ }
+
+ return mod->install_commands;
+
+failed:
+ ERR(mod->ctx, "out of memory\n");
+ return NULL;
+}
+
+KMOD_EXPORT const char *kmod_module_get_remove_commands(const struct kmod_module *mod)
+{
+ if (mod == NULL)
+ return NULL;
+
+ if (!mod->init.remove_commands) {
+ /* lazy init */
+ struct kmod_module *m = (struct kmod_module *)mod;
+ const struct kmod_list *l, *ctx_remove_commands;
+ char *cmds = NULL;
+ size_t cmdslen = 0;
+ ctx_remove_commands = kmod_get_remove_commands(mod->ctx);
+ kmod_list_foreach(l, ctx_remove_commands) {
+ const char *modname = kmod_command_get_modname(l);
+ const char *str;
+ size_t len;
+ void *tmp;
+
+ if (strcmp(modname, mod->name) != 0)
+ continue;
+
+ str = kmod_command_get_command(l);
+ len = strlen(str);
+ if (len < 1)
+ continue;
+
+ tmp = realloc(cmds, cmdslen + len + 2);
+ if (tmp == NULL) {
+ free(cmds);
+ goto failed;
+ }
+ cmds = tmp;
+ if (cmdslen > 0) {
+ cmds[cmdslen] = ';';
+ cmdslen++;
+ }
+ memcpy(cmds + cmdslen, str, len);
+ cmdslen += len;
+ cmds[cmdslen] = '\0';
+ }
+ m->init.remove_commands = true;
+ m->remove_commands = cmds;
+ }
+
+ return mod->remove_commands;
+
+failed:
+ ERR(mod->ctx, "out of memory\n");
+ return NULL;
+}
void kmod_pool_add_module(struct kmod_ctx *ctx, struct kmod_module *mod) __attribute__((nonnull(1,2)));
void kmod_pool_del_module(struct kmod_ctx *ctx, struct kmod_module *mod) __attribute__((nonnull(1,2)));
+const struct kmod_list *kmod_get_options(const struct kmod_ctx *ctx) __must_check __attribute__((nonnull(1)));
+const struct kmod_list *kmod_get_install_commands(const struct kmod_ctx *ctx) __must_check __attribute__((nonnull(1)));
+const struct kmod_list *kmod_get_remove_commands(const struct kmod_ctx *ctx) __must_check __attribute__((nonnull(1)));
+
/* libkmod-config.c */
struct kmod_config {
void kmod_config_free(struct kmod_config *config) __attribute__((nonnull(1)));
const char *kmod_alias_get_name(const struct kmod_list *l) __attribute__((nonnull(1)));
const char *kmod_alias_get_modname(const struct kmod_list *l) __attribute__((nonnull(1)));
+const char *kmod_option_get_options(const struct kmod_list *l) __attribute__((nonnull(1)));
+const char *kmod_option_get_modname(const struct kmod_list *l) __attribute__((nonnull(1)));
+const char *kmod_command_get_command(const struct kmod_list *l) __attribute__((nonnull(1)));
+const char *kmod_command_get_modname(const struct kmod_list *l) __attribute__((nonnull(1)));
+
/* libkmod-module.c */
int kmod_module_parse_depline(struct kmod_module *mod, char *line) __attribute__((nonnull(1, 2)));
}
}
}
+
+KMOD_EXPORT int kmod_resolve_alias_options(struct kmod_ctx *ctx, const char *alias, char **options)
+{
+ struct kmod_list *modules = NULL, *l;
+ char *opts = NULL;
+ size_t optslen = 0;
+ int err;
+
+ if (ctx == NULL || options == NULL)
+ return -ENOENT;
+
+ err = kmod_module_new_from_lookup(ctx, alias, &modules);
+ if (err >= 0) {
+ kmod_list_foreach(l, modules) {
+ const char *str = kmod_module_get_options(l->data);
+ size_t len;
+ void *tmp;
+
+ if (str == NULL)
+ continue;
+ len = strlen(str);
+
+ tmp = realloc(opts, optslen + len + 2);
+ if (tmp == NULL)
+ goto failed;
+ opts = tmp;
+ if (optslen > 0) {
+ opts[optslen] = ' ';
+ optslen++;
+ }
+ memcpy(opts + optslen, str, len);
+ optslen += len;
+ opts[optslen] = '\0';
+ }
+ }
+
+ kmod_list_foreach(l, ctx->config->options) {
+ const struct kmod_list *ml;
+ const char *modname = kmod_option_get_modname(l);
+ const char *str;
+ bool already_done = false;
+ size_t len;
+ void *tmp;
+
+ if (fnmatch(modname, alias, 0) != 0)
+ continue;
+
+ kmod_list_foreach(ml, modules) {
+ const char *mln = kmod_module_get_name(ml->data);
+ if (fnmatch(modname, mln, 0) == 0) {
+ already_done = true;
+ break;
+ }
+ }
+ if (already_done)
+ continue;
+
+ str = kmod_option_get_options(l);
+ len = strlen(str);
+ tmp = realloc(opts, optslen + len + 2);
+ if (tmp == NULL)
+ goto failed;
+ opts = tmp;
+ if (optslen > 0) {
+ opts[optslen] = ' ';
+ optslen++;
+ }
+ memcpy(opts + optslen, str, len);
+ optslen += len;
+ opts[optslen] = '\0';
+ }
+
+ DBG(ctx, "alias=%s options='%s'\n", alias, opts);
+ kmod_module_unref_list(modules);
+ *options = opts;
+ return 0;
+
+failed:
+ kmod_module_unref_list(modules);
+ free(opts);
+ ERR(ctx, "out of memory\n");
+ *options = NULL;
+ return -ENOMEM;
+}
+
+const struct kmod_list *kmod_get_options(const struct kmod_ctx *ctx)
+{
+ return ctx->config->options;
+}
+
+const struct kmod_list *kmod_get_install_commands(const struct kmod_ctx *ctx)
+{
+ return ctx->config->install_commands;
+}
+
+const struct kmod_list *kmod_get_remove_commands(const struct kmod_ctx *ctx)
+{
+ return ctx->config->remove_commands;
+}
long kmod_module_get_size(const struct kmod_module *mod);
+const char *kmod_module_get_options(const struct kmod_module *mod);
+const char *kmod_module_get_install_commands(const struct kmod_module *mod);
+const char *kmod_module_get_remove_commands(const struct kmod_module *mod);
+
+int kmod_resolve_alias_options(struct kmod_ctx *ctx, const char *alias, char **options);
+
#ifdef __cplusplus
} /* extern "C" */
#endif
kmod_module_section_get_address;
kmod_module_get_holders;
kmod_module_get_size;
+
+ kmod_module_get_options;
+ kmod_module_get_install_commands;
+ kmod_module_get_remove_commands;
+ kmod_resolve_alias_options;
local:
*;
};
const char *alias = NULL;
struct kmod_ctx *ctx;
struct kmod_list *list = NULL, *l;
+ char *options;
int load_resources = 0;
- int i, err;
+ int err;
printf("libkmod version %s\n", VERSION);
kmod_list_foreach(l, list) {
struct kmod_module *mod = kmod_module_get_module(l);
+ const char *str;
+
printf("\t%s\n", kmod_module_get_name(mod));
+ str = kmod_module_get_options(mod);
+ if (str)
+ printf("\t\toptions: '%s'\n", str);
+ str = kmod_module_get_install_commands(mod);
+ if (str)
+ printf("\t\tinstall commands: '%s'\n", str);
+ str = kmod_module_get_remove_commands(mod);
+ if (str)
+ printf("\t\tremove commands: '%s'\n", str);
kmod_module_unref(mod);
}
+ err = kmod_resolve_alias_options(ctx, alias, &options);
+ if (err == 0) {
+ printf("Alias options: '%s'\n", options);
+ free(options);
+ }
+
kmod_module_unref_list(list);
kmod_unref(ctx);