size_t inbufdata, inbufsize;
size_t curread, totalsize;
int freeing;
+ struct timer *timeout;
struct qcommand *queue;
struct transfer *transfer;
int state;
int extended;
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;
{
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);
sendadc(peer->sk, "0");
sendadc(peer->sk, "-1");
qstr(peer->sk, "|");
+ peer->fetchingtthl = 1;
return;
}
}
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"), "$_|_");
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>",
+ qstrf(sk, "<%s V:%s,M:%c,H:%i/%i/%i,S:%i>",
DCIDTAG,
DCIDTAGV,
(tcpsock == NULL)?'P':'A',
- numhubs,
+ hn1, hn2, hn3,
confgetint("transfer", "slots")
);
qstrf(sk, "$ $");
} else {
freeargs = 0;
}
- if((newfn = fnetinitconnect(L"dc", args)) != NULL)
+ if((newfn = fnetinitconnect(L"dc", args, NULL)) != NULL)
{
linkfnetnode(newfn);
putfnetnode(newfn);
/* Do nothing for now. */
}
+static void cmd_getpass(struct socket *sk, struct fnetnode *fn, char *cmd, char *args)
+{
+ struct dchub *hub;
+ struct wcspair *arg;
+ 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))
+ {
+ 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;
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;
- }
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")) {
{"$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);
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;
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)
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);