Plugged a couple of memory leaks.
[doldaconnect.git] / daemon / ui.c
index dd3d931..fdedc50 100644 (file)
@@ -34,6 +34,7 @@
 #include <time.h>
 #include <fcntl.h>
 #include <signal.h>
+#include <stdint.h>
 
 #ifdef HAVE_CONFIG_H
 #include <config.h>
@@ -118,6 +119,7 @@ struct uidata
     struct uidata *next, *prev;
     struct socket *sk;
     struct qcommand *queue, *queuelast;
+    size_t queuesize;
     struct authhandle *auth;
     int close;
     union
@@ -369,7 +371,7 @@ static void cmd_connect(struct socket *sk, struct uidata *data, int argc, wchar_
            return;
        }
     }
-    sq(sk, 0, L"201", L"1", L"2", L"Dolda Connect daemon v" VERSION, NULL);
+    sq(sk, 0, L"201", L"1", L"3", L"Dolda Connect daemon v" VERSION, NULL);
 }
 
 static void cmd_notfound(struct socket *sk, struct uidata *data, int argc, wchar_t **argv)
@@ -694,7 +696,7 @@ static void cmd_lspeers(struct socket *sk, struct uidata *data, int argc, wchar_
 {
     int i;
     struct fnetnode *fn;
-    struct fnetpeer *peer;
+    struct fnetpeer *peer, *npeer;
     
     haveargs(2);
     if((fn = findfnetnode(wcstol(argv[1], NULL, 0))) == NULL)
@@ -704,11 +706,12 @@ static void cmd_lspeers(struct socket *sk, struct uidata *data, int argc, wchar_
     }
     if(fn->peers == NULL)
     {
-       sq(sk, 0, L"201", L"No peers avaiable", NULL);
+       sq(sk, 0, L"201", L"No peers available", NULL);
     } else {
-       for(peer = fn->peers; peer != NULL; peer = peer->next)
+       for(peer = btreeiter(fn->peers); peer != NULL; peer = npeer)
        {
-           sq(sk, 2 | ((peer->next != NULL)?1:0), L"200", L"%ls", peer->id, L"%ls", peer->nick, NULL);
+           npeer = btreeiter(NULL);
+           sq(sk, 2 | ((npeer != NULL)?1:0), L"200", L"%ls", peer->id, L"%ls", peer->nick, NULL);
            for(i = 0; i < peer->dinum; i++)
            {
                if(peer->peerdi[i].datum->datatype == FNPD_INT)
@@ -1211,6 +1214,7 @@ static void cmd_filtercmd(struct socket *sk, struct uidata *data, int argc, wcha
     for(pp = cargv; *pp; pp++)
        free(*pp);
     free(cargv);
+    free(filtercmd);
     data->fcmdsk = wrapsock(pipe);
     data->fcmdpid = pid;
     if(data->fcmdbuf != NULL)
@@ -1420,6 +1424,7 @@ static struct qcommand *unlinkqcmd(struct uidata *data)
     qcmd = data->queue;
     if(qcmd != NULL)
     {
+       data->queuesize--;
        data->queue = qcmd->next;
        if(qcmd == data->queuelast)
            data->queuelast = qcmd->next;
@@ -1559,6 +1564,7 @@ static void freeuidata(struct uidata *data)
        actives = data->next;
     data->sk->readcb = NULL;
     data->sk->errcb = NULL;
+    closesock(data->sk);
     putsock(data->sk);
     while((qcmd = unlinkqcmd(data)) != NULL)
        freequeuecmd(qcmd);
@@ -1609,6 +1615,7 @@ static void queuecmd(struct uidata *data, struct command *cmd, int argc, wchar_t
     data->queuelast = new;
     if(data->queue == NULL)
        data->queue = new;
+    data->queuesize++;
 }
 
 static struct uidata *newuidata(struct socket *sk)
@@ -1801,6 +1808,11 @@ static void uiread(struct socket *sk, struct uidata *data)
            break;
        }
     }
+    if(data->cbdata > 16384)
+    {
+       /* Kill clients that send us unreasonably long lines */
+       data->close = 1;
+    }
 }
 
 static void uierror(struct socket *sk, int err, struct uidata *data)
@@ -2398,6 +2410,15 @@ static int run(void)
            freequeuecmd(qcmd);
            return(1);
        }
+       if(data->queuesize > 10)
+       {
+           /* Clients should not be queue up commands at all, since
+            * they should not send a new command before receiving a
+            * reply to the previous command. Therefore, we
+            * mercilessly massacre clients which are stacking up too
+            * many commands. */
+           data->close = 1;
+       }
     }
     return(0);
 }