X-Git-Url: http://git.archive.openwrt.org/?p=project%2Frpcd.git;a=blobdiff_plain;f=plugin.c;h=33266b34b4553cb97b459adfcc7398d394254a13;hp=37deddf5120ca9d03e8021d2ac5400a4d775e308;hb=07c2f0a9b1c7f79e81fa8a51cca5ecbe9eaf7293;hpb=90e8e9ca002a4509d620e99068f05ef081b5cdad diff --git a/plugin.c b/plugin.c index 37deddf..33266b3 100644 --- a/plugin.c +++ b/plugin.c @@ -1,5 +1,5 @@ /* - * luci-rpcd - LuCI UBUS RPC server + * rpcd - UBUS RPC server * * Copyright (C) 2013 Jo-Philipp Wich * @@ -17,7 +17,6 @@ */ #include "plugin.h" -#include "exec.h" static struct blob_buf buf; @@ -94,6 +93,12 @@ rpc_plugin_call_stdout_cb(struct blob_buf *blob, char *buf, int len, void *priv) } static int +rpc_plugin_call_stderr_cb(struct blob_buf *blob, char *buf, int len, void *priv) +{ + return len; +} + +static int rpc_plugin_call_finish_cb(struct blob_buf *blob, int stat, void *priv) { struct call_context *c = priv; @@ -160,8 +165,8 @@ rpc_plugin_call(struct ubus_context *ctx, struct ubus_object *obj, c->argv[2] = c->method; return rpc_exec(c->argv, rpc_plugin_call_stdin_cb, - rpc_plugin_call_stdout_cb, NULL, rpc_plugin_call_finish_cb, - c, ctx, req); + rpc_plugin_call_stdout_cb, rpc_plugin_call_stderr_cb, + rpc_plugin_call_finish_cb, c, ctx, req); fail: if (c) @@ -248,7 +253,7 @@ rpc_plugin_parse_signature(struct blob_attr *sig, struct ubus_method *method) } static struct ubus_object * -rpc_plugin_parse_plugin(const char *name, int fd) +rpc_plugin_parse_exec(const char *name, int fd) { int len, rem, n_method; struct blob_attr *cur; @@ -335,7 +340,7 @@ rpc_plugin_parse_plugin(const char *name, int fd) } static int -rpc_plugin_register(struct ubus_context *ctx, const char *path) +rpc_plugin_register_exec(struct ubus_context *ctx, const char *path) { pid_t pid; int rv = UBUS_STATUS_NO_DATA, fd, fds[2]; @@ -376,7 +381,7 @@ rpc_plugin_register(struct ubus_context *ctx, const char *path) return UBUS_STATUS_UNKNOWN_ERROR; default: - plugin = rpc_plugin_parse_plugin(name + 1, fds[0]); + plugin = rpc_plugin_parse_exec(name + 1, fds[0]); if (!plugin) goto out; @@ -392,6 +397,35 @@ out: } } + +static LIST_HEAD(plugins); + +static const struct rpc_daemon_ops ops = { + .access = rpc_session_access, + .exec = rpc_exec, +}; + +static int +rpc_plugin_register_library(struct ubus_context *ctx, const char *path) +{ + struct rpc_plugin *p; + void *dlh; + + dlh = dlopen(path, RTLD_LAZY | RTLD_GLOBAL); + + if (!dlh) + return UBUS_STATUS_UNKNOWN_ERROR; + + p = dlsym(dlh, "rpc_plugin"); + + if (!p) + return UBUS_STATUS_NOT_FOUND; + + list_add(&p->list, &plugins); + + return p->init(&ops, ctx); +} + int rpc_plugin_api_init(struct ubus_context *ctx) { DIR *d; @@ -400,22 +434,37 @@ int rpc_plugin_api_init(struct ubus_context *ctx) struct dirent *e; char path[PATH_MAX]; - d = opendir(RPC_PLUGIN_DIRECTORY); + if ((d = opendir(RPC_PLUGIN_DIRECTORY)) != NULL) + { + while ((e = readdir(d)) != NULL) + { + snprintf(path, sizeof(path) - 1, + RPC_PLUGIN_DIRECTORY "/%s", e->d_name); - if (!d) - return UBUS_STATUS_NOT_FOUND; + if (stat(path, &s) || !S_ISREG(s.st_mode) || !(s.st_mode & S_IXUSR)) + continue; + + rv |= rpc_plugin_register_exec(ctx, path); + } + + closedir(d); + } - while ((e = readdir(d)) != NULL) + if ((d = opendir(RPC_LIBRARY_DIRECTORY)) != NULL) { - snprintf(path, sizeof(path) - 1, RPC_PLUGIN_DIRECTORY "/%s", e->d_name); + while ((e = readdir(d)) != NULL) + { + snprintf(path, sizeof(path) - 1, + RPC_LIBRARY_DIRECTORY "/%s", e->d_name); - if (stat(path, &s) || !S_ISREG(s.st_mode) || !(s.st_mode & S_IXUSR)) - continue; + if (stat(path, &s) || !S_ISREG(s.st_mode)) + continue; - rv |= rpc_plugin_register(ctx, path); - } + rv |= rpc_plugin_register_library(ctx, path); + } - closedir(d); + closedir(d); + } return rv; }