char *inbuf;
size_t inbufdata, inbufsize;
struct qcommand *queue;
- int extended;
+ int extended, dcppemu;
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;
void *cprsdata;
char *key;
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;
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)
sendadc(peer->sk, "0");
sendadc(peer->sk, "-1");
qstr(peer->sk, "|");
+ peer->fetchingtthl = 1;
return;
}
}
}
}
qstrf(sk, "<%s V:%s,M:%c,H:%i/%i/%i,S:%i>",
- DCIDTAG,
- DCIDTAGV,
+ (hub->dcppemu)?"++":"Dolda",
+ (hub->dcppemu)?"0.674":VERSION,
(tcpsock == NULL)?'P':'A',
hn1, hn2, hn3,
confgetint("transfer", "slots")
*(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);
static void cmd_getpass(struct socket *sk, struct fnetnode *fn, char *cmd, char *args)
{
struct dchub *hub;
- struct wcspair *arg;
+ wchar_t *pw;
char *mbspw;
hub = fn->data;
- for(arg = fn->args; arg != NULL; arg = arg->next)
- {
- if(!wcscmp(arg->key, L"password"))
- break;
- }
- if((arg == NULL) || ((mbspw = icwcstombs(arg->val, DCCHARSET)) == NULL))
+ pw = wpfind(fn->args, L"password");
+ if((pw == NULL) || ((mbspw = icwcstombs(pw, DCCHARSET)) == NULL))
{
killfnetnode(fn);
return;
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->fn = NULL;
} else {
+ hub = expect->fn->data;
peer->fn = expect->fn;
getfnetnode(peer->fn);
+ peer->dcppemu = hub->dcppemu;
freeexppeer(expect);
}
}
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;
- }
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);
} 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")) {
{
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;
}
}
static struct dchub *newdchub(struct fnetnode *fn)
{
struct dchub *new;
+ wchar_t *emu;
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;
+ }
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;
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)
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}
};