+static int ubusd_handle_lookup(struct ubus_client *cl, struct ubus_msg_buf *ub, struct blob_attr **attr)
+{
+ int rc;
+
+ if (list_empty(&cl->tx_queue))
+ rc = __ubusd_handle_lookup(cl, ub, attr, NULL);
+ else
+ rc = ubus_client_cmd_queue_add(cl, ub, NULL);
+
+ return rc;
+}
+
+int ubusd_cmd_lookup(struct ubus_client *cl, struct ubus_client_cmd *cmd)
+{
+ struct ubus_msg_buf *ub = cmd->msg;
+ struct blob_attr **attr;
+ int ret;
+
+ attr = ubus_parse_msg(ub->data, blob_raw_len(ub->data));
+ ret = __ubusd_handle_lookup(cl, ub, attr, cmd);
+
+ if (ret != -2) {
+ struct ubus_msg_buf *retmsg = cl->retmsg;
+ int *retmsg_data = blob_data(blob_data(retmsg->data));
+
+ retmsg->hdr.seq = ub->hdr.seq;
+ retmsg->hdr.peer = ub->hdr.peer;
+
+ *retmsg_data = htonl(ret);
+ ubus_msg_send(cl, retmsg);
+ }
+ return ret;
+}
+
+static void
+ubusd_forward_invoke(struct ubus_client *cl, struct ubus_object *obj,
+ const char *method, struct ubus_msg_buf *ub,
+ struct blob_attr *data)
+{
+ blob_put_int32(&b, UBUS_ATTR_OBJID, obj->id.id);
+ blob_put_string(&b, UBUS_ATTR_METHOD, method);
+ if (cl->user)
+ blob_put_string(&b, UBUS_ATTR_USER, cl->user);
+ if (cl->group)
+ blob_put_string(&b, UBUS_ATTR_GROUP, cl->group);
+ if (data)
+ blob_put(&b, UBUS_ATTR_DATA, blob_data(data), blob_len(data));
+
+ ubus_proto_send_msg_from_blob(obj->client, ub, UBUS_MSG_INVOKE);
+}
+