Introduce shared object plugin api
This commit is contained in:
parent
0b4d4aeeac
commit
3d358bb3a1
2 changed files with 81 additions and 16 deletions
65
plugin.c
65
plugin.c
|
@ -17,7 +17,6 @@
|
|||
*/
|
||||
|
||||
#include "plugin.h"
|
||||
#include "exec.h"
|
||||
|
||||
static struct blob_buf buf;
|
||||
|
||||
|
@ -254,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;
|
||||
|
@ -341,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];
|
||||
|
@ -382,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;
|
||||
|
@ -398,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;
|
||||
|
@ -406,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)
|
||||
return UBUS_STATUS_NOT_FOUND;
|
||||
|
||||
if ((d = opendir(RPC_PLUGIN_DIRECTORY)) != NULL)
|
||||
{
|
||||
while ((e = readdir(d)) != NULL)
|
||||
{
|
||||
snprintf(path, sizeof(path) - 1, RPC_PLUGIN_DIRECTORY "/%s", e->d_name);
|
||||
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;
|
||||
|
||||
rv |= rpc_plugin_register(ctx, path);
|
||||
rv |= rpc_plugin_register_exec(ctx, path);
|
||||
}
|
||||
|
||||
closedir(d);
|
||||
}
|
||||
|
||||
if ((d = opendir(RPC_LIBRARY_DIRECTORY)) != NULL)
|
||||
{
|
||||
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))
|
||||
continue;
|
||||
|
||||
rv |= rpc_plugin_register_library(ctx, path);
|
||||
}
|
||||
|
||||
closedir(d);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
|
24
plugin.h
24
plugin.h
|
@ -21,6 +21,7 @@
|
|||
|
||||
#define _GNU_SOURCE /* asprintf() */
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
@ -33,8 +34,29 @@
|
|||
#include <libubox/blobmsg_json.h>
|
||||
#include <libubus.h>
|
||||
|
||||
#include "exec.h"
|
||||
#include "session.h"
|
||||
|
||||
/* location of plugin executables */
|
||||
#define RPC_PLUGIN_DIRECTORY "/usr/lib/luci-rpcd/plugins"
|
||||
#define RPC_PLUGIN_DIRECTORY "/usr/libexec/luci-rpcd"
|
||||
|
||||
/* location of plugin libraries */
|
||||
#define RPC_LIBRARY_DIRECTORY "/usr/lib/luci-rpcd"
|
||||
|
||||
struct rpc_daemon_ops {
|
||||
bool (*access)(const char *sid, const char *scope,
|
||||
const char *object, const char *function);
|
||||
int (*exec)(const char **args,
|
||||
rpc_exec_write_cb_t in, rpc_exec_read_cb_t out,
|
||||
rpc_exec_read_cb_t err, rpc_exec_done_cb_t end,
|
||||
void *priv, struct ubus_context *ctx,
|
||||
struct ubus_request_data *req);
|
||||
};
|
||||
|
||||
struct rpc_plugin {
|
||||
struct list_head list;
|
||||
int (*init)(const struct rpc_daemon_ops *ops, struct ubus_context *ctx);
|
||||
};
|
||||
|
||||
int rpc_plugin_api_init(struct ubus_context *ctx);
|
||||
|
||||
|
|
Loading…
Reference in a new issue