Made the daemon 64-bit filesize capable.
authorFredrik Tolf <fredrik@dolda2000.com>
Thu, 14 Feb 2008 04:22:54 +0000 (05:22 +0100)
committerFredrik Tolf <fredrik@dolda2000.com>
Thu, 14 Feb 2008 04:22:54 +0000 (05:22 +0100)
daemon/Makefile.am
daemon/client.h
daemon/fnet-dc.c
daemon/net.c
daemon/search.h
daemon/transfer.c
daemon/transfer.h
daemon/ui.c

index 1ff686c..e809b60 100644 (file)
@@ -30,4 +30,4 @@ doldacond_SOURCES=    main.c \
 EXTRA_DIST=emacs-local
 doldacond_LDADD=$(top_srcdir)/common/libcommon.a \
                @KRB5_LIBS@ -lbz2 -lz -lgdbm @PAM_LIBS@ @KEYUTILS_LIBS@
-doldacond_CPPFLAGS=-I$(top_srcdir)/include -DDAEMON @KRB5_CFLAGS@ -D_ISOC99_SOURCE -D_BSD_SOURCE -D_SVID_SOURCE
+doldacond_CPPFLAGS=-I$(top_srcdir)/include -DDAEMON @KRB5_CFLAGS@ -D_ISOC99_SOURCE -D_BSD_SOURCE -D_SVID_SOURCE -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64
index aa15d42..19708d2 100644 (file)
@@ -58,7 +58,7 @@ struct sharecache
     struct sharecache *next, *prev, *child, *parent;
     char *path;
     wchar_t *name;
-    size_t size;
+    off_t size;
     time_t mtime;
     dev_t dev;
     ino_t inode;
index 01592c6..d934025 100644 (file)
@@ -127,7 +127,7 @@ struct dcpeer
     struct fnetnode *fn;
     char *inbuf;
     size_t inbufdata, inbufsize;
-    size_t curread, totalsize;
+    off_t curread, totalsize;
     int freeing;
     struct timer *timeout;
     struct qcommand *queue;
@@ -502,7 +502,11 @@ static void sendadc(struct socket *sk, char *arg)
     free(buf);
 }
 
-static void sendadcf(struct socket *sk, char *arg, ...)
+#if defined(__GNUC__)
+static void __attribute__ ((format (printf, 2, 3))) sendadcf(struct socket *sk, char *arg, ...) 
+#else
+static void sendadcf(struct socket *sk, char *arg, ...) 
+#endif
 {
     char *buf;
     va_list args;
@@ -740,8 +744,8 @@ static void requestfile(struct dcpeer *peer)
        }
        sendadc(peer->sk, buf);
        free(buf);
-       sendadcf(peer->sk, "%i", peer->transfer->curpos);
-       sendadcf(peer->sk, "%i", peer->transfer->size - peer->transfer->curpos);
+       sendadcf(peer->sk, "%ji", (intmax_t)peer->transfer->curpos);
+       sendadcf(peer->sk, "%ji", (intmax_t)(peer->transfer->size - peer->transfer->curpos));
        qstr(peer->sk, "|");
     } else if(supports(peer, "xmlbzlist")) {
        if((buf = icswcstombs(peer->transfer->path, "UTF-8", NULL)) == NULL)
@@ -750,7 +754,7 @@ static void requestfile(struct dcpeer *peer)
            freedcpeer(peer);
            return;
        }
-       qstrf(peer->sk, "$UGetBlock %zi %zi %s|", peer->transfer->curpos, peer->transfer->size - peer->transfer->curpos, buf);
+       qstrf(peer->sk, "$UGetBlock %ji %ji %s|", (intmax_t)peer->transfer->curpos, (intmax_t)(peer->transfer->size - peer->transfer->curpos), buf);
     } else {
        /* Use DCCHARSET for $Get paths until further researched... */
        if((buf = icswcstombs(peer->transfer->path, DCCHARSET, NULL)) == NULL)
@@ -759,7 +763,7 @@ static void requestfile(struct dcpeer *peer)
            freedcpeer(peer);
            return;
        }
-       qstrf(peer->sk, "$Get %s$%zi|", buf, peer->transfer->curpos + 1);
+       qstrf(peer->sk, "$Get %s$%ji|", buf, (intmax_t)peer->transfer->curpos + 1);
     }
 }
 
@@ -1257,10 +1261,10 @@ static void cmd_search(struct socket *sk, struct fnetnode *fn, char *cmd, char *
                if(node->f.b.hastth)
                {
                    buf2 = base32encode(node->hashtth, 24);
-                   qstrf(dsk, "%s%s\005%zi%sTTH:%.39s%s", prefix, buf, node->size, infix, buf2, postfix);
+                   qstrf(dsk, "%s%s\005%ji%sTTH:%.39s%s", prefix, buf, (intmax_t)node->size, infix, buf2, postfix);
                    free(buf2);
                } else {
-                   qstrf(dsk, "%s%s\005%zi%s%s%s", prefix, buf, node->size, infix, hub->nativename, postfix);
+                   qstrf(dsk, "%s%s\005%ji%s%s%s", prefix, buf, (intmax_t)node->size, infix, hub->nativename, postfix);
                }
                free(buf);
            }
@@ -1410,7 +1414,8 @@ static void cmd_sr(struct socket *sk, struct fnetnode *fn, char *cmd, char *args
     struct dchub *hub;
     char *p, *p2, *buf;
     char *nick, *filename, *hubname;
-    int size, slots;
+    off_t size;
+    int slots;
     size_t buflen;
     struct srchres *sr;
     wchar_t *wnick, *wfile;
@@ -1429,7 +1434,7 @@ static void cmd_sr(struct socket *sk, struct fnetnode *fn, char *cmd, char *args
     if((p2 = strchr(p, ' ')) == NULL)
        return;
     *p2 = 0;
-    size = atoi(p);
+    size = strtoll(p, NULL, 10);
     p = p2 + 1;
     if((p2 = strchr(p, '/')) == NULL)
        return;
@@ -1704,7 +1709,7 @@ static void startul(struct dcpeer *peer)
 
 static void cmd_filelength(struct socket *sk, struct dcpeer *peer, char *cmd, char *args)
 {
-    int size;
+    off_t size;
     struct transfer *transfer;
     
     if(peer->transfer == NULL)
@@ -1712,7 +1717,7 @@ static void cmd_filelength(struct socket *sk, struct dcpeer *peer, char *cmd, ch
        freedcpeer(peer);
        return;
     }
-    size = atoi(args);
+    size = strtoll(args, NULL, 10);
     if(peer->transfer->size != size)
     {
        transfersetsize(peer->transfer, size);
@@ -1835,7 +1840,7 @@ static struct sharecache *resdcpath(char *path, char *charset, char sep)
 
 static void cmd_get(struct socket *sk, struct dcpeer *peer, char *cmd, char *args)
 {
-    int offset;
+    off_t offset;
     char *p, *buf;
     wchar_t *buf2;
     struct sharecache *node;
@@ -1854,7 +1859,7 @@ static void cmd_get(struct socket *sk, struct dcpeer *peer, char *cmd, char *arg
        return;
     }
     *(p++) = 0;
-    if((offset = (atoi(p) - 1)) < 0)
+    if((offset = (strtoll(p, NULL, 10) - 1)) < 0)
     {
        freedcpeer(peer);
        return;
@@ -1917,7 +1922,7 @@ static void cmd_get(struct socket *sk, struct dcpeer *peer, char *cmd, char *arg
     lesk = wrapsock(fd);
     transferprepul(peer->transfer, sb.st_size, offset, -1, lesk);
     putsock(lesk);
-    qstrf(sk, "$FileLength %zi|", peer->transfer->size);
+    qstrf(sk, "$FileLength %ji|", (intmax_t)peer->transfer->size);
 }
 
 static void cmd_send(struct socket *sk, struct dcpeer *peer, char *cmd, char *args)
@@ -1968,7 +1973,7 @@ static void cmd_getblock(struct socket *sk, struct dcpeer *peer, char *cmd, char
 {
     int fd;
     char *p, *p2;
-    int start, numbytes;
+    off_t start, numbytes;
     char *charset, *buf;
     wchar_t *buf2;
     struct sharecache *node;
@@ -1987,7 +1992,7 @@ static void cmd_getblock(struct socket *sk, struct dcpeer *peer, char *cmd, char
        return;
     }
     *(p2++) = 0;
-    start = atoi(p);
+    start = strtoll(p, NULL, 10);
     p = p2;
     if((p2 = strchr(p, ' ')) == NULL)
     {
@@ -1995,7 +2000,7 @@ static void cmd_getblock(struct socket *sk, struct dcpeer *peer, char *cmd, char
        return;
     }
     *(p2++) = 0;
-    numbytes = atoi(p);
+    numbytes = strtoll(p, NULL, 10);
     p = p2;
     if(!strcmp(cmd, "$UGetBlock") || !strcmp(cmd, "$UGetZBlock"))
        charset = "UTF-8";
@@ -2057,7 +2062,7 @@ static void cmd_getblock(struct socket *sk, struct dcpeer *peer, char *cmd, char
     lesk = wrapsock(fd);
     transferprepul(peer->transfer, sb.st_size, start, start + numbytes, lesk);
     putsock(lesk);
-    qstrf(sk, "$Sending %i|", numbytes);
+    qstrf(sk, "$Sending %ji|", (intmax_t)numbytes);
     startul(peer);
 }
 
@@ -2065,7 +2070,7 @@ static void cmd_adcget(struct socket *sk, struct dcpeer *peer, char *cmd, char *
 {
     int i;
     char **argv, *buf;
-    int start, numbytes;
+    off_t start, numbytes;
     struct sharecache *node;
     struct stat sb;
     struct socket *lesk;
@@ -2087,8 +2092,8 @@ static void cmd_adcget(struct socket *sk, struct dcpeer *peer, char *cmd, char *
        freedcpeer(peer);
        goto out;
     }
-    start = atoi(argv[2]);
-    numbytes = atoi(argv[3]);
+    start = strtoll(argv[2], NULL, 10);
+    numbytes = strtoll(argv[3], NULL, 10);
     node = NULL;
     fd = -1;
     if(((fd = openfilelist(argv[1])) < 0) && (errno != 0))
@@ -2161,8 +2166,8 @@ static void cmd_adcget(struct socket *sk, struct dcpeer *peer, char *cmd, char *
        qstr(sk, "$ADCSND");
        sendadc(sk, "file");
        sendadc(sk, argv[1]);
-       sendadcf(sk, "%i", start);
-       sendadcf(sk, "%i", numbytes);
+       sendadcf(sk, "%ji", (intmax_t)start);
+       sendadcf(sk, "%ji", (intmax_t)numbytes);
        if(peer->compress == CPRS_ZLIB)
            sendadc(sk, "ZL1");
        qstr(sk, "|");
@@ -2223,7 +2228,7 @@ static void handletthl(struct dcpeer *peer)
 static void cmd_adcsnd(struct socket *sk, struct dcpeer *peer, char *cmd, char *args)
 {
     char **argv;
-    int start, numbytes;
+    off_t start, numbytes;
     
     if(peer->transfer == NULL)
     {
@@ -2240,8 +2245,8 @@ static void cmd_adcsnd(struct socket *sk, struct dcpeer *peer, char *cmd, char *
        freedcpeer(peer);
        goto out;
     }
-    start = atoi(argv[2]);
-    numbytes = atoi(argv[3]);
+    start = strtoll(argv[2], NULL, 10);
+    numbytes = strtoll(argv[3], NULL, 10);
     if(!strcmp(argv[0], "tthl"))
     {
        if((start != 0) || (numbytes % 24 != 0))
@@ -2289,14 +2294,14 @@ static void cmd_adcsnd(struct socket *sk, struct dcpeer *peer, char *cmd, char *
 
 static void cmd_sending(struct socket *sk, struct dcpeer *peer, char *cmd, char *args)
 {
-    int numbytes;
+    off_t numbytes;
     
     if(peer->transfer == NULL)
     {
        freedcpeer(peer);
        return;
     }
-    numbytes = atoi(args);
+    numbytes = strtoll(args, NULL, 10);
     if(peer->transfer->size - peer->transfer->curpos != numbytes)
     {
        transfersetsize(peer->transfer, peer->transfer->curpos + numbytes);
@@ -2811,7 +2816,8 @@ static void udpread(struct socket *sk, void *data)
     size_t buflen, hashlen;
     char *nick, *filename, *hubname;
     struct sockaddr_in hubaddr;
-    int size, slots;
+    off_t size;
+    int slots;
     struct fnetnode *fn, *myfn;
     struct dchub *hub;
     struct srchres *sr;
@@ -2847,7 +2853,7 @@ static void udpread(struct socket *sk, void *data)
            return;
        }
        *p2 = 0;
-       size = atoi(p);
+       size = strtoll(p, NULL, 10);
        p = p2 + 1;
        if((p2 = strchr(p, '/')) == NULL)
        {
@@ -3317,7 +3323,7 @@ static void updatehmlist(void)
            if(node->f.b.type == FILE_REG)
            {
                addtobuf(buf, '|');
-               sprintf(numbuf, "%zi", node->size);
+               sprintf(numbuf, "%ji", (intmax_t)node->size);
                bufcat(buf, numbuf, strlen(numbuf));
            }
            addtobuf(buf, 13);
@@ -3492,7 +3498,7 @@ static void updatexmllist(void)
                lev++;
                continue;
            } else {
-               fprintf(fs, "<File Name=\"%s\" Size=\"%zi\"", namebuf, node->size);
+               fprintf(fs, "<File Name=\"%s\" Size=\"%ji\"", namebuf, (intmax_t)node->size);
                if(node->f.b.hastth)
                {
                    hashbuf = base32encode(node->hashtth, 24);
index 9b5a34a..e0d12af 100644 (file)
@@ -388,12 +388,17 @@ static void sockrecv(struct socket *sk)
 #if defined(HAVE_LINUX_SOCKIOS_H) && defined(SIOCINQ)
        /* SIOCINQ is Linux-specific AFAIK, but I really have no idea
         * how to read the inqueue size on other OSs */
-       if(ioctl(sk->fd, SIOCINQ, &inq))
-       {
-           /* I don't really know what could go wrong here, so let's
-            * assume it's transient. */
-           flog(LOG_WARNING, "SIOCINQ return %s on socket %i, falling back to 2048 bytes", strerror(errno), sk->fd);
-           inq = 2048;
+       if(sk->isrealsocket) {
+           if(ioctl(sk->fd, SIOCINQ, &inq))
+           {
+               /* I don't really know what could go wrong here, so let's
+                * assume it's transient. */
+               flog(LOG_WARNING, "SIOCINQ return %s on socket %i, falling back to 2048 bytes", strerror(errno), sk->fd);
+               inq = 2048;
+           }
+       } else {
+           /* There are perils when trying to use SIOCINQ on files >2GiB... */
+           inq = 65536;
        }
 #else
        inq = 2048;
index 990391e..230436c 100644 (file)
@@ -104,7 +104,7 @@ struct srchres
     wchar_t *filename;
     struct fnet *fnet;
     wchar_t *peerid, *peernick;
-    size_t size;
+    off_t size;
     int slots;
     struct fnetnode *fn;
     double time;
index e2fe54e..c432815 100644 (file)
@@ -305,7 +305,7 @@ void *transfergetdata(struct transfer *transfer, size_t *size)
     return(buf);
 }
 
-void transferprepul(struct transfer *transfer, size_t size, size_t start, size_t end, struct socket *lesk)
+void transferprepul(struct transfer *transfer, off_t size, off_t start, off_t end, struct socket *lesk)
 {
     transfersetsize(transfer, size);
     transfer->curpos = start;
@@ -461,7 +461,7 @@ void transfersetnick(struct transfer *transfer, wchar_t *newnick)
     CBCHAINDOCB(transfer, trans_ac, transfer, L"nick");
 }
 
-void transfersetsize(struct transfer *transfer, int newsize)
+void transfersetsize(struct transfer *transfer, off_t newsize)
 {
     transfer->size = newsize;
     CBCHAINDOCB(transfer, trans_ac, transfer, L"size");
@@ -670,7 +670,7 @@ int forkfilter(struct transfer *transfer)
     {
        argv = NULL;
        argvsize = argvdata = 0;
-       buf = sprintf2("%zi", transfer->size);
+       buf = sprintf2("%ji", (intmax_t)transfer->size);
        addtobuf(argv, filtername);
        addtobuf(argv, filename);
        addtobuf(argv, buf);
index 06b334f..b4ffa69 100644 (file)
@@ -73,7 +73,7 @@ struct transfer
     wchar_t *path;
     uid_t owner;
     int state, dir, error;
-    size_t size, curpos, endpos;
+    off_t size, curpos, endpos;
     struct fnetnode *fn;
     void *ifacedata;
     struct socket *localend;
@@ -103,7 +103,7 @@ struct transfer *newupload(struct fnetnode *fn, struct fnet *fnet, wchar_t *nick
 void transfersetnick(struct transfer *transfer, wchar_t *newnick);
 void transfersetpath(struct transfer *transfer, wchar_t *newpath);
 void transfersetstate(struct transfer *transfer, int newstate);
-void transfersetsize(struct transfer *transfer, int newsize);
+void transfersetsize(struct transfer *transfer, off_t newsize);
 void transferseterror(struct transfer *transfer, int error);
 void transfersetactivity(struct transfer *transfer, wchar_t *desc);
 void transferattach(struct transfer *transfer, struct transferiface *iface, void *data);
@@ -115,7 +115,7 @@ int forkfilter(struct transfer *transfer);
 void transferputdata(struct transfer *transfer, void *buf, size_t size);
 size_t transferdatasize(struct transfer *transfer);
 void transferendofdata(struct transfer *transfer);
-void transferprepul(struct transfer *transfer, size_t size, size_t start, size_t end, struct socket *lesk);
+void transferprepul(struct transfer *transfer, off_t size, off_t start, off_t end, struct socket *lesk);
 void transferstartul(struct transfer *transfer, struct socket *sk);
 void transfersethash(struct transfer *transfer, struct hash *hash);
 struct transfer *finddownload(wchar_t *peerid);
index 9604a93..dd3d931 100644 (file)
@@ -62,6 +62,7 @@
 #define NOTIF_STR 2
 #define NOTIF_FLOAT 3
 #define NOTIF_ID 4
+#define NOTIF_OFF 5
 #define NOTIF_PEND 0
 #define NOTIF_WAIT 1
 
@@ -105,6 +106,7 @@ struct notif
        union
        {
            int n;
+           off_t o;
            wchar_t *s;
            double d;
        } d;
@@ -232,6 +234,12 @@ static void sq(struct socket *sk, int cont, ...)
            {
                freepart = 1;
                part = swprintf2(L"%i", va_arg(al, int));
+           } else if(!wcscmp(tpart, L"zi")) {
+               freepart = 1;
+               part = swprintf2(L"%zi", va_arg(al, size_t));
+           } else if(!wcscmp(tpart, L"oi")) {
+               freepart = 1;
+               part = swprintf2(L"%ji", (intmax_t)va_arg(al, off_t));
            } else if(!wcscmp(tpart, L"s")) {
                freepart = 1;
                part = icmbstowcs(sarg = va_arg(al, char *), NULL);
@@ -764,7 +772,7 @@ static void cmd_download(struct socket *sk, struct uidata *data, int argc, wchar
        linktransfer(transfer);
     }
     if(argc > 4)
-       transfersetsize(transfer, wcstol(argv[4], NULL, 0));
+       transfersetsize(transfer, wcstoll(argv[4], NULL, 0));
     if(argc > 5)
     {
        for(i = 5; i < argc; i += 2)
@@ -796,7 +804,7 @@ static void cmd_lstrans(struct socket *sk, struct uidata *data, int argc, wchar_
                   L"%i", pt->state, pt->peerid,
                   (pt->peernick == NULL)?L"":(pt->peernick),
                   (pt->path == NULL)?L"":(pt->path),
-                  L"%i", pt->size, L"%i", pt->curpos,
+                  L"%oi", pt->size, L"%oi", pt->curpos,
                   (pt->hash == NULL)?L"":unparsehash(pt->hash),
                   NULL);
            pt = transfer;
@@ -809,7 +817,7 @@ static void cmd_lstrans(struct socket *sk, struct uidata *data, int argc, wchar_
           L"%i", pt->state, pt->peerid,
           (pt->peernick == NULL)?L"":(pt->peernick),
           (pt->path == NULL)?L"":(pt->path),
-          L"%i", pt->size, L"%i", pt->curpos,
+          L"%oi", pt->size, L"%oi", pt->curpos,
           (pt->hash == NULL)?L"":unparsehash(pt->hash),
           NULL);
 }
@@ -1048,7 +1056,7 @@ static void cmd_lssr(struct socket *sk, struct uidata *data, int argc, wchar_t *
        for(sr = srch->results; sr != NULL; sr = sr->next)
        {
            sq(sk, (sr->next != NULL)?1:0, L"200", L"%ls", sr->filename,
-              sr->fnet->name, L"%ls", sr->peerid, L"%i", sr->size,
+              sr->fnet->name, L"%ls", sr->peerid, L"%oi", sr->size,
               L"%i", sr->slots, L"%i", (sr->fn == NULL)?-1:(sr->fn->id),
               L"%f", sr->time,
               L"%ls", (sr->hash == NULL)?L"":unparsehash(sr->hash), NULL);
@@ -1434,6 +1442,9 @@ static void notifappendv(struct notif *notif, va_list args)
        case NOTIF_ID:
            notif->argv[ca].d.n = va_arg(args, int);
            break;
+       case NOTIF_OFF:
+           notif->argv[ca].d.o = va_arg(args, off_t);
+           break;
        case NOTIF_STR:
            notif->argv[ca].d.s = swcsdup(va_arg(args, wchar_t *));
            break;
@@ -1844,7 +1855,7 @@ static int srchres(struct search *srch, struct srchres *sr, void *uudata)
     {
        if(haspriv(data, PERM_SRCH) && data->notify.b.srch && !wcscmp(srch->owner, data->username))
        {
-           newnotif(data, 622, NOTIF_ID, srch->id, NOTIF_STR, sr->filename, NOTIF_STR, sr->fnet->name, NOTIF_STR, sr->peerid, NOTIF_INT, sr->size,
+           newnotif(data, 622, NOTIF_ID, srch->id, NOTIF_STR, sr->filename, NOTIF_STR, sr->fnet->name, NOTIF_STR, sr->peerid, NOTIF_OFF, sr->size,
                     NOTIF_INT, sr->slots, NOTIF_INT, (sr->fn == NULL)?-1:(sr->fn->id), NOTIF_FLOAT, sr->time, NOTIF_STR, (sr->hash == NULL)?L"":unparsehash(sr->hash), NOTIF_END);
        }
     }
@@ -2007,7 +2018,7 @@ static int transferchattr(struct transfer *transfer, wchar_t *attrib, void *uuda
        for(data = actives; data != NULL; data = data->next)
        {
            if(haspriv(data, PERM_TRANS) && data->notify.b.tract && ((transfer->owner == 0) || (transfer->owner == data->uid)))
-               newnotif(data, 613, NOTIF_ID, transfer->id, NOTIF_INT, transfer->size, NOTIF_END);
+               newnotif(data, 613, NOTIF_ID, transfer->id, NOTIF_OFF, transfer->size, NOTIF_END);
        }
     } else if(!wcscmp(attrib, L"error")) {
        for(data = actives; data != NULL; data = data->next)
@@ -2041,9 +2052,9 @@ static int transferprog(struct transfer *transfer, void *uudata)
        if(haspriv(data, PERM_TRANS) && data->notify.b.trprog && ((transfer->owner == 0) || (transfer->owner == data->uid)))
        {
            if((notif = findnotif(data->fnotif, 1, NOTIF_PEND, 615, transfer->id)) != NULL)
-               notif->argv[1].d.n = transfer->curpos;
+               notif->argv[1].d.o = transfer->curpos;
            else
-               newnotif(data, 615, NOTIF_ID, transfer->id, NOTIF_INT, transfer->curpos, NOTIF_END)->rlimit = 0.5;
+               newnotif(data, 615, NOTIF_ID, transfer->id, NOTIF_OFF, transfer->curpos, NOTIF_END)->rlimit = 0.5;
        }
     }
     return(0);
@@ -2358,6 +2369,9 @@ static int run(void)
                case NOTIF_ID:
                    sq(data->sk, 2, L"%i", notif->argv[i].d.n, NULL);
                    break;
+               case NOTIF_OFF:
+                   sq(data->sk, 2, L"%oi", notif->argv[i].d.o, NULL);
+                   break;
                case NOTIF_STR:
                    if(notif->argv[i].d.s[0] == L'%')
                        sq(data->sk, 2, L"%ls", notif->argv[i].d.s, NULL);