#include <libubox/blobmsg_json.h>
#include <rpcd/uci.h>
+#include <rpcd/exec.h>
#include <rpcd/session.h>
static struct blob_buf buf;
static struct uci_context *cursor;
static struct uloop_timeout apply_timer;
static struct ubus_context *apply_ctx;
-static char apply_sid[RPC_SID_LEN + 1];
+
+char apply_sid[RPC_SID_LEN + 1];
enum {
RPC_G_CONFIG,
}
}
+/*
+ * Clear all save directories from the uci cursor and append the given path
+ * as new save directory.
+ */
+static void
+rpc_uci_replace_savedir(const char *path)
+{
+ struct uci_element *e, *tmp;
+
+ uci_foreach_element_safe(&cursor->delta_path, tmp, e)
+ free(e);
+
+ cursor->delta_path.prev = &cursor->delta_path;
+ cursor->delta_path.next = &cursor->delta_path;
+
+ if (path)
+ uci_set_savedir(cursor, path);
+}
+
/*
* 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
if (!sid)
{
- uci_set_savedir(cursor, "/tmp/.uci");
+ rpc_uci_replace_savedir("/tmp/.uci");
return;
}
snprintf(path, sizeof(path) - 1,
RPC_UCI_SAVEDIR_PREFIX "%s", blobmsg_get_string(sid));
- uci_set_savedir(cursor, path);
+ rpc_uci_replace_savedir(path);
}
/*
switch (blobmsg_type(v))
{
case BLOBMSG_TYPE_STRING:
- if (blobmsg_data_len(v) > 1)
- *p = blobmsg_data(v);
+ *p = blobmsg_data(v);
break;
case BLOBMSG_TYPE_INT64:
else
{
if (!uci_lookup_ptr(cursor, &ptr, NULL, true) && ptr.p)
+ {
uci_revert(cursor, &ptr);
+ uci_unload(cursor, ptr.p);
+ }
}
return rpc_uci_status();
rpc_uci_apply_config(struct ubus_context *ctx, char *config)
{
struct uci_package *p = NULL;
- struct uci_ptr ptr = { 0 };
-
- ptr.package = config;
- if (!uci_load(cursor, ptr.package, &p)) {
+ if (!uci_load(cursor, config, &p)) {
uci_commit(cursor, &p, false);
uci_unload(cursor, p);
}
if (!apply_sid[0])
return UBUS_STATUS_NO_DATA;
- printf("CMP=%s/%s\n", apply_sid, sid);
-
if (strcmp(apply_sid, sid))
return UBUS_STATUS_PERMISSION_DENIED;
return 0;
}
+static int
+rpc_uci_reload(struct ubus_context *ctx, struct ubus_object *obj,
+ struct ubus_request_data *req, const char *method,
+ struct blob_attr *msg)
+{
+ char * const cmd[2] = { "/sbin/reload_config", NULL };
+
+ if (!fork()) {
+ /* wait for the RPC call to complete */
+ sleep(2);
+ return execv(cmd[0], cmd);
+ }
+
+ return 0;
+}
/*
* Session destroy callback to purge associated delta directory.
UBUS_METHOD("apply", rpc_uci_apply, rpc_uci_apply_policy),
UBUS_METHOD("confirm", rpc_uci_confirm, rpc_uci_rollback_policy),
UBUS_METHOD("rollback", rpc_uci_rollback, rpc_uci_rollback_policy),
+ UBUS_METHOD_NOARG("reload_config", rpc_uci_reload),
};
static struct ubus_object_type uci_type =