X-Git-Url: http://git.archive.openwrt.org/?p=project%2Frpcd.git;a=blobdiff_plain;f=uci.c;h=0fede861aaeac674e1d3a32dd47d1ca9724f5c1e;hp=ac97cbdd4231a74805768f6b98594673bea7a5d4;hb=fc1b008e081429101d5d3bb878ddb417c0d2be12;hpb=97384dd72acbba1e586824b477c2bea483505a40 diff --git a/uci.c b/uci.c index ac97cbd..0fede86 100644 --- a/uci.c +++ b/uci.c @@ -1,5 +1,5 @@ /* - * luci-rpcd - LuCI UBUS RPC server + * rpcd - UBUS RPC server * * Copyright (C) 2013 Jo-Philipp Wich * @@ -16,8 +16,8 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include "uci.h" -#include "session.h" +#include +#include static struct blob_buf buf; static struct uci_context *cursor; @@ -169,6 +169,28 @@ rpc_uci_status(void) } /* + * Setup per-session delta save directory. If the passed "sid" blob attribute + * pointer is NULL then the precedure was not invoked through the ubus-rpc so + * we do not perform session isolation and use the default save directory. + */ +static void +rpc_uci_set_savedir(struct blob_attr *sid) +{ + char path[PATH_MAX]; + + if (!sid) + { + uci_set_savedir(cursor, "/tmp/.uci"); + return; + } + + snprintf(path, sizeof(path) - 1, + "/tmp/.uci-rpc-%s", (char *)blobmsg_data(sid)); + + uci_set_savedir(cursor, path); +} + +/* * Test read access to given config. If the passed "sid" blob attribute pointer * is NULL then the precedure was not invoked through the ubus-rpc so we do not * perform access control and always assume true. @@ -176,6 +198,8 @@ rpc_uci_status(void) static bool rpc_uci_read_access(struct blob_attr *sid, struct blob_attr *config) { + rpc_uci_set_savedir(sid); + if (!sid) return true; @@ -191,6 +215,8 @@ rpc_uci_read_access(struct blob_attr *sid, struct blob_attr *config) static bool rpc_uci_write_access(struct blob_attr *sid, struct blob_attr *config) { + rpc_uci_set_savedir(sid); + if (!sid) return true; @@ -1085,6 +1111,68 @@ out: } +/* + * Remove given delta save directory (if any). + */ +static void +rpc_uci_purge_savedir(const char *path) +{ + DIR *d; + struct stat s; + struct dirent *e; + char file[PATH_MAX]; + + if (stat(path, &s) || !S_ISDIR(s.st_mode)) + return; + + if ((d = opendir(path)) != NULL) + { + while ((e = readdir(d)) != NULL) + { + snprintf(file, sizeof(file) - 1, "%s/%s", path, e->d_name); + + if (stat(file, &s) || !S_ISREG(s.st_mode)) + continue; + + unlink(file); + } + + closedir(d); + + rmdir(path); + } +} + +/* + * Session destroy callback to purge associated delta directory. + */ +static void +rpc_uci_purge_savedir_cb(struct rpc_session *ses, void *priv) +{ + char path[PATH_MAX]; + + snprintf(path, sizeof(path) - 1, "/tmp/.uci-rpc-%s", ses->id); + rpc_uci_purge_savedir(path); +} + +/* + * Removes all delta directories which match the /tmp/.uci-rpc-* pattern. + * This is used to clean up garbage when starting rpcd. + */ +void rpc_uci_purge_savedirs(void) +{ + int i; + glob_t gl; + + if (!glob("/tmp/.uci-rpc-*", 0, NULL, &gl)) + { + for (i = 0; i < gl.gl_pathc; i++) + rpc_uci_purge_savedir(gl.gl_pathv[i]); + + globfree(&gl); + } +} + int rpc_uci_api_init(struct ubus_context *ctx) { static const struct ubus_method uci_methods[] = { @@ -1110,10 +1198,16 @@ int rpc_uci_api_init(struct ubus_context *ctx) .n_methods = ARRAY_SIZE(uci_methods), }; + static struct rpc_session_cb cb = { + .cb = rpc_uci_purge_savedir_cb + }; + cursor = uci_alloc_context(); if (!cursor) return UBUS_STATUS_UNKNOWN_ERROR; + rpc_session_destroy_cb(&cb); + return ubus_add_object(ctx, &obj); }