X-Git-Url: http://dolda2000.com/gitweb/?a=blobdiff_plain;f=daemon%2Ffnet-dc.c;h=c88deef9e6dc036889350c9e6012beb089e59fff;hb=987518f8933f88fae1987c600890dd75464a54d2;hp=ed3427269b6480b8f9e1431ebf93d793b5ce7a8f;hpb=316e9a1376008f14d35a8254a8afa0679d399d38;p=doldaconnect.git diff --git a/daemon/fnet-dc.c b/daemon/fnet-dc.c index ed34272..c88deef 100644 --- a/daemon/fnet-dc.c +++ b/daemon/fnet-dc.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include @@ -44,7 +43,7 @@ #include "transfer.h" #include "sysevents.h" #include "net.h" -#include "tiger.h" +#include /* * The Direct Connect protocol is extremely ugly. Thus, this code must @@ -107,6 +106,7 @@ struct dchub size_t inbufdata, inbufsize; struct qcommand *queue; int extended, dcppemu; + char *charset; char *nativename; char *nativenick; }; @@ -139,6 +139,7 @@ struct dcpeer int compress; int hascurpos, fetchingtthl, notthl; struct tigertreehash tth; + char *charset; void *cprsdata; char *key; char *nativename; @@ -156,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); @@ -166,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) { @@ -388,7 +391,9 @@ static void hubrecvchat(struct socket *sk, struct fnetnode *fn, char *from, char wchar_t *chat, *wfrom, *wpeer; char *p, *end; struct fnetpeer *peer; + struct dchub *hub; + hub = fn->data; end = string + strlen(string); while((p = strchr(string, 13)) != NULL) memmove(p, p + 1, (end-- - p)); @@ -396,7 +401,7 @@ static void hubrecvchat(struct socket *sk, struct fnetnode *fn, char *from, char { if((strlen(string) > strlen(from) + 2) && (*string == '<') && !memcmp(string + 1, from, strlen(from)) && (*(string + strlen(from) + 1) == '>')) string += strlen(from) + 2; - if((wfrom = icmbstowcs(from, DCCHARSET)) == NULL) + if((wfrom = icmbstowcs(from, hub->charset)) == NULL) return; wpeer = swcsdup(wfrom); } else { @@ -414,7 +419,7 @@ static void hubrecvchat(struct socket *sk, struct fnetnode *fn, char *from, char *(p++) = 0; if(*p == ' ') p++; - if((wpeer = icmbstowcs(string + 1, DCCHARSET)) == NULL) + if((wpeer = icmbstowcs(string + 1, hub->charset)) == NULL) return; string = p; } @@ -422,7 +427,7 @@ static void hubrecvchat(struct socket *sk, struct fnetnode *fn, char *from, char if(wpeer == NULL) wpeer = swcsdup(L""); } - if((chat = icmbstowcs(string, DCCHARSET)) == NULL) + if((chat = icmbstowcs(string, hub->charset)) == NULL) { if(wfrom != NULL) free(wfrom); @@ -586,6 +591,7 @@ static char *getadcid(struct dcpeer *peer) char *ret; int isfilelist; + isfilelist = 0; if(!wcscmp(peer->transfer->path, L"files.xml") || !wcscmp(peer->transfer->path, L"files.xml.bz2") || !wcscmp(peer->transfer->path, L"MyList.DcLst")) isfilelist = 1; if(!isfilelist && (peer->transfer->hash != NULL) && isdchash(peer->transfer->hash) && supports(peer, "tthf")) @@ -623,13 +629,13 @@ static int trresumecb(struct transfer *transfer, wchar_t *cmd, wchar_t *arg, str static void sendmynick(struct dcpeer *peer) { - struct dchub *hub; + struct fnetnode *fn; - hub = (peer->fn == NULL)?NULL:(peer->fn->data); - if(hub == NULL) - qstrf(peer->sk, "$MyNick %s|", icswcstombs(confgetstr("cli", "defnick"), DCCHARSET, "DoldaConnectUser-IN")); + fn = peer->fn; + if(fn == NULL) + qstrf(peer->sk, "$MyNick %s|", icswcstombs(confgetstr("cli", "defnick"), peer->charset, "DoldaConnectUser-IN")); else - qstrf(peer->sk, "$MyNick %s|", hub->nativenick); + qstrf(peer->sk, "$MyNick %s|", icswcstombs(fn->mynick, peer->charset, "DoldaConnectUser-IN")); } static void sendpeerlock(struct dcpeer *peer) @@ -654,6 +660,7 @@ static void requestfile(struct dcpeer *peer) if(peer->transfer->size == -1) { + /* Use DCCHARSET for $Get paths until further researched... */ if((buf = icswcstombs(peer->transfer->path, DCCHARSET, NULL)) == NULL) { transferseterror(peer->transfer, TRNSE_NOTFOUND); @@ -722,6 +729,7 @@ static void requestfile(struct dcpeer *peer) } qstrf(peer->sk, "$UGetBlock %i %i %s|", peer->transfer->curpos, 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) { transferseterror(peer->transfer, TRNSE_NOTFOUND); @@ -741,7 +749,7 @@ static void sendmyinfo(struct socket *sk, struct fnetnode *fn) hub = fn->data; qstrf(sk, "$MyINFO $ALL %s ", hub->nativenick); - buf = tr(icswcstombs(confgetstr("dc", "desc"), DCCHARSET, "Charset_conv_failure"), "$_|_"); + buf = tr(icswcstombs(confgetstr("dc", "desc"), hub->charset, "Charset_conv_failure"), "$_|_"); qstrf(sk, "%s", buf); hn1 = hn2 = hn3 = 0; for(cfn = fnetnodes; cfn != NULL; cfn = cfn->next) @@ -764,9 +772,9 @@ static void sendmyinfo(struct socket *sk, struct fnetnode *fn) confgetint("transfer", "slots") ); qstrf(sk, "$ $"); - buf = tr(icswcstombs(confgetstr("dc", "speedstring"), DCCHARSET, "Charset_conv_failure"), "$_|_"); + buf = tr(icswcstombs(confgetstr("dc", "speedstring"), hub->charset, "Charset_conv_failure"), "$_|_"); qstrf(sk, "%s\x01$", buf); - buf = tr(icswcstombs(confgetstr("dc", "email"), DCCHARSET, "Charset_conv_failure"), "$_|_"); + buf = tr(icswcstombs(confgetstr("dc", "email"), hub->charset, "Charset_conv_failure"), "$_|_"); qstrf(sk, "%s$", buf); qstrf(sk, "%llu$|", sharesize); } @@ -825,7 +833,7 @@ static void cmd_hubname(struct socket *sk, struct fnetnode *fn, char *cmd, char if(hub->nativename == NULL) free(hub->nativename); hub->nativename = sstrdup(args); - buf = icmbstowcs(args, DCCHARSET); + buf = icmbstowcs(args, hub->charset); fnetsetname(fn, (buf == NULL)?L"Hubname conv error":buf); if(buf != NULL) free(buf); @@ -838,7 +846,7 @@ static void cmd_hello(struct socket *sk, struct fnetnode *fn, char *cmd, char *a struct dchub *hub; hub = fn->data; - if((nick = icmbstowcs(args, DCCHARSET)) == NULL) + if((nick = icmbstowcs(args, hub->charset)) == NULL) return; if(strcmp(args, hub->nativenick) && (fnetfindpeer(fn, nick) == NULL)) fnetaddpeer(fn, nick, nick); @@ -853,7 +861,7 @@ static void cmd_quit(struct socket *sk, struct fnetnode *fn, char *cmd, char *ar struct dchub *hub; hub = fn->data; - if((nick = icmbstowcs(args, DCCHARSET)) == NULL) + if((nick = icmbstowcs(args, hub->charset)) == NULL) return; if((peer = fnetfindpeer(fn, nick)) != NULL) fnetdelpeer(peer); @@ -874,7 +882,7 @@ static void cmd_nicklist(struct socket *sk, struct fnetnode *fn, char *cmd, char while((p = strstr(args, "$$")) != NULL) { *p = 0; - if((buf = icmbstowcs(args, DCCHARSET)) != NULL) + if((buf = icmbstowcs(args, hub->charset)) != NULL) { if((peer = fnetfindpeer(fn, buf)) == NULL) peer = fnetaddpeer(fn, buf, buf); @@ -907,7 +915,7 @@ static void cmd_oplist(struct socket *sk, struct fnetnode *fn, char *cmd, char * while((p = strstr(args, "$$")) != NULL) { *p = 0; - if((buf = icmbstowcs(args, DCCHARSET)) != NULL) + if((buf = icmbstowcs(args, hub->charset)) != NULL) { if((peer = fnetfindpeer(fn, buf)) != NULL) peer->flags.b.op = 1; @@ -934,7 +942,7 @@ static void cmd_myinfo(struct socket *sk, struct fnetnode *fn, char *cmd, char * if((p2 = strchr(p, ' ')) == NULL) return; *p2 = 0; - if((buf = icmbstowcs(p, DCCHARSET)) == NULL) + if((buf = icmbstowcs(p, hub->charset)) == NULL) return; if((peer = fnetfindpeer(fn, buf)) == NULL) peer = fnetaddpeer(fn, buf, buf); @@ -943,7 +951,7 @@ static void cmd_myinfo(struct socket *sk, struct fnetnode *fn, char *cmd, char * if((p2 = strstr(p, "$ $")) == NULL) return; *p2 = 0; - if((buf = icmbstowcs(p, DCCHARSET)) == NULL) + if((buf = icmbstowcs(p, hub->charset)) == NULL) return; if((wcslen(buf) > 0) && (buf[wcslen(buf) - 1] == L'>') && ((wp = wcsrchr(buf, L'<')) != NULL)) { @@ -972,7 +980,7 @@ static void cmd_myinfo(struct socket *sk, struct fnetnode *fn, char *cmd, char * if((p2 = strchr(p, '$')) == NULL) return; *(p2 - 1) = 0; - if((buf = icmbstowcs(p, DCCHARSET)) == NULL) + if((buf = icmbstowcs(p, hub->charset)) == NULL) return; fnetpeersetstr(peer, L"dc-speed", buf); free(buf); @@ -980,7 +988,7 @@ static void cmd_myinfo(struct socket *sk, struct fnetnode *fn, char *cmd, char * if((p2 = strchr(p, '$')) == NULL) return; *p2 = 0; - if((buf = icmbstowcs(p, DCCHARSET)) == NULL) + if((buf = icmbstowcs(p, hub->charset)) == NULL) return; fnetpeersetstr(peer, L"email", buf); free(buf); @@ -1010,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); @@ -1020,7 +1028,7 @@ static void cmd_forcemove(struct socket *sk, struct fnetnode *fn, char *cmd, cha free(args); } -static char *getdcpath(struct sharecache *node, size_t *retlen) +static char *getdcpath(struct sharecache *node, size_t *retlen, char *charset) { char *buf, *buf2; size_t len, len2; @@ -1029,15 +1037,15 @@ static char *getdcpath(struct sharecache *node, size_t *retlen) return(NULL); if(node->parent == shareroot) { - if((buf = icwcstombs(node->name, DCCHARSET)) == NULL) + if((buf = icwcstombs(node->name, charset)) == NULL) return(NULL); if(retlen != NULL) *retlen = strlen(buf); return(buf); } else { - if((buf2 = icwcstombs(node->name, DCCHARSET)) == NULL) + if((buf2 = icwcstombs(node->name, charset)) == NULL) return(NULL); - if((buf = getdcpath(node->parent, &len)) == NULL) + if((buf = getdcpath(node->parent, &len, charset)) == NULL) { free(buf2); return(NULL); @@ -1076,7 +1084,8 @@ static void cmd_search(struct socket *sk, struct fnetnode *fn, char *cmd, char * struct sockaddr_in addr; struct sharecache *node; int minsize, maxsize; - int dotth, buflen; + int dotth; + size_t buflen; int termnum, satisfied, skipcheck; int level, tersat[32]; wchar_t *terms[32]; @@ -1159,14 +1168,15 @@ 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 { - if((terms[termnum] = icmbstowcs(p, DCCHARSET)) != NULL) + if((terms[termnum] = icmbstowcs(p, hub->charset)) != NULL) termnum++; } } @@ -1214,7 +1224,8 @@ static void cmd_search(struct socket *sk, struct fnetnode *fn, char *cmd, char * } if(!skipcheck && (satisfied == termnum)) { - if((buf = getdcpath(node, NULL)) != NULL) + /* Use DCCHARSET in $Get paths until further researched... */ + if((buf = getdcpath(node, NULL, DCCHARSET)) != NULL) { if(node->f.b.hastth) { @@ -1300,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)); @@ -1405,8 +1416,9 @@ static void cmd_sr(struct socket *sk, struct fnetnode *fn, char *cmd, char *args if((p2 = strstr(p, " (")) == NULL) return; *p2 = 0; - if((wnick = icmbstowcs(nick, DCCHARSET)) == NULL) + if((wnick = icmbstowcs(nick, hub->charset)) == NULL) return; + /* Use DCCHARSET in $Get paths until further researched... */ if((wfile = icmbstowcs(filename, DCCHARSET)) == NULL) { free(wnick); @@ -1448,7 +1460,7 @@ static void cmd_getpass(struct socket *sk, struct fnetnode *fn, char *cmd, char hub = fn->data; pw = wpfind(fn->args, L"password"); - if((pw == NULL) || ((mbspw = icwcstombs(pw, DCCHARSET)) == NULL)) + if((pw == NULL) || ((mbspw = icwcstombs(pw, hub->charset)) == NULL)) { killfnetnode(fn); return; @@ -1478,7 +1490,7 @@ static void cmd_mynick(struct socket *sk, struct dcpeer *peer, char *cmd, char * peer->nativename = sstrdup(args); if(peer->wcsname != NULL) free(peer->wcsname); - if((peer->wcsname = icmbstowcs(peer->nativename, DCCHARSET)) == NULL) + if((peer->wcsname = icmbstowcs(peer->nativename, peer->charset)) == NULL) { freedcpeer(peer); return; @@ -1534,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) @@ -1580,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 { @@ -1591,6 +1613,7 @@ static void cmd_peerlock(struct socket *sk, struct dcpeer *peer, char *cmd, char peer->transfer = transfer; qstrf(sk, "$Direction %s %i|", (peer->direction == TRNSD_UP)?"Upload":"Download", rand() % 10000); qstrf(sk, "$Key %s|", key); + free(key); } else { if(peer->key != NULL) free(peer->key); @@ -1791,6 +1814,7 @@ static void cmd_get(struct socket *sk, struct dcpeer *peer, char *cmd, char *arg } if(fd < 0) { + /* Use DCCHARSET in $Get paths until further researched... */ if((node = resdcpath(args, DCCHARSET, '\\')) == NULL) { qstrf(sk, "$Error File not in share|"); @@ -1919,6 +1943,7 @@ static void cmd_getblock(struct socket *sk, struct dcpeer *peer, char *cmd, char if(!strcmp(cmd, "$UGetBlock") || !strcmp(cmd, "$UGetZBlock")) charset = "UTF-8"; else + /* Use DCCHARSET in $Get paths until further researched... */ charset = DCCHARSET; if(!strcmp(cmd, "$GetZBlock") || !strcmp(cmd, "$UGetZBlock")) initcompress(peer, CPRS_ZLIB); @@ -2262,7 +2287,7 @@ static int hubreqconn(struct fnetpeer *peer) errno = EFAULT; return(1); } - if((mbsnick = icwcstombs(peer->id, DCCHARSET)) == NULL) + if((mbsnick = icwcstombs(peer->id, hub->charset)) == NULL) return(1); /* Shouldn't happen, of course, but who knows... */ if(tcpsock != NULL) { @@ -2281,12 +2306,12 @@ static int hubsendchat(struct fnetnode *fn, int public, wchar_t *to, wchar_t *st char *mbsstring, *mbsto; hub = fn->data; - if((mbsto = icwcstombs(to, DCCHARSET)) == NULL) + if((mbsto = icwcstombs(to, hub->charset)) == NULL) { errno = EILSEQ; return(1); } - if((mbsstring = icwcstombs(string, DCCHARSET)) == NULL) + if((mbsstring = icwcstombs(string, hub->charset)) == NULL) { errno = EILSEQ; return(1); @@ -2401,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; @@ -2467,6 +2494,7 @@ static int hubsearch(struct fnetnode *fn, struct search *srch, struct srchfnnlis { for(cur = list; cur != NULL; cur = cur->next) { + /* Use DCCHARSET in $Get paths until further researched... */ if((buf = icwcstombs(cur->str, DCCHARSET)) == NULL) { /* Can't find anything anyway if the search expression @@ -2504,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 { @@ -2525,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)}, @@ -2548,7 +2576,7 @@ struct command hubcmds[] = {NULL, NULL} }; -struct command peercmds[] = +static struct command peercmds[] = { {"$MyNick", cc(cmd_mynick)}, {"$Lock", cc(cmd_peerlock)}, @@ -2584,7 +2612,7 @@ static void dctransgotdata(struct transfer *transfer, struct dcpeer *peer) { int ret; void *buf; - char outbuf[1024]; + unsigned char outbuf[1024]; z_stream *cstr; size_t bufsize; @@ -2724,6 +2752,7 @@ static void udpread(struct socket *sk, void *data) char *buf, *p, *p2, *hashbuf; size_t buflen, hashlen; char *nick, *filename, *hubname; + struct sockaddr_in hubaddr; int size, slots; struct fnetnode *fn, *myfn; struct dchub *hub; @@ -2783,14 +2812,30 @@ static void udpread(struct socket *sk, void *data) return; } *p2 = 0; - if((wnick = icmbstowcs(nick, DCCHARSET)) == NULL) + p = p2 + 2; + if((p2 = strchr(p, ':')) == NULL) + { + free(buf); + return; + } + *(p2++) = 0; + hubaddr.sin_family = AF_INET; + if(!inet_aton(p, &hubaddr.sin_addr)) + { + free(buf); + return; + } + p = p2; + if((p2 = strchr(p, ')')) == NULL) { free(buf); return; } + *p2 = 0; + hubaddr.sin_port = htons(atoi(p)); + /* Use DCCHARSET in $Get paths until further researched... */ if((wfile = icmbstowcs(filename, DCCHARSET)) == NULL) { - free(wnick); free(buf); return; } @@ -2822,6 +2867,25 @@ static void udpread(struct socket *sk, void *data) } } } + if(myfn == NULL) + { + for(fn = fnetnodes; fn != NULL; fn = fn->next) + { + if((fn->fnet == &dcnet) && (fn->sk != NULL) && addreq(fn->sk->remote, (struct sockaddr *)&hubaddr)) + { + myfn = fn; + break; + } + } + } + hub = NULL; + if(myfn != NULL) + hub = myfn->data; + if((wnick = icmbstowcs(nick, (hub == NULL)?DCCHARSET:(hub->charset))) == NULL) + { + free(buf); + return; + } sr = newsrchres(&dcnet, wfile, wnick); if(sr->peernick != NULL) free(sr->peernick); @@ -2878,7 +2942,7 @@ static int hubsetnick(struct fnetnode *fn, wchar_t *newnick) char *buf; hub = fn->data; - if((buf = icwcstombs(newnick, DCCHARSET)) == NULL) + if((buf = icwcstombs(newnick, (hub == NULL)?DCCHARSET:(hub->charset))) == NULL) return(1); if((strchr(buf, ' ') != NULL) || (strchr(buf, '|') != NULL) || (strchr(buf, '$') != NULL)) { @@ -2900,6 +2964,8 @@ static struct dchub *newdchub(struct fnetnode *fn) { struct dchub *new; wchar_t *emu; + wchar_t *wcharset; + char *charset; new = smalloc(sizeof(*new)); memset(new, 0, sizeof(*new)); @@ -2913,6 +2979,22 @@ static struct dchub *newdchub(struct fnetnode *fn) if(*emu == L'n') new->dcppemu = 0; } + charset = NULL; + if((wcharset = wpfind(fn->args, L"charset")) != NULL) + { + if((charset = icwcstombs(wcharset, "US-ASCII")) != NULL) + { + if(!havecharset(charset)) + { + free(charset); + charset = NULL; + } + } + } + if(charset != NULL) + new->charset = charset; + else + new->charset = sstrdup(DCCHARSET); if(hubsetnick(fn, fn->mynick)) fnetsetnick(fn, L"DoldaConnectUser-IN"); /* IN as in Invalid Nick */ @@ -2982,6 +3064,8 @@ static void freedcpeer(struct dcpeer *peer) free(peer->wcsname); if(peer->nativename != NULL) free(peer->nativename); + if(peer->charset != NULL) + free(peer->charset); if(peer->fn != NULL) putfnetnode(peer->fn); while((qcmd = ulqcmd(&peer->queue)) != NULL) @@ -3006,13 +3090,10 @@ static void hubdestroy(struct fnetnode *fn) struct qcommand *qcmd; hub = (struct dchub *)fn->data; - if(fn->sk != NULL) + if((fn->sk != NULL) && (fn->sk->data == fn)) { - if(fn->sk->data == fn) - { - fn->sk->data = NULL; - putfnetnode(fn); - } + fn->sk->data = NULL; + putfnetnode(fn); } if(hub == NULL) return; @@ -3022,6 +3103,8 @@ static void hubdestroy(struct fnetnode *fn) free(hub->nativename); if(hub->nativenick != NULL) free(hub->nativenick); + if(hub->charset != NULL) + free(hub->charset); if(hub->inbuf != NULL) free(hub->inbuf); free(hub); @@ -3105,6 +3188,7 @@ static void peerconnect(struct socket *sk, int err, struct fnetnode *fn) if(err != 0) { putfnetnode(fn); + putsock(sk); return; } hub = fn->data; @@ -3150,6 +3234,7 @@ static void updatehmlist(void) while(1) { ic = 0; + /* Use DCCHARSET in $Get paths until further researched... */ if((buf2 = icwcstombs(node->name, DCCHARSET)) != NULL) { for(i = 0; i < lev; i++) @@ -3430,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); } @@ -3601,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} };