CMakeLists.txt: bump minimum cmake version
[project/ubus.git] / ubusd_main.c
index d298b51db17b5ccd35255a5f89877a6db781d67f..adbd2932be3d22a1317ca8a33be50fb30662f7cd 100644 (file)
@@ -32,6 +32,28 @@ static void handle_client_disconnect(struct ubus_client *cl)
        free(cl);
 }
 
+static void ubus_client_cmd_free(struct ubus_client_cmd *cmd)
+{
+       list_del(&cmd->list);
+       ubus_msg_free(cmd->msg);
+       free(cmd);
+}
+
+static void ubus_client_cmd_queue_process(struct ubus_client *cl)
+{
+       struct ubus_client_cmd *cmd, *tmp;
+
+       list_for_each_entry_safe(cmd, tmp, &cl->cmd_queue, list) {
+               int ret = ubusd_cmd_lookup(cl, cmd);
+
+               /* Stop if the last command caused buffering again */
+               if (ret == -2)
+                       break;
+
+               ubus_client_cmd_free(cmd);
+       }
+}
+
 static void client_cb(struct uloop_fd *sock, unsigned int events)
 {
        struct ubus_client *cl = container_of(sock, struct ubus_client, sock);
@@ -78,13 +100,19 @@ static void client_cb(struct uloop_fd *sock, unsigned int events)
                if (cl->txq_ofs < ub->len + sizeof(ub->hdr))
                        break;
 
+               cl->txq_ofs = 0;
                ubus_msg_list_free(ubl);
        }
 
-       /* prevent further ULOOP_WRITE events if we don't have data
-        * to send anymore */
-       if (list_empty(&cl->tx_queue) && (events & ULOOP_WRITE))
-               uloop_fd_add(sock, ULOOP_READ | ULOOP_EDGE_TRIGGER);
+       if (list_empty(&cl->tx_queue) && (events & ULOOP_WRITE)) {
+               /* Process queued commands */
+               ubus_client_cmd_queue_process(cl);
+
+               /* prevent further ULOOP_WRITE events if we don't have data
+                * to send anymore */
+               if (list_empty(&cl->tx_queue))
+                       uloop_fd_add(sock, ULOOP_READ | ULOOP_EDGE_TRIGGER);
+       }
 
 retry:
        if (!sock->eof && cl->pending_msg_offset < (int) sizeof(cl->hdrbuf)) {
@@ -115,6 +143,8 @@ retry:
                if (cl->pending_msg_offset < (int) sizeof(cl->hdrbuf))
                        goto out;
 
+               if (blob_raw_len(&cl->hdrbuf.data) < sizeof(struct blob_attr))
+                       goto disconnect;
                if (blob_pad_len(&cl->hdrbuf.data) > UBUS_MAX_MSGLEN)
                        goto disconnect;
 
@@ -230,6 +260,8 @@ static void mkdir_sockdir()
        free(ubus_sock_dir);
 }
 
+#include <libubox/ulog.h>
+
 int main(int argc, char **argv)
 {
        const char *ubus_socket = UBUS_UNIX_SOCKET;
@@ -239,6 +271,7 @@ int main(int argc, char **argv)
        signal(SIGPIPE, SIG_IGN);
        signal(SIGHUP, sighup_handler);
 
+       ulog_open(ULOG_KMSG | ULOG_SYSLOG, LOG_DAEMON, "ubusd");
        openlog("ubusd", LOG_PID, LOG_DAEMON);
        uloop_init();