Fixed some typos.
[doldaconnect.git] / daemon / ui.c
index a2ec720..9c89b50 100644 (file)
@@ -159,6 +159,8 @@ struct uidata
     size_t cwsize, cwdata;
 };
 
+static int uiread(struct socket *sk, struct uidata *data);
+static int uierror(struct socket *sk, int err, struct uidata *data);
 static int srcheta(struct search *srch, void *uudata);
 static int srchcommit(struct search *srch, void *uudata);
 static int srchres(struct search *srch, struct srchres *sr, void *uudata);
@@ -168,6 +170,7 @@ static void notifappend(struct notif *notif, ...);
 struct uiuser *users = NULL;
 struct uidata *actives = NULL;
 struct socket *uisocket = NULL;
+static time_t starttime;
 
 static wchar_t *quoteword(wchar_t *word)
 {
@@ -589,7 +592,7 @@ static void cmd_fnetconnect(struct socket *sk, struct uidata *data, int argc, wc
     args = NULL;
     for(i = 3; i < argc - 1; i += 2)
        newwcspair(argv[i], argv[i + 1], &args);
-    fn = fnetinitconnect(argv[1], buf, args);
+    fn = fnetinitconnect(argv[1], data->userinfo->name, buf, args);
     err = errno;
     free(buf);
     if(fn == NULL)
@@ -640,6 +643,11 @@ static void cmd_disconnect(struct socket *sk, struct uidata *data, int argc, wch
            sq(sk, 0, L"510", L"No such node", NULL);
            return;
        }
+       if(wpfind(fn->args, L"locked") && !((data->userinfo->perms & PERM_ADMIN) || !wcscmp(data->userinfo->name, fn->owner)))
+       {
+           sq(sk, 0, L"502", L"This node is locked and you are neither administrator nor its owner", NULL);
+           return;
+       }
        killfnetnode(fn);
        unlinkfnetnode(fn);
     }
@@ -685,7 +693,7 @@ static void cmd_lspeers(struct socket *sk, struct uidata *data, int argc, wchar_
     } else {
        for(peer = fn->peers; peer != NULL; peer = peer->next)
        {
-           sq(sk, 2 | ((peer->next != NULL)?1:0), L"200", peer->id, peer->nick, NULL);
+           sq(sk, 2 | ((peer->next != NULL)?1:0), L"200", L"%%s", peer->id, L"%%s", peer->nick, NULL);
            for(i = 0; i < peer->dinum; i++)
            {
                if(peer->peerdi[i].datum->datatype == FNPD_INT)
@@ -698,7 +706,7 @@ static void cmd_lspeers(struct socket *sk, struct uidata *data, int argc, wchar_
                    sq(sk, 2, peer->peerdi[i].datum->id, buf, NULL);
                }
                if((peer->peerdi[i].datum->datatype == FNPD_STR) && (peer->peerdi[i].data.str != NULL))
-                   sq(sk, 2, peer->peerdi[i].datum->id, peer->peerdi[i].data.str, NULL);
+                   sq(sk, 2, peer->peerdi[i].datum->id, L"%%s", peer->peerdi[i].data.str, NULL);
            }
            sq(sk, 0, NULL);
        }
@@ -1048,18 +1056,19 @@ static void cmd_cansrch(struct socket *sk, struct uidata *data, int argc, wchar_
     sq(sk, 0, L"200", L"Search cancelled", NULL);
 }
 
-static void fcmdread(struct socket *sk, struct uidata *data)
+static int fcmdread(struct socket *sk, struct uidata *data)
 {
     char *buf;
     size_t bufsize;
     
     if((buf = sockgetinbuf(sk, &bufsize)) == NULL)
-       return;
+       return(0);
     bufcat(data->fcmdbuf, buf, bufsize);
     free(buf);
+    return(0);
 }
 
-static void fcmderr(struct socket *sk, int err, struct uidata *data)
+static int fcmderr(struct socket *sk, int err, struct uidata *data)
 {
     wchar_t *wbuf, *p, *p2;
     
@@ -1076,7 +1085,7 @@ static void fcmderr(struct socket *sk, int err, struct uidata *data)
        }
        data->fcmdbufsize = data->fcmdbufdata = 0;
        sq(data->sk, 0, L"505", L"An error occurred on the pipe to the filtercmd", L"%%s", strerror(err), NULL);
-       return;
+       return(0);
     }
     putsock(data->fcmdsk);
     data->fcmdsk = NULL;
@@ -1094,7 +1103,7 @@ static void fcmderr(struct socket *sk, int err, struct uidata *data)
     if(wbuf == NULL)
     {
        sq(data->sk, 0, L"504", L"Filtercmd sent data which could not be converted from the local charset", NULL);
-       return;
+       return(0);
     }
     p = wbuf;
     for(p2 = wcschr(p, L'\n'); p2 != NULL; p2 = wcschr(p, L'\n'))
@@ -1111,6 +1120,7 @@ static void fcmderr(struct socket *sk, int err, struct uidata *data)
        sq(data->sk, 0, L"200", L"%%ls", p, NULL);
     }
     free(wbuf);
+    return(0);
 }
 
 static void cmd_filtercmd(struct socket *sk, struct uidata *data, int argc, wchar_t **argv)
@@ -1176,9 +1186,8 @@ static void cmd_filtercmd(struct socket *sk, struct uidata *data, int argc, wcha
        data->fcmdbuf = NULL;
     }
     data->fcmdbufsize = data->fcmdbufdata = 0;
-    data->fcmdsk->data = data;
-    data->fcmdsk->readcb = (void (*)(struct socket *, void *))fcmdread;
-    data->fcmdsk->errcb = (void (*)(struct socket *, int, void *))fcmderr;
+    CBREG(data->fcmdsk, socket_read, (int (*)(struct socket *, void *))fcmdread, NULL, data);
+    CBREG(data->fcmdsk, socket_err, (int (*)(struct socket *, int, void *))fcmderr, NULL, data);
 }
 
 static void cmd_lstrarg(struct socket *sk, struct uidata *data, int argc, wchar_t **argv)
@@ -1251,7 +1260,7 @@ static void cmd_register(struct socket *sk, struct uidata *data, int argc, wchar
        return;
     }
     for(d2 = actives; d2 != NULL; d2 = d2->next) {
-       if((d2 != data) && d2->regname && !wcscmp(d2->regname, argv[1])) {
+       if((d2 != data) && (d2->userinfo == data->userinfo) && d2->regname && !wcscmp(d2->regname, argv[1])) {
            sq(sk, 0, L"516", L"Name already in use", NULL);
            return;
        }
@@ -1277,12 +1286,12 @@ static void cmd_sendmsg(struct socket *sk, struct uidata *data, int argc, wchar_
     if(argv[1][0] == L'#') {
        rcptid = wcstol(argv[1] + 1, NULL, 0);
        for(rcpt = actives; rcpt != NULL; rcpt = rcpt->next) {
-           if(rcpt->id == rcptid)
+           if((rcpt->userinfo == data->userinfo) && (rcpt->id == rcptid))
                break;
        }
     } else {
        for(rcpt = actives; rcpt != NULL; rcpt = rcpt->next) {
-           if(rcpt->regname && !wcscmp(rcpt->regname, argv[1]))
+           if((rcpt->userinfo == data->userinfo) && rcpt->regname && !wcscmp(rcpt->regname, argv[1]))
                break;
        }
     }
@@ -1304,6 +1313,11 @@ static void cmd_sendmsg(struct socket *sk, struct uidata *data, int argc, wchar_
     sq(sk, 0, L"200", L"Message sent", NULL);
 }
 
+static void cmd_uptime(struct socket *sk, struct uidata *data, int argc, wchar_t **argv)
+{
+    sq(sk, 0, L"200", L"%%i", time(NULL) - starttime, NULL);
+}
+
 #undef haveargs
 #undef havepriv
 
@@ -1342,6 +1356,7 @@ static struct command commands[] =
     {L"transstatus", cmd_transstatus},
     {L"register", cmd_register},
     {L"sendmsg", cmd_sendmsg},
+    {L"uptime", cmd_uptime},
     {NULL, NULL}
 };
 
@@ -1499,8 +1514,8 @@ static void freeuidata(struct uidata *data)
        data->prev->next = data->next;
     if(data == actives)
        actives = data->next;
-    data->sk->readcb = NULL;
-    data->sk->errcb = NULL;
+    CBUNREG(data->sk, socket_read, uiread, data);
+    CBUNREG(data->sk, socket_err, uierror, data);
     putsock(data->sk);
     while((qcmd = unlinkqcmd(data)) != NULL)
        freequeuecmd(qcmd);
@@ -1578,7 +1593,7 @@ static struct uidata *newuidata(struct socket *sk)
     return(data);
 }
 
-static void uiread(struct socket *sk, struct uidata *data)
+static int uiread(struct socket *sk, struct uidata *data)
 {
     int ret, done;
     char *newbuf;
@@ -1590,7 +1605,7 @@ static void uiread(struct socket *sk, struct uidata *data)
     if(data->indata > 1024)
        data->indata = 0;
     if((newbuf = sockgetinbuf(sk, &datalen)) == NULL)
-       return;
+       return(0);
     sizebuf(&data->inbuf, &data->inbufsize, data->indata + datalen, 1, 1);
     memcpy(data->inbuf + data->indata, newbuf, datalen);
     free(newbuf);
@@ -1743,26 +1758,29 @@ static void uiread(struct socket *sk, struct uidata *data)
            break;
        }
     }
+    return(0);
 }
 
-static void uierror(struct socket *sk, int err, struct uidata *data)
+static int uierror(struct socket *sk, int err, struct uidata *data)
 {
     if(err)
        flog(LOG_WARNING, "error occurred on UI socket: %s", strerror(err));
     freeuidata(data);
+    return(0);
 }
 
-static void uiaccept(struct socket *sk, struct socket *newsk, void *data)
+static int uiaccept(struct socket *sk, struct socket *newsk, void *data)
 {
     struct uidata *uidata;
     
-    newsk->data = uidata = newuidata(newsk);
+    uidata = newuidata(newsk);
     socksettos(newsk, confgetint("ui", "uitos"));
     if(uidata == NULL)
-       return;
-    newsk->errcb = (void (*)(struct socket *, int, void *))uierror;
-    newsk->readcb = (void (*)(struct socket *, void *))uiread;
+       return(0);
+    CBREG(newsk, socket_err, (int (*)(struct socket *, int, void *))uierror, NULL, uidata);
+    CBREG(newsk, socket_read, (int (*)(struct socket *, void *))uiread, NULL, uidata);
     queuecmd(uidata, &commands[0], 0, NULL);
+    return(0);
 }
 
 static int srcheta(struct search *srch, void *uudata)
@@ -2153,6 +2171,7 @@ static int init(int hup)
     }
     if(!hup)
     {
+       starttime = time(NULL);
        if(uisocket != NULL)
            putsock(uisocket);
        if((uisocket = netcstcplisten(confgetint("ui", "port"), 1, uiaccept, NULL)) == NULL)