X-Git-Url: http://git.archive.openwrt.org/?p=project%2Frpcd.git;a=blobdiff_plain;f=plugin.c;h=b75241aae1f82ce0a84b5d40c1c74b2e8c0577ed;hp=d6bdcef516a69bf788cbb30d36be6f0553c3639e;hb=b65f6a844f920eb19f7d05d2ee93819b72021057;hpb=0b4d4aeeace1c0a2cab6b913f309efb83ffd7c97;ds=sidebyside diff --git a/plugin.c b/plugin.c index d6bdcef..b75241a 100644 --- a/plugin.c +++ b/plugin.c @@ -1,7 +1,7 @@ /* - * luci-rpcd - LuCI UBUS RPC server + * rpcd - UBUS RPC server * - * Copyright (C) 2013 Jo-Philipp Wich + * Copyright (C) 2013-2014 Jo-Philipp Wich * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -16,8 +16,7 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include "plugin.h" -#include "exec.h" +#include static struct blob_buf buf; @@ -109,12 +108,9 @@ rpc_plugin_call_finish_cb(struct blob_buf *blob, int stat, void *priv) { if (c->obj) { - if (json_object_get_type(c->obj) == json_type_object || - json_object_get_type(c->obj) == json_type_array) - { - blobmsg_add_json_element(blob, NULL, c->obj); + if (json_object_get_type(c->obj) == json_type_object && + blobmsg_add_object(blob, c->obj)) rv = UBUS_STATUS_OK; - } json_object_put(c->obj); } @@ -195,7 +191,7 @@ rpc_plugin_parse_signature(struct blob_attr *sig, struct ubus_method *method) struct blob_attr *attr; struct blobmsg_policy *policy = NULL; - if (!sig || blob_id(sig) != BLOBMSG_TYPE_TABLE) + if (!sig || blobmsg_type(sig) != BLOBMSG_TYPE_TABLE) return false; n_attr = 0; @@ -214,7 +210,7 @@ rpc_plugin_parse_signature(struct blob_attr *sig, struct ubus_method *method) blobmsg_for_each_attr(attr, sig, rem) { - type = blob_id(attr); + type = blobmsg_type(attr); if (type == BLOBMSG_TYPE_INT32) { @@ -254,7 +250,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; @@ -341,7 +337,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]; @@ -382,7 +378,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; @@ -398,6 +394,37 @@ out: } } + +static LIST_HEAD(plugins); + +static const struct rpc_daemon_ops ops = { + .session_access = rpc_session_access, + .session_create_cb = rpc_session_create_cb, + .session_destroy_cb = rpc_session_destroy_cb, + .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; @@ -406,22 +433,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 (stat(path, &s) || !S_ISREG(s.st_mode) || !(s.st_mode & S_IXUSR)) + continue; - if (!d) - return UBUS_STATUS_NOT_FOUND; + rv |= rpc_plugin_register_exec(ctx, path); + } - while ((e = readdir(d)) != NULL) + closedir(d); + } + + 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; }