X-Git-Url: http://dolda2000.com/gitweb/?a=blobdiff_plain;f=daemon%2Ffnet-dc.c;h=d93402529956dc73474bdcf3ab6493d8572fb4e6;hb=dcf7a1a214150f84d51159c9c679b7697cb05298;hp=90ae9d639acaf52dcdaa01fe3c543e65e4171d53;hpb=d05758f6eda21695e6215d60d28b9747d0b8aaa3;p=doldaconnect.git diff --git a/daemon/fnet-dc.c b/daemon/fnet-dc.c index 90ae9d6..d934025 100644 --- a/daemon/fnet-dc.c +++ b/daemon/fnet-dc.c @@ -1,6 +1,6 @@ /* * Dolda Connect - Modular multiuser Direct Connect-style client - * Copyright (C) 2004 Fredrik Tolf (fredrik@dolda2000.com) + * Copyright (C) 2004 Fredrik Tolf * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -101,6 +101,7 @@ struct qcommand struct dchub { + struct socket *sk; char *inbuf; size_t inbufdata, inbufsize; struct qcommand *queue; @@ -126,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; @@ -501,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; @@ -666,10 +671,14 @@ static void sendpeerlock(struct dcpeer *peer) static void sendsupports(struct dcpeer *peer) { - if(peer->dcppemu) + if(peer->dcppemu) { qstr(peer->sk, "$Supports MiniSlots XmlBZList ADCGet TTHL TTHF GetZBlock ZLIG |"); - else - qstr(peer->sk, "$Supports MiniSlots XmlBZList ADCGet TTHL TTHF GetZBlock ZLIG|"); + } else { + qstr(peer->sk, "$Supports MiniSlots XmlBZList ADCGet TTHL TTHF"); + if(!confgetint("dc", "hidedeflate")) + qstr(peer->sk, " GetZBlock ZLIG"); + qstr(peer->sk, "|"); + } } static void requestfile(struct dcpeer *peer) @@ -735,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) @@ -745,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) @@ -754,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); } } @@ -831,10 +840,14 @@ static void cmd_lock(struct socket *sk, struct fnetnode *fn, char *cmd, char *ar *(p++) = 0; if(hub->extended) { - if(hub->dcppemu) + if(hub->dcppemu) { qstrf(sk, "$Supports UserCommand NoGetINFO NoHello UserIP2 TTHSearch GetZBlock |"); - else - qstrf(sk, "$Supports UserCommand NoGetINFO NoHello UserIP2 TTHSearch GetZBlock|"); + } else { + qstrf(sk, "$Supports UserCommand NoGetINFO NoHello UserIP2 TTHSearch"); + if(!confgetint("dc", "hidedeflate")) + qstr(sk, " GetZBlock"); + qstr(sk, "|"); + } } key = dcmakekey(args); qstrf(sk, "$Key %s|", key); @@ -1127,7 +1140,7 @@ static void cmd_search(struct socket *sk, struct fnetnode *fn, char *cmd, char * goto out; prefix = sprintf2("$SR %s ", hub->nativenick); infix = sprintf2(" %i/%i\005", slotsleft(), confgetint("transfer", "slots")); - postfix = sprintf2(" (%s)\005%s|", formataddress(fn->sk->remote, fn->sk->remotelen), args + 4); + postfix = sprintf2(" (%s)\005%s|", formataddress(hub->sk->remote, hub->sk->remotelen), args + 4); dsk = sk; getsock(dsk); } else { @@ -1140,7 +1153,7 @@ static void cmd_search(struct socket *sk, struct fnetnode *fn, char *cmd, char * addr.sin_port = htons(atoi(p2)); prefix = sprintf2("$SR %s ", hub->nativenick); infix = sprintf2(" %i/%i\005", slotsleft(), confgetint("transfer", "slots")); - postfix = sprintf2(" (%s)|", formataddress(fn->sk->remote, fn->sk->remotelen)); + postfix = sprintf2(" (%s)|", formataddress(hub->sk->remote, hub->sk->remotelen)); netdgramconn(dsk = netdupsock(udpsock), (struct sockaddr *)&addr, sizeof(addr)); } @@ -1248,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); } @@ -1392,7 +1405,7 @@ static void cmd_to(struct socket *sk, struct fnetnode *fn, char *cmd, char *args return; *p2 = 0; p2 += 2; - hubrecvchat(fn->sk, fn, p, p2); + hubrecvchat(hub->sk, fn, p, p2); hubhandleaction(sk, fn, cmd, args); } @@ -1401,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; @@ -1420,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; @@ -1695,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) @@ -1703,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); @@ -1826,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; @@ -1845,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; @@ -1908,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) @@ -1959,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; @@ -1978,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) { @@ -1986,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"; @@ -2048,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); } @@ -2056,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; @@ -2078,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)) @@ -2152,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, "|"); @@ -2214,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) { @@ -2231,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)) @@ -2280,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); @@ -2339,10 +2353,10 @@ static int hubreqconn(struct fnetpeer *peer) return(1); /* Shouldn't happen, of course, but who knows... */ if(tcpsock != NULL) { - sendctm(peer->fn->sk, mbsnick); + sendctm(hub->sk, mbsnick); expectpeer(mbsnick, peer->fn); } else { - qstrf(peer->fn->sk, "$RevConnectToMe %s %s|", hub->nativenick, mbsnick); + qstrf(hub->sk, "$RevConnectToMe %s %s|", hub->nativenick, mbsnick); } free(mbsnick); return(0); @@ -2382,12 +2396,12 @@ static int hubsendchat(struct fnetnode *fn, int public, wchar_t *to, wchar_t *st { if(*to == L'\0') { - qstrf(fn->sk, "<%s> %s|", hub->nativenick, mbsstring); + qstrf(hub->sk, "<%s> %s|", hub->nativenick, mbsstring); } else { - qstrf(fn->sk, "$To: %s From: %s $<%s> %s|", mbsto, hub->nativenick, hub->nativenick, mbsstring); + qstrf(hub->sk, "$To: %s From: %s $<%s> %s|", mbsto, hub->nativenick, hub->nativenick, mbsstring); } } else { - qstrf(fn->sk, "$To: %s From: %s $<%s> %s|", mbsto, hub->nativenick, hub->nativenick, mbsstring); + qstrf(hub->sk, "$To: %s From: %s $<%s> %s|", mbsto, hub->nativenick, hub->nativenick, mbsstring); } free(mbsto); free(mbsstring); @@ -2502,7 +2516,7 @@ static int hubsearch(struct fnetnode *fn, struct search *srch, struct srchfnnlis struct hash *hash; hub = fn->data; - if((fn->state != FNN_EST) || (fn->sk == NULL) || (fn->sk->state != SOCK_EST)) + if((fn->state != FNN_EST) || (hub->sk == NULL) || (hub->sk->state != SOCK_EST)) return(1); list = findsexprstrs(srch->sexpr); findsizelimit(srch->sexpr, &minsize, &maxsize); @@ -2580,15 +2594,15 @@ static int hubsearch(struct fnetnode *fn, struct search *srch, struct srchfnnlis addtobuf(sstr, 0); if(tcpsock != NULL) { - if(sockgetremotename2(udpsock, fn->sk, &name, &namelen) < 0) + if(sockgetremotename2(udpsock, hub->sk, &name, &namelen) < 0) { flog(LOG_WARNING, "cannot get address of UDP socket"); } else { - qstrf(fn->sk, "$Search %s %s|", formataddress(name, namelen), sstr); + qstrf(hub->sk, "$Search %s %s|", formataddress(name, namelen), sstr); free(name); } } else { - qstrf(fn->sk, "$Search Hub:%s %s|", hub->nativenick, sstr); + qstrf(hub->sk, "$Search Hub:%s %s|", hub->nativenick, sstr); } free(sstr); freesl(&list); @@ -2802,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; @@ -2838,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) { @@ -2920,10 +2935,13 @@ static void udpread(struct socket *sk, void *data) { for(fn = fnetnodes; fn != NULL; fn = fn->next) { - if((fn->fnet == &dcnet) && (fn->sk != NULL) && addreq(fn->sk->remote, (struct sockaddr *)&hubaddr)) + if((fn->fnet == &dcnet) && ((hub = fn->data) != NULL)) { - myfn = fn; - break; + if((hub->sk != NULL) && addreq(hub->sk->remote, (struct sockaddr *)&hubaddr)) + { + myfn = fn; + break; + } } } } @@ -3123,13 +3141,15 @@ static void freedcpeer(struct dcpeer *peer) numdcpeers--; } -static void hubconnect(struct fnetnode *fn) +static void hubconnect(struct fnetnode *fn, struct socket *sk) { - fn->sk->readcb = (void (*)(struct socket *, void *))hubread; - fn->sk->errcb = (void (*)(struct socket *, int, void *))huberr; - getfnetnode(fn); - fn->data = newdchub(fn); - fn->sk->data = fn; + struct dchub *hub; + + sk->readcb = (void (*)(struct socket *, void *))hubread; + sk->errcb = (void (*)(struct socket *, int, void *))huberr; + fn->data = hub = newdchub(fn); + sk->data = fn; + getsock(hub->sk = sk); return; } @@ -3140,15 +3160,7 @@ static void hubdestroy(struct fnetnode *fn) struct qcommand *qcmd; hub = (struct dchub *)fn->data; - if((fn->sk != NULL) && (fn->sk->data == fn)) - { - fn->sk->data = NULL; - fn->sk->readcb = NULL; - fn->sk->errcb = NULL; - putfnetnode(fn); - } - if(hub == NULL) - return; + putsock(hub->sk); while((qcmd = ulqcmd(&hub->queue)) != NULL) freeqcmd(qcmd); if(hub->supports != NULL) @@ -3168,6 +3180,14 @@ static void hubdestroy(struct fnetnode *fn) free(hub); } +static void hubkill(struct fnetnode *fn) +{ + struct dchub *hub; + + hub = (struct dchub *)fn->data; + hub->sk->close = 1; +} + static wchar_t *dcbasename(wchar_t *filename) { wchar_t *ret; @@ -3190,6 +3210,7 @@ static struct fnet dcnet = .name = L"dc", .connect = hubconnect, .destroy = hubdestroy, + .kill = hubkill, .setnick = hubsetnick, .reqconn = hubreqconn, .sendchat = hubsendchat, @@ -3302,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); @@ -3477,7 +3498,7 @@ static void updatexmllist(void) lev++; continue; } else { - fprintf(fs, "size); + fprintf(fs, "size); if(node->f.b.hastth) { hashbuf = base32encode(node->hashtth, 24); @@ -3721,10 +3742,10 @@ static int run(void) { if(*qcmd->string == '$') { - if((fn->sk != NULL) && (fn->sk->state == SOCK_EST)) - dispatchcommand(qcmd, hubcmds, fn->sk, fn); + if((hub->sk != NULL) && (hub->sk->state == SOCK_EST)) + dispatchcommand(qcmd, hubcmds, hub->sk, fn); } else if(*qcmd->string != 0) { - hubrecvchat(fn->sk, fn, NULL, qcmd->string); + hubrecvchat(hub->sk, fn, NULL, qcmd->string); } freeqcmd(qcmd); ret = 1; @@ -3873,6 +3894,11 @@ static struct configvar myvars[] = * unknown commands it receives, and their arguments, to * /tmp/dc-unimpl. */ {CONF_VAR_BOOL, "logunimpl", {.num = 0}}, + /** If set to true, doldacond will hide its support for deflate + * compression of transfers from other clients, so that they will + * not request compressed uploads. Compressed transfers may + * consume a non-trivial amount of CPU time on slower machines. */ + {CONF_VAR_BOOL, "hidedeflate", {.num = 0}}, {CONF_VAR_END} };