Removed every instance of malloc.h.
[doldaconnect.git] / daemon / fnet-dc.c
index 772306c..c88deef 100644 (file)
@@ -19,7 +19,6 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <wchar.h>
-#include <malloc.h>
 #include <unistd.h>
 #include <fcntl.h>
 #include <string.h>
@@ -44,7 +43,7 @@
 #include "transfer.h"
 #include "sysevents.h"
 #include "net.h"
-#include "tiger.h"
+#include <tiger.h>
 
 /*
  * The Direct Connect protocol is extremely ugly. Thus, this code must
@@ -158,6 +157,7 @@ static struct dcexppeer *expected = NULL;
 static char *hmlistname = NULL;
 static char *xmllistname = NULL;
 static char *xmlbz2listname = NULL;
+static struct timer *listwritetimer = NULL;
 
 static void peerconnect(struct socket *sk, int err, struct fnetnode *fn);
 static void freedcpeer(struct dcpeer *peer);
@@ -168,6 +168,7 @@ static void updatehmlist(void);
 static void updatexmllist(void);
 static void updatexmlbz2list(void);
 static void requestfile(struct dcpeer *peer);
+static void updatelists(int now);
 
 static int reservedchar(unsigned char c)
 {
@@ -1017,7 +1018,7 @@ static void cmd_forcemove(struct socket *sk, struct fnetnode *fn, char *cmd, cha
     } else {
        freeargs = 0;
     }
-    if((newfn = fnetinitconnect(L"dc", args, NULL)) != NULL)
+    if((newfn = fnetinitconnect(L"dc", fn->owner, args, NULL)) != NULL)
     {
        linkfnetnode(newfn);
        putfnetnode(newfn);
@@ -1167,10 +1168,11 @@ static void cmd_search(struct socket *sk, struct fnetnode *fn, char *cmd, char *
                if(!dotth && !strncmp(p, "TTH:", 4))
                {
                    dotth = 1;
-                   if((buf = base32decode(p + 4, &buflen)) == NULL)
-                       goto out;
-                   if(buflen != 24)
+                   if(((buf = base32decode(p + 4, &buflen)) == NULL) || (buflen != 24))
+                   {
+                       free(buf);
                        goto out;
+                   }
                    memcpy(hashtth, buf, 24);
                    free(buf);
                } else {
@@ -1309,7 +1311,7 @@ static void sendctm(struct socket *sk, char *nick)
     
     if(tcpsock == NULL)
        return;
-    if(sockgetremotename(tcpsock, &addr, &addrlen) < 0)
+    if(sockgetremotename2(tcpsock, sk, &addr, &addrlen) < 0)
        return;
     if(addr->sa_family == AF_INET)
        qstrf(sk, "$ConnectToMe %s %s|", nick, formataddress(addr, addrlen));
@@ -1544,6 +1546,11 @@ static void cmd_direction(struct socket *sk, struct dcpeer *peer, char *cmd, cha
        peer->direction = mydir;
        if(peer->direction == TRNSD_UP)
        {
+           if(confgetint("transfer", "ulquota") && hasupload(&dcnet, peer->wcsname))
+           {
+               freedcpeer(peer);
+               return;
+           }
            transfer = newupload(peer->fn, &dcnet, peer->wcsname, &dctransfer, peer);
        } else {
            if((transfer = finddownload(peer->wcsname)) == NULL)
@@ -1590,6 +1597,11 @@ static void cmd_peerlock(struct socket *sk, struct dcpeer *peer, char *cmd, char
            sendsupports(peer);
        if((transfer = finddownload(peer->wcsname)) == NULL)
        {
+           if(confgetint("transfer", "ulquota") && hasupload(&dcnet, peer->wcsname))
+           {
+               freedcpeer(peer);
+               return;
+           }
            peer->direction = TRNSD_UP;
            transfer = newupload(peer->fn, &dcnet, peer->wcsname, &dctransfer, peer);
        } else {
@@ -2414,8 +2426,10 @@ static struct hash *findsehash(struct sexpr *sexpr)
            return(h1);
        break;
     case SOP_OR:
-       h1 = findsehash(sexpr->l);
-       h2 = findsehash(sexpr->r);
+       if((h1 = findsehash(sexpr->l)) == NULL)
+           return(NULL);
+       if((h2 = findsehash(sexpr->r)) == NULL)
+           return(NULL);
        if(hashcmp(h1, h2))
            return(h1);
        break;
@@ -2518,7 +2532,7 @@ static int hubsearch(struct fnetnode *fn, struct search *srch, struct srchfnnlis
     addtobuf(sstr, 0);
     if(tcpsock != NULL)
     {
-       if(sockgetremotename(udpsock, &name, &namelen) < 0)
+       if(sockgetremotename2(udpsock, fn->sk, &name, &namelen) < 0)
        {
            flog(LOG_WARNING, "cannot get address of UDP socket");
        } else {
@@ -2539,7 +2553,7 @@ static int hubsearch(struct fnetnode *fn, struct search *srch, struct srchfnnlis
 #undef qstrf
 
 #define cc(c) ((void (*)(struct socket *, void *, char *, char *))(c))
-struct command hubcmds[] =
+static struct command hubcmds[] =
 {
     {"$Lock", cc(cmd_lock)},
     {"$HubName", cc(cmd_hubname)},
@@ -2562,7 +2576,7 @@ struct command hubcmds[] =
     {NULL, NULL}
 };
 
-struct command peercmds[] =
+static struct command peercmds[] =
 {
     {"$MyNick", cc(cmd_mynick)},
     {"$Lock", cc(cmd_peerlock)},
@@ -3501,11 +3515,33 @@ static void updatexmlbz2list(void)
     fclose(real);
 }
 
-static int shareupdate(unsigned long long uusharesize, void *data)
+static void listtimercb(int cancelled, void *uudata)
+{
+    listwritetimer = NULL;
+    if(!cancelled)
+       updatelists(1);
+}
+
+static void updatelists(int now)
 {
+    if((hmlistname == NULL) || (xmllistname == NULL) || (xmlbz2listname == NULL))
+       now = 1;
+    if(!now)
+    {
+       if(listwritetimer == NULL)
+           listwritetimer = timercallback(ntime() + 300, listtimercb, NULL);
+       return;
+    }
+    if(listwritetimer != NULL)
+       canceltimer(listwritetimer);
     updatehmlist();
     updatexmllist();
     updatexmlbz2list();
+}
+
+static int shareupdate(unsigned long long uusharesize, void *data)
+{
+    updatelists(0);
     return(0);
 }
 
@@ -3672,11 +3708,31 @@ static void terminate(void)
 
 static struct configvar myvars[] =
 {
+    /** Specifies the share description reported to other DC users. */
     {CONF_VAR_STRING, "desc", {.str = L""}},
+    /** Specifies the speed reported to other DC users. Normal values
+     * are 28.8Kbps, 33.6Kbps, 56Kbps, Satellite, ISDN, DSL, Cable,
+     * LAN(T1) or LAN(T3)*/
     {CONF_VAR_STRING, "speedstring", {.str = L"LAN(T1)"}},
+    /** The e-mail address to report to other DC users. */
     {CONF_VAR_STRING, "email", {.str = L"spam@spam.org"}},
+    /** Specifies a specific UDP port to use for DC search results. If
+     * left unspecified, a port is allocated dynamically. Useful for
+     * NAT routers (see also the net.visibleipv4 address for those
+     * cases). */
     {CONF_VAR_INT, "udpport", {.num = 0}},
+    /** Specifies a specific TCP port to use for DC peer
+     * connections. If left unspecified, a port is allocated
+     * dynamically. Useful for NAT routers (see also the
+     * net.visibleipv4 address for those cases). */
     {CONF_VAR_INT, "tcpport", {.num = 0}},
+    /** If set to true, doldacond will do its best to emulate DC++
+     * (currently v0.674). This should be left off if at all possible,
+     * since turning it on will violate the rules of most hubs and
+     * thus give hub owners an actual reason to kick you if it is
+     * detected. It might be needed for some of the more bone-headed
+     * hub owners, though. Note that DC++ emulation can also be turned
+     * on or off for individual hubs, overriding this setting. */
     {CONF_VAR_BOOL, "dcppemu", {.num = 0}},
     {CONF_VAR_END}
 };