X-Git-Url: http://git.archive.openwrt.org/?p=project%2Fubus.git;a=blobdiff_plain;f=libubus-obj.c;h=a9972c5862eae0d62469e3010c346ed378877d12;hp=a1062e0a5a8b247cb849b729867dd585c3d22761;hb=97ac89f9727d4fae1b2d63d2fc3b59e0d5d4bf65;hpb=47a9ab0c645d4d49def8080ae68c7c477e733530 diff --git a/libubus-obj.c b/libubus-obj.c index a1062e0..a9972c5 100644 --- a/libubus-obj.c +++ b/libubus-obj.c @@ -11,12 +11,13 @@ * GNU General Public License for more details. */ +#include #include "libubus.h" #include "libubus-internal.h" static void ubus_process_unsubscribe(struct ubus_context *ctx, struct ubus_msghdr *hdr, - struct ubus_object *obj, struct blob_attr **attrbuf) + struct ubus_object *obj, struct blob_attr **attrbuf, int fd) { struct ubus_subscriber *s; @@ -29,11 +30,13 @@ ubus_process_unsubscribe(struct ubus_context *ctx, struct ubus_msghdr *hdr, s = container_of(obj, struct ubus_subscriber, obj); if (s->remove_cb) s->remove_cb(ctx, s, blob_get_u32(attrbuf[UBUS_ATTR_TARGET])); + + close(fd); } static void ubus_process_notify(struct ubus_context *ctx, struct ubus_msghdr *hdr, - struct ubus_object *obj, struct blob_attr **attrbuf) + struct ubus_object *obj, struct blob_attr **attrbuf, int fd) { if (!obj || !attrbuf[UBUS_ATTR_ACTIVE]) return; @@ -41,14 +44,18 @@ ubus_process_notify(struct ubus_context *ctx, struct ubus_msghdr *hdr, obj->has_subscribers = blob_get_u8(attrbuf[UBUS_ATTR_ACTIVE]); if (obj->subscribe_cb) obj->subscribe_cb(ctx, obj); + + close(fd); } static void ubus_process_invoke(struct ubus_context *ctx, struct ubus_msghdr *hdr, - struct ubus_object *obj, struct blob_attr **attrbuf) + struct ubus_object *obj, struct blob_attr **attrbuf, int fd) { struct ubus_request_data req = { .fd = -1, + .req_fd = fd, }; + int method; int ret; bool no_reply = false; @@ -65,11 +72,15 @@ ubus_process_invoke(struct ubus_context *ctx, struct ubus_msghdr *hdr, if (attrbuf[UBUS_ATTR_NO_REPLY]) no_reply = blob_get_int8(attrbuf[UBUS_ATTR_NO_REPLY]); - + req.peer = hdr->peer; req.seq = hdr->seq; req.object = obj->id; - + if (attrbuf[UBUS_ATTR_USER] && attrbuf[UBUS_ATTR_GROUP]) { + req.acl.user = blobmsg_get_string(attrbuf[UBUS_ATTR_USER]); + req.acl.group = blobmsg_get_string(attrbuf[UBUS_ATTR_GROUP]); + req.acl.object = obj->name; + } for (method = 0; method < obj->n_methods; method++) if (!obj->methods[method].name || !strcmp(obj->methods[method].name, @@ -84,6 +95,7 @@ found: ret = obj->methods[method].handler(ctx, obj, &req, blob_data(attrbuf[UBUS_ATTR_METHOD]), attrbuf[UBUS_ATTR_DATA]); + close(req.req_fd); if (req.deferred || no_reply) return; @@ -91,15 +103,17 @@ send: ubus_complete_deferred_request(ctx, &req, ret); } -void __hidden ubus_process_obj_msg(struct ubus_context *ctx, struct ubus_msghdr *hdr) + +void __hidden ubus_process_obj_msg(struct ubus_context *ctx, struct ubus_msghdr_buf *buf, int fd) { void (*cb)(struct ubus_context *, struct ubus_msghdr *, - struct ubus_object *, struct blob_attr **); + struct ubus_object *, struct blob_attr **, int fd); + struct ubus_msghdr *hdr = &buf->hdr; struct blob_attr **attrbuf; struct ubus_object *obj; uint32_t objid; - - attrbuf = ubus_parse_msg(ubus_msghdr_data(hdr)); + void *prev_data = NULL; + attrbuf = ubus_parse_msg(buf->data); if (!attrbuf[UBUS_ATTR_OBJID]) return; @@ -119,7 +133,20 @@ void __hidden ubus_process_obj_msg(struct ubus_context *ctx, struct ubus_msghdr default: return; } - cb(ctx, hdr, obj, attrbuf); + + if (buf == &ctx->msgbuf) { + prev_data = buf->data; + buf->data = NULL; + } + + cb(ctx, hdr, obj, attrbuf, fd); + + if (prev_data) { + if (buf->data) + free(prev_data); + else + buf->data = prev_data; + } } static void ubus_add_object_cb(struct ubus_request *req, int type, struct blob_attr *msg) @@ -146,8 +173,12 @@ static void ubus_push_method_data(const struct ubus_method *m) mtbl = blobmsg_open_table(&b, m->name); - for (i = 0; i < m->n_policy; i++) + for (i = 0; i < m->n_policy; i++) { + if (m->mask && !(m->mask & (1 << i))) + continue; + blobmsg_add_u32(&b, m->policy[i].name, m->policy[i].type); + } blobmsg_close_table(&b, mtbl); }