char *inbuf;
size_t inbufdata, inbufsize;
struct qcommand *queue;
- int extended;
+ int extended, dcppemu;
+ char *charset;
char *nativename;
char *nativenick;
};
size_t inbufdata, inbufsize;
size_t curread, totalsize;
int freeing;
+ struct timer *timeout;
struct qcommand *queue;
struct transfer *transfer;
int state;
int ptclose; /* Close after transfer is complete */
int accepted; /* If false, we connected, otherwise, we accepted */
- int extended;
+ int extended, dcppemu;
int direction; /* Using the constants from transfer.h */
int compress;
- int hascurpos, notthl;
+ int hascurpos, fetchingtthl, notthl;
struct tigertreehash tth;
+ char *charset;
void *cprsdata;
char *key;
char *nativename;
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));
{
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 {
*(p++) = 0;
if(*p == ' ')
p++;
- if((wpeer = icmbstowcs(string + 1, DCCHARSET)) == NULL)
+ if((wpeer = icmbstowcs(string + 1, hub->charset)) == NULL)
return;
string = p;
}
if(wpeer == NULL)
wpeer = swcsdup(L"");
}
- if((chat = icmbstowcs(string, DCCHARSET)) == NULL)
+ if((chat = icmbstowcs(string, hub->charset)) == NULL)
{
if(wfrom != NULL)
free(wfrom);
free(chat);
}
+static void peertimeout(int cancelled, struct dcpeer *peer)
+{
+ peer->timeout = NULL;
+ if(cancelled)
+ return;
+ freedcpeer(peer);
+}
+
static void sendadc(struct socket *sk, char *arg)
{
char *buf;
{
char *buf;
char *ret;
+ int isfilelist;
- if((peer->transfer->hash != NULL) && isdchash(peer->transfer->hash) && supports(peer, "tthf"))
+ 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"))
{
buf = base32encode(peer->transfer->hash->buf, 24);
ret = sprintf2("TTH/%.39s", buf);
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)
{
-#ifdef DCPP_MASQUERADE
- qstrf(peer->sk, "$Lock EXTENDEDPROTOCOLABCABCABCABCABCABC Pk=DCPLUSPLUS0.674ABCABC|");
-#else
- qstrf(peer->sk, "$Lock EXTENDEDPROTOCOLABCABCABCABCABCABC Pk=DOLDA%sABCABCABC|", VERSION);
-#endif
+ if(peer->dcppemu)
+ qstrf(peer->sk, "$Lock EXTENDEDPROTOCOLABCABCABCABCABCABC Pk=DCPLUSPLUS0.674ABCABC|");
+ else
+ qstrf(peer->sk, "$Lock EXTENDEDPROTOCOLABCABCABCABCABCABC Pk=DOLDA%sABCABCABC|", VERSION);
}
static void sendsupports(struct dcpeer *peer)
{
-#ifdef DCPP_MASQUERADE
- qstr(peer->sk, "$Supports MiniSlots XmlBZList ADCGet TTHL TTHF GetZBlock ZLIG |");
-#else
- qstr(peer->sk, "$Supports MiniSlots XmlBZList ADCGet TTHL TTHF GetZBlock ZLIG|");
-#endif
+ 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|");
}
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);
sendadc(peer->sk, "0");
sendadc(peer->sk, "-1");
qstr(peer->sk, "|");
+ peer->fetchingtthl = 1;
return;
}
}
}
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);
struct dchub *hub;
char *buf;
struct fnetnode *cfn;
- int numhubs;
+ int hn1, hn2, hn3;
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);
- numhubs = 0;
+ hn1 = hn2 = hn3 = 0;
for(cfn = fnetnodes; cfn != NULL; cfn = cfn->next)
{
if((cfn->state == FNN_EST) || (cfn->state == FNN_HS))
- numhubs++;
+ {
+ if(cfn->regstatus == FNNS_OP)
+ hn3++;
+ else if(cfn->regstatus == FNNS_REG)
+ hn2++;
+ else
+ hn1++;
+ }
}
- qstrf(sk, "<%s V:%s,M:%c,H:%i/0/0,S:%i>",
- DCIDTAG,
- DCIDTAGV,
+ qstrf(sk, "<%s V:%s,M:%c,H:%i/%i/%i,S:%i>",
+ (hub->dcppemu)?"++":"Dolda",
+ (hub->dcppemu)?"0.674":VERSION,
(tcpsock == NULL)?'P':'A',
- numhubs,
+ hn1, hn2, hn3,
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);
}
*(p++) = 0;
if(hub->extended)
{
-#ifdef DCPP_MASQUERADE
- qstrf(sk, "$Supports UserCommand NoGetINFO NoHello UserIP2 TTHSearch GetZBlock |");
-#else
- qstrf(sk, "$Supports UserCommand NoGetINFO NoHello UserIP2 TTHSearch GetZBlock|");
-#endif
+ if(hub->dcppemu)
+ qstrf(sk, "$Supports UserCommand NoGetINFO NoHello UserIP2 TTHSearch GetZBlock |");
+ else
+ qstrf(sk, "$Supports UserCommand NoGetINFO NoHello UserIP2 TTHSearch GetZBlock|");
}
key = dcmakekey(args);
qstrf(sk, "$Key %s|", key);
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);
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);
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);
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);
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;
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);
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 = wcschr(buf, L'<')) != NULL))
+ if((wcslen(buf) > 0) && (buf[wcslen(buf) - 1] == L'>') && ((wp = wcsrchr(buf, L'<')) != NULL))
{
buf[wcslen(buf) - 1] = L'\0';
*(wp++) = L'\0';
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);
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);
} else {
freeargs = 0;
}
- if((newfn = fnetinitconnect(L"dc", args)) != NULL)
+ if((newfn = fnetinitconnect(L"dc", args, NULL)) != NULL)
{
linkfnetnode(newfn);
putfnetnode(newfn);
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;
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);
memcpy(hashtth, buf, 24);
free(buf);
} else {
- if((terms[termnum] = icmbstowcs(p, DCCHARSET)) != NULL)
+ if((terms[termnum] = icmbstowcs(p, hub->charset)) != NULL)
termnum++;
}
}
}
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)
{
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);
/* Do nothing for now. */
}
+static void cmd_getpass(struct socket *sk, struct fnetnode *fn, char *cmd, char *args)
+{
+ struct dchub *hub;
+ wchar_t *pw;
+ char *mbspw;
+
+ hub = fn->data;
+ pw = wpfind(fn->args, L"password");
+ if((pw == NULL) || ((mbspw = icwcstombs(pw, hub->charset)) == NULL))
+ {
+ killfnetnode(fn);
+ return;
+ }
+ qstrf(sk, "$MyPass %s|", mbspw);
+ free(mbspw);
+ fn->regstatus = FNNS_REG;
+ hubhandleaction(sk, fn, cmd, args);
+}
+
+static void cmd_logedin(struct socket *sk, struct fnetnode *fn, char *cmd, char *args)
+{
+ struct dchub *hub;
+
+ hub = fn->data;
+ fn->regstatus = FNNS_OP;
+ hubhandleaction(sk, fn, cmd, args);
+}
+
static void cmd_mynick(struct socket *sk, struct dcpeer *peer, char *cmd, char *args)
{
struct dcexppeer *expect;
+ struct dchub *hub;
if(peer->nativename != NULL)
free(peer->nativename);
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;
{
peer->fn = NULL;
} else {
+ hub = expect->fn->data;
peer->fn = expect->fn;
getfnetnode(peer->fn);
+ peer->dcppemu = hub->dcppemu;
freeexppeer(expect);
}
}
freedcpeer(peer);
return;
}
- requestfile(peer);
+ if(peer->direction == TRNSD_DOWN)
+ requestfile(peer);
} else {
if(peer->wcsname == NULL)
{
static void startdl(struct dcpeer *peer)
{
+ if(peer->timeout != NULL)
+ canceltimer(peer->timeout);
peer->state = PEER_TRNS;
transferstartdl(peer->transfer, peer->sk);
peer->sk->readcb = (void (*)(struct socket *, void *))transread;
static void startul(struct dcpeer *peer)
{
+ if(peer->timeout != NULL)
+ canceltimer(peer->timeout);
peer->state = PEER_TRNS;
transferstartul(peer->transfer, peer->sk);
peer->sk->writecb = (void (*)(struct socket *, void *))transwrite;
static void cmd_filelength(struct socket *sk, struct dcpeer *peer, char *cmd, char *args)
{
int size;
+ struct transfer *transfer;
if(peer->transfer == NULL)
{
if(peer->transfer->size != size)
{
transfersetsize(peer->transfer, size);
+ transfer = peer->transfer;
freedcpeer(peer);
+ trytransferbypeer(transfer->fnet, transfer->peerid);
return;
}
startdl(peer);
static void cmd_error(struct socket *sk, struct dcpeer *peer, char *cmd, char *args)
{
+ if(peer->fetchingtthl)
+ {
+ peer->fetchingtthl = 0;
+ peer->notthl = 1;
+ requestfile(peer);
+ return;
+ }
if((peer->transfer != NULL) && (peer->transfer->dir == TRNSD_DOWN))
{
transferseterror(peer->transfer, TRNSE_NOTFOUND);
} else if(fd >= 0) {
if((buf2 = icsmbstowcs(args, DCCHARSET, NULL)) != NULL)
transfersetpath(peer->transfer, buf2);
+ peer->transfer->flags.b.minislot = 1;
}
if(fd < 0)
{
- if(slotsleft() < 1)
- {
- qstr(sk, "$MaxedOut|");
- freedcpeer(peer);
- return;
- }
+ /* Use DCCHARSET in $Get paths until further researched... */
if((node = resdcpath(args, DCCHARSET, '\\')) == NULL)
{
qstrf(sk, "$Error File not in share|");
freedcpeer(peer);
return;
}
+ if(sb.st_size < 65536)
+ peer->transfer->flags.b.minislot = 1;
+ if(!peer->transfer->flags.b.minislot && (slotsleft() < 1)) {
+ close(fd);
+ qstr(sk, "$MaxedOut|");
+ freedcpeer(peer);
+ return;
+ }
if((offset != 0) && (lseek(fd, offset, SEEK_SET) < 0))
{
close(fd);
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);
} else if(fd >= 0) {
if((buf2 = icsmbstowcs(args, charset, NULL)) != NULL)
transfersetpath(peer->transfer, buf2);
+ peer->transfer->flags.b.minislot = 1;
}
if(fd < 0)
{
- if(slotsleft() < 1)
- {
- qstr(sk, "$MaxedOut|");
- return;
- }
if((node = resdcpath(p, charset, '\\')) == NULL)
{
qstr(sk, "$Error File not in cache|");
qstr(sk, "$Error|");
return;
}
+ if(sb.st_size < 65536)
+ peer->transfer->flags.b.minislot = 1;
+ if(!peer->transfer->flags.b.minislot && (slotsleft() < 1)) {
+ close(fd);
+ qstr(sk, "$MaxedOut|");
+ return;
+ }
if((start != 0) && ((start >= sb.st_size) || (lseek(fd, start, SEEK_SET) < 0)))
{
close(fd);
} else if(fd >= 0) {
if((wbuf = icsmbstowcs(argv[1], "UTF-8", NULL)) != NULL)
transfersetpath(peer->transfer, wbuf);
+ peer->transfer->flags.b.minislot = 1;
}
if(fd < 0)
{
- if(slotsleft() < 1)
- {
- qstr(sk, "$MaxedOut|");
- goto out;
- }
if(!strncmp(argv[1], "TTH/", 4))
{
if((node = findbytth(argv[1] + 4)) == NULL)
qstr(sk, "$Error|");
goto out;
}
+ if(sb.st_size < 65536)
+ peer->transfer->flags.b.minislot = 1;
+ if(!peer->transfer->flags.b.minislot && (slotsleft() < 1)) {
+ qstr(sk, "$MaxedOut|");
+ goto out;
+ }
if((start != 0) && ((start >= sb.st_size) || (lseek(fd, start, SEEK_SET) < 0)))
{
qstr(sk, "$Error Offset out of range|");
}
if(peer->curread >= peer->totalsize)
{
+ if(peer->timeout == NULL)
+ peer->timeout = timercallback(ntime() + 180, (void (*)(int, void *))peertimeout, peer);
peer->state = PEER_CMD;
synctigertree(&peer->tth);
restigertree(&peer->tth, buf);
freedcpeer(peer);
goto out;
}
+ if(peer->timeout != NULL)
+ canceltimer(peer->timeout);
peer->state = PEER_TTHL;
peer->totalsize = numbytes;
peer->curread = 0;
+ peer->fetchingtthl = 0;
inittigertree(&peer->tth);
handletthl(peer);
} else if(!strcmp(argv[0], "file")) {
return;
}
startdl(peer);
+ if(peer->inbufdata > 0)
+ {
+ sockpushdata(sk, peer->inbuf, peer->inbufdata);
+ peer->inbufdata = 0;
+ transread(sk, 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)
{
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);
if(minsize != 0)
{
sizebuf2(sstr, sstrdata + 32, 1);
- snprintf(sstr + sstrdata, sstrsize - sstrdata, "T?F?%i?1?", minsize);
+ sstrdata += snprintf(sstr + sstrdata, sstrsize - sstrdata, "T?F?%i?1?", minsize);
} else if(maxsize != -1) {
sizebuf2(sstr, sstrdata + 32, 1);
- snprintf(sstr + sstrdata, sstrsize - sstrdata, "T?T?%i?1?", maxsize);
+ sstrdata += snprintf(sstr + sstrdata, sstrsize - sstrdata, "T?T?%i?1?", maxsize);
} else {
bufcat(sstr, "F?F?0?1?", 8);
}
{
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
{"$To:", cc(cmd_to)},
{"$SR", cc(cmd_sr)},
{"$UserCommand", cc(cmd_usercommand)},
+ {"$GetPass", cc(cmd_getpass)},
+ {"$LogedIn", cc(cmd_logedin)}, /* sic */
{NULL, NULL}
};
{
freedcpeer(peer);
} else {
+ if(peer->timeout == NULL)
+ peer->timeout = timercallback(ntime() + 180, (void (*)(int, void *))peertimeout, peer);
peer->state = PEER_CMD;
endcompress(peer);
transfersetstate(transfer, TRNS_HS);
socksettos(peer->sk, confgetint("fnet", "fnptos"));
+ transfer->flags.b.minislot = 0;
peer->sk->writecb = NULL;
}
}
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;
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;
}
}
}
}
+ 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);
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))
{
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));
fn->data = new;
+ if(confgetint("dc", "dcppemu"))
+ new->dcppemu = 1;
+ if((emu = wpfind(fn->args, L"dcppemu")) != NULL)
+ {
+ if(*emu == L'y')
+ new->dcppemu = 1;
+ 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 */
new->transfer = NULL;
getsock(sk);
new->sk = sk;
+ if(confgetint("dc", "dcppemu"))
+ new->dcppemu = 1;
new->next = peers;
new->prev = NULL;
if(peers != NULL)
resettransfer(peer->transfer);
transferdetach(peer->transfer);
}
+ if(peer->timeout != NULL)
+ canceltimer(peer->timeout);
if(peer->sk->data == peer)
peer->sk->data = NULL;
peer->sk->readcb = NULL;
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)
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;
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);
newqcmd(&peer->queue, peer->inbuf);
for(cmd = peercmds; cmd->handler != NULL; cmd++)
{
- if(!memcmp(peer->inbuf, cmd->name, strlen(cmd->name)) && (peer->inbuf[strlen(cmd->name)] == 0))
+ if(!memcmp(peer->inbuf, cmd->name, strlen(cmd->name)) && ((peer->inbuf[strlen(cmd->name)] == ' ') || (peer->inbuf[strlen(cmd->name)] == '|')))
break;
}
+ memmove(peer->inbuf, p, peer->inbufdata -= p - peer->inbuf);
if(cmd->stop)
{
peer->state = PEER_STOP;
break;
}
- memmove(peer->inbuf, p, peer->inbufdata -= p - peer->inbuf);
}
} else if(peer->state == PEER_TTHL) {
handletthl(peer);
static void peerconnect(struct socket *sk, int err, struct fnetnode *fn)
{
struct dcpeer *peer;
+ struct dchub *hub;
if(err != 0)
{
putfnetnode(fn);
return;
}
+ hub = fn->data;
peer = newdcpeer(sk);
peer->fn = fn;
peer->accepted = 0;
+ peer->dcppemu = hub->dcppemu;
sk->readcb = (void (*)(struct socket *, void *))peerread;
sk->errcb = (void (*)(struct socket *, int, void *))peererror;
sk->data = peer;
socksettos(sk, confgetint("fnet", "fnptos"));
putsock(sk);
+ peer->timeout = timercallback(ntime() + 180, (void (*)(int, void *))peertimeout, peer);
sendmynick(peer);
sendpeerlock(peer);
}
newsk->errcb = (void (*)(struct socket *, int, void *))peererror;
newsk->data = peer;
socksettos(newsk, confgetint("fnet", "fnptos"));
+ peer->timeout = timercallback(ntime() + 180, (void (*)(int, void *))peertimeout, peer);
}
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++)
for(i = 0; i < sizeof(cidbuf) - 1; i++)
cidbuf[i] = (rand() % ('Z' - 'A' + 1)) + 'A';
cidbuf[i] = 0;
- fprintf(fs, "<FileListing Version=\"1\" CID=\"%s\" Base=\"/\" Generator=\"%s\">\r\n", cidbuf, DCIDFULL);
+ if(confgetint("dc", "dcppemu"))
+ fprintf(fs, "<FileListing Version=\"1\" CID=\"%s\" Base=\"/\" Generator=\"DC++ 0.674\">\r\n", cidbuf);
+ else
+ fprintf(fs, "<FileListing Version=\"1\" CID=\"%s\" Base=\"/\" Generator=\"%s\">\r\n", cidbuf, "DoldaConnect" VERSION);
node = shareroot->child;
lev = 0;
}
}
-#ifdef DCPP_MASQUERADE
- fprintf(fs, "</FileListing>");
-#else
- fprintf(fs, "</FileListing>\r\n");
-#endif
+ if(confgetint("dc", "dcppemu"))
+ fprintf(fs, "</FileListing>");
+ else
+ fprintf(fs, "</FileListing>\r\n");
fclose(fs);
}
nextpeer = peer->next;
if((qcmd = ulqcmd(&peer->queue)) != NULL)
{
+ if(peer->timeout != NULL)
+ canceltimer(peer->timeout);
+ peer->timeout = timercallback(ntime() + 180, (void (*)(int, void *))peertimeout, peer);
if(*qcmd->string == '$')
dispatchcommand(qcmd, peercmds, peer->sk, peer);
freeqcmd(qcmd);
{CONF_VAR_STRING, "email", {.str = L"spam@spam.org"}},
{CONF_VAR_INT, "udpport", {.num = 0}},
{CONF_VAR_INT, "tcpport", {.num = 0}},
+ {CONF_VAR_BOOL, "dcppemu", {.num = 0}},
{CONF_VAR_END}
};