#include <murphy/core/event.h>
#include <murphy/core/plugin.h>
-
#define PLUGIN_PREFIX "plugin-"
+#define BUILTIN TRUE
+#define DYNAMIC FALSE
-static mrp_plugin_descr_t *open_builtin(const char *name);
-static mrp_plugin_descr_t *open_dynamic(const char *path, void **handle);
+static mrp_plugin_descr_t *open_builtin(mrp_context_t *ctx, const char *name);
+static mrp_plugin_descr_t *open_dynamic(mrp_context_t *ctx, const char *name,
+ void **handle);
static mrp_plugin_t *find_plugin(mrp_context_t *ctx, char *name);
static mrp_plugin_t *find_plugin_instance(mrp_context_t *ctx,
const char *instance);
{ MRP_PLUGIN_EVENT_UNLOADED, PLUGIN_EVENT_UNLOADED });
+static inline int is_listed(const char *list, const char *name)
+{
+ const char *b, *n, *e;
+
+ if (list == NULL || name == NULL)
+ return FALSE;
+
+ if ((list[0] == '*' && list[1] == '\0') || (!strcmp(list, "all")))
+ return TRUE;
+
+ b = list;
+ while (b && *b) {
+ while (*b == ' ' || *b == '\t' || *b == ',')
+ b++;
+
+ if ((e = n = strchr(b, ',')) != NULL) {
+ while (e > b && (*e == ' ' || *e == '\t' || *e == ','))
+ e--;
+ }
+
+ if ((e != NULL && e > b && !strncmp(b, name, e - b)) ||
+ (e == NULL && !strcmp (b, name)))
+ return TRUE;
+
+ if ((b[0] == '*' && (b[1] == ',' ||
+ b[1] == ' ' || b[1] == '\t' ||
+ b[1] == '\0')) ||
+ (b[0] == 'a' && b[1] == 'l' && b[2] == 'l' &&
+ (b[1] == ',' ||
+ b[1] == ' ' || b[1] == '\t' ||
+ b[1] == '\0'))) {
+ mrp_log_warning("Wildcard entry in blacklist/whitelist '%s'", list);
+ return TRUE;
+ }
+
+ b = n ? n + 1 : NULL;
+ }
+
+ return FALSE;
+}
+
+
+static inline int is_blacklisted(mrp_context_t *ctx, const char *name,
+ int builtin)
+{
+#define IS_WILDCARD(l) \
+ (((l) != NULL && (l)[0] == '*' && (l)[1] == '\0') || \
+ ((l) != NULL && !strcmp((l), "all")))
+
+ const char *bl, *wl, *type_bl, *type_wl;
+ int b, w, tb, tw, blacklist;
+
+ mrp_debug("checking if %s plugin %s is blacklisted",
+ builtin ? "builtin" : "dynamic", name);
+
+ bl = ctx->blacklist_plugins;
+ wl = ctx->whitelist_plugins;
+ b = is_listed(bl, name);
+ w = is_listed(wl, name);
+
+ if (builtin) {
+ type_bl = ctx->blacklist_builtin;
+ type_wl = ctx->whitelist_builtin;
+ }
+ else {
+ type_bl = ctx->blacklist_dynamic;
+ type_wl = ctx->whitelist_dynamic;
+ }
+
+ tb = is_listed(type_bl, name);
+ tw = is_listed(type_wl, name);
+
+ mrp_debug("%s: b:(%s,%s), w:(%s,%s)", name,
+ b ? "true" : "false", tb ? "true" : "false",
+ w ? "true" : "false", tw ? "true" : "false");
+
+ if (IS_WILDCARD(bl) || IS_WILDCARD(type_bl)) {
+ if (w || tw)
+ blacklist = FALSE;
+ else
+ blacklist = TRUE;
+
+ goto verdict;
+ }
+
+ if (IS_WILDCARD(wl) || IS_WILDCARD(type_wl)) {
+ if (b || tb)
+ blacklist = TRUE;
+ else
+ blacklist = FALSE;
+
+ goto verdict;
+ }
+
+ blacklist = (( is_listed(bl, name) || is_listed(type_bl, name)) &&
+ !(is_listed(wl, name) || is_listed(type_wl, name)));
+
+
+ verdict:
+ if (blacklist)
+ mrp_log_warning("%s plugin '%s' is blacklisted.",
+ builtin ? "Builtin" : "Dynamic", name);
+
+ mrp_debug("%s: %sblacklisted", name, blacklist ? "" : "not ");
+
+ return blacklist;
+}
+
+
static int emit_plugin_event(int idx, mrp_plugin_t *plugin)
{
uint16_t name = MRP_PLUGIN_TAG_PLUGIN;
struct stat st;
char path[PATH_MAX];
- if (open_builtin(name))
+ if (open_builtin(ctx, name))
return TRUE;
else {
+ if (is_blacklisted(ctx, name, DYNAMIC))
+ return FALSE;
+
snprintf(path, sizeof(path), "%s/%s%s.so", ctx->plugin_dir,
PLUGIN_PREFIX, name);
if (stat(path, &st) == 0)
snprintf(path, sizeof(path), "%s/%s%s.so", ctx->plugin_dir,
PLUGIN_PREFIX, name);
- dynamic = open_dynamic(path, &handle);
- builtin = open_builtin(name);
+ dynamic = open_dynamic(ctx, name, &handle);
+ builtin = open_builtin(ctx, name);
if (dynamic != NULL) {
if (builtin != NULL)
pattern = PLUGIN_PREFIX".*\\.so$";
mrp_scan_dir(ctx->plugin_dir, pattern, type, load_plugin_cb, ctx);
-
mrp_list_foreach(&builtin_plugins, p, n) {
plugin = mrp_list_entry(p, typeof(*plugin), hook);
}
-static mrp_plugin_descr_t *open_dynamic(const char *path, void **handle)
+static mrp_plugin_descr_t *open_dynamic(mrp_context_t *ctx, const char *name,
+ void **handle)
{
mrp_plugin_descr_t *(*describe)(void);
mrp_plugin_descr_t *d;
void *h;
+ char path[PATH_MAX];
+
+ snprintf(path, sizeof(path), "%s/%s%s.so", ctx->plugin_dir,
+ PLUGIN_PREFIX, name);
+
+ if (is_blacklisted(ctx, name, DYNAMIC))
+ return NULL;
if ((h = dlopen(path, RTLD_LAZY | RTLD_LOCAL)) != NULL) {
if ((describe = dlsym(h, "mrp_get_plugin_descriptor")) != NULL) {
}
-static mrp_plugin_descr_t *open_builtin(const char *name)
+static mrp_plugin_descr_t *open_builtin(mrp_context_t *ctx, const char *name)
{
mrp_list_hook_t *p, *n;
mrp_plugin_t *plugin;
+ if (is_blacklisted(ctx, name, BUILTIN))
+ return NULL;
+
mrp_list_foreach(&builtin_plugins, p, n) {
plugin = mrp_list_entry(p, typeof(*plugin), hook);
" -h, --help show help on usage\n"
" -q, --query-plugins show detailed information about\n"
" all the available plugins\n"
+ " -B, --blacklist-plugins <list> disable list of plugins\n"
+ " -I, --blacklist-builtin <list> disable list of builtin plugins\n"
+ " -E, --blacklist-dynamic <list> disable list of dynamic plugins\n"
+ " -w, --whitelist-plugins <list> disable list of plugins\n"
+ " -i, --whitelist-builtin <list> disable list of builtin plugins\n"
+ " -e, --whitelist-dynamic <list> disable list of dynamic plugins\n"
" -V, --valgrind run through valgrind\n",
argv0, ctx->config_file, ctx->config_dir, ctx->plugin_dir);
void mrp_parse_cmdline(mrp_context_t *ctx, int argc, char **argv, char **envp)
{
-# define OPTIONS "c:C:l:t:fP:a:vd:DhHqV"
+# define OPTIONS "c:C:l:t:fP:a:vd:DhHqB:I:E:w:i:e:V"
struct option options[] = {
- { "config-file" , required_argument, NULL, 'c' },
- { "config-dir" , required_argument, NULL, 'C' },
- { "plugin-dir" , required_argument, NULL, 'P' },
- { "log-level" , required_argument, NULL, 'l' },
- { "log-target" , required_argument, NULL, 't' },
- { "verbose" , optional_argument, NULL, 'v' },
- { "debug" , required_argument, NULL, 'd' },
- { "list-debug" , no_argument , NULL, 'D' },
- { "foreground" , no_argument , NULL, 'f' },
- { "help" , no_argument , NULL, 'h' },
- { "more-help" , no_argument , NULL, 'H' },
- { "query-plugins", no_argument , NULL, 'q' },
- { "valgrind" , optional_argument, NULL, 'V' },
+ { "config-file" , required_argument, NULL, 'c' },
+ { "config-dir" , required_argument, NULL, 'C' },
+ { "plugin-dir" , required_argument, NULL, 'P' },
+ { "log-level" , required_argument, NULL, 'l' },
+ { "log-target" , required_argument, NULL, 't' },
+ { "verbose" , optional_argument, NULL, 'v' },
+ { "debug" , required_argument, NULL, 'd' },
+ { "list-debug" , no_argument , NULL, 'D' },
+ { "foreground" , no_argument , NULL, 'f' },
+ { "help" , no_argument , NULL, 'h' },
+ { "more-help" , no_argument , NULL, 'H' },
+ { "query-plugins" , no_argument , NULL, 'q' },
+ { "blacklist" , required_argument, NULL, 'B' },
+ { "blacklist-plugins", required_argument, NULL, 'B' },
+ { "blacklist-builtin", required_argument, NULL, 'I' },
+ { "blacklist-dynamic", required_argument, NULL, 'E' },
+ { "whitelist" , required_argument, NULL, 'w' },
+ { "whitelist-plugins", required_argument, NULL, 'w' },
+ { "whitelist-builtin", required_argument, NULL, 'i' },
+ { "whitelist-dynamic", required_argument, NULL, 'e' },
+ { "valgrind" , optional_argument, NULL, 'V' },
{ NULL, 0, NULL, 0 }
};
print_plugin_help(ctx, TRUE);
break;
+ case 'B':
+ if (ctx->blacklist_plugins != NULL)
+ print_usage(ctx, argv[0], EINVAL,
+ "blacklist option given multiple times");
+ SAVE_OPTARG("-B", optarg);
+ ctx->blacklist_plugins = optarg;
+ break;
+ case 'I':
+ if (ctx->blacklist_builtin != NULL)
+ print_usage(ctx, argv[0], EINVAL,
+ "builtin blacklist option given multiple times");
+ SAVE_OPTARG("-I", optarg);
+ ctx->blacklist_builtin = optarg;
+ break;
+ case 'E':
+ if (ctx->blacklist_dynamic != NULL)
+ print_usage(ctx, argv[0], EINVAL,
+ "dynamic blacklist option given multiple times");
+ SAVE_OPTARG("-E", optarg);
+ ctx->blacklist_dynamic = optarg;
+ break;
+ case 'w':
+ if (ctx->whitelist_plugins != NULL)
+ print_usage(ctx, argv[0], EINVAL,
+ "whitelist option given multiple times");
+ SAVE_OPTARG("-w", optarg);
+ ctx->whitelist_plugins = optarg;
+ break;
+ case 'i':
+ if (ctx->whitelist_builtin != NULL)
+ print_usage(ctx, argv[0], EINVAL,
+ "builtin whitelist option given multiple times");
+ SAVE_OPTARG("-i", optarg);
+ ctx->whitelist_builtin = optarg;
+ break;
+ case 'e':
+ if (ctx->whitelist_dynamic != NULL)
+ print_usage(ctx, argv[0], EINVAL,
+ "dynamic whitelist option given multiple times");
+ SAVE_OPTARG("-e", optarg);
+ ctx->whitelist_dynamic = optarg;
+ break;
case 'V':
valgrind(optarg, argc, argv, optind, saved_argc, saved_argv, envp);
break;