static void updatexmlbz2list(void);
static void requestfile(struct dcpeer *peer);
static void updatelists(int now);
+static int trdestroycb(struct transfer *transfer, struct dcpeer *peer);
static int reservedchar(unsigned char c)
{
state = 3;
else if(*args != ' ')
state = 1;
+ else
+ args++;
break;
case 1:
if((*args == ' ') || (*args == 0))
peer->close = 1;
return;
}
- CBREG(peer->transfer, trans_filterout, (int (*)(struct transfer *, wchar_t *, wchar_t *, void *))trresumecb, NULL, peer);
return;
}
if(supports(peer, "adcget"))
int minsize, maxsize;
int dotth;
size_t buflen;
- int termnum, satisfied, skipcheck;
+ int termnum, satisfied, matches, skipcheck, proper;
int level, tersat[32];
wchar_t *terms[32], *lname;
char hashtth[24];
termnum = 0;
p2 = p;
done = 0;
+ proper = 0;
while(!done)
{
if((*p2 == 0) || (*p2 == '$'))
} else {
if((terms[termnum] = icmbstowcs(p, hub->charset)) != NULL) {
wcslower(terms[termnum]);
+ if(wcslen(terms[termnum]) > 1)
+ proper = 1;
termnum++;
}
}
}
p2++;
}
+ if(!proper)
+ goto out;
node = shareroot->child;
level = 0;
for(i = 0; i < termnum; i++)
tersat[i] = -1;
satisfied = 0;
+ matches = 0;
while(1)
{
skipcheck = 0;
qstrf(dsk, "%s%s\005%ji%s%s%s", prefix, buf, (intmax_t)node->size, infix, hub->nativename, postfix);
}
free(buf);
+ if(++matches >= 20)
+ break;
}
}
if((!skipcheck && (satisfied == termnum)) || (node->child == NULL))
}
}
+static void peerattach(struct dcpeer *peer, struct transfer *transfer)
+{
+ peer->transfer = transfer;
+ CBREG(peer->transfer, trans_filterout, (int (*)(struct transfer *, wchar_t *, wchar_t *, void *))trresumecb, NULL, peer);
+ CBREG(peer->transfer, trans_destroy, (int (*)(struct transfer *, void *))trdestroycb, NULL, peer);
+}
+
static void cmd_direction(struct socket *sk, struct dcpeer *peer, char *cmd, char *args)
{
char *p;
if(peer->direction == TRNSD_DOWN)
requestfile(peer);
} else {
- if(peer->wcsname == NULL)
+ if((peer->wcsname == NULL) || (peer->transfer != NULL))
{
peer->close = 1;
return;
transfersetstate(transfer, TRNS_HS);
}
transfersetnick(transfer, peer->wcsname);
- peer->transfer = transfer;
+ peerattach(peer, transfer);
if(peer->extended)
sendsupports(peer);
qstrf(sk, "$Direction %s %i|", (peer->direction == TRNSD_UP)?"Upload":"Download", rand() % 10000);
transfersetstate(transfer, TRNS_HS);
}
transfersetnick(transfer, peer->wcsname);
- peer->transfer = transfer;
+ peerattach(peer, transfer);
qstrf(sk, "$Direction %s %i|", (peer->direction == TRNSD_UP)?"Upload":"Download", rand() % 10000);
qstrf(sk, "$Key %s|", key);
free(key);
return(0);
}
-static void findsizelimit(struct sexpr *sexpr, int *min, int *max)
+static void findsizelimit(struct sexpr *sexpr, off_t *min, off_t *max)
{
- int minl, maxl, minr, maxr, retmin, retmax;
+ off_t minl, maxl, minr, maxr, retmin, retmax;
switch(sexpr->op)
{
}
case SOP_SIZELT:
retmin = 0;
- retmax = sexpr->d.n - 1;
+ retmax = sexpr->d.sz - 1;
break;
case SOP_SIZEEQ:
- retmin = sexpr->d.n;
- retmax = sexpr->d.n;
+ retmin = sexpr->d.sz;
+ retmax = sexpr->d.sz;
break;
case SOP_SIZEGT:
- retmin = sexpr->d.n + 1;
+ retmin = sexpr->d.sz + 1;
retmax = -1;
break;
default:
size_t sstrsize, sstrdata;
struct sockaddr *name;
socklen_t namelen;
- int minsize, maxsize;
+ off_t minsize, maxsize;
struct hash *hash;
hub = fn->data;
if(minsize != 0)
{
sizebuf2(sstr, sstrdata + 32, 1);
- sstrdata += snprintf(sstr + sstrdata, sstrsize - sstrdata, "T?F?%i?1?", minsize);
+ sstrdata += snprintf(sstr + sstrdata, sstrsize - sstrdata, "T?F?%ji?1?", (intmax_t)minsize);
} else if(maxsize != -1) {
sizebuf2(sstr, sstrdata + 32, 1);
- sstrdata += snprintf(sstr + sstrdata, sstrsize - sstrdata, "T?T?%i?1?", maxsize);
+ sstrdata += snprintf(sstr + sstrdata, sstrsize - sstrdata, "T?T?%ji?1?", (intmax_t)maxsize);
} else {
bufcat(sstr, "F?F?0?1?", 8);
}
}
if(peer->ptclose)
{
- freedcpeer(peer);
+ peer->close = 1;
} else {
if(peer->timeout == NULL)
peer->timeout = timercallback(ntime() + 180, (void (*)(int, void *))peertimeout, peer);
}
}
+static void peerdetach(struct dcpeer *peer)
+{
+ CBUNREG(peer->transfer, trans_filterout, peer);
+ CBUNREG(peer->transfer, trans_destroy, peer);
+ peer->trpipe->pnext = NULL;
+ closesock(peer->trpipe);
+ quitsock(peer->trpipe);
+ peer->trpipe = NULL;
+ peer->transfer = NULL;
+}
+
+static int trdestroycb(struct transfer *transfer, struct dcpeer *peer)
+{
+ peerdetach(peer);
+ peer->close = 1;
+ return(0);
+}
+
static void transread(struct socket *sk, struct dcpeer *peer)
{
void *buf;
size_t bufsize;
+ if(peer->transfer == NULL) {
+ freedcpeer(peer);
+ return;
+ }
if(sockqueueleft(peer->trpipe) < 0)
return;
if((buf = sockgetinbuf(sk, &bufsize)) != NULL)
}
if(peer->transfer->curpos >= peer->transfer->size)
{
- closesock(peer->trpipe);
- quitsock(peer->trpipe);
- peer->trpipe = NULL;
- peer->transfer = NULL;
+ peerdetach(peer);
peer->close = 1;
return;
}
freedcpeer(peer);
return;
}
- closesock(peer->trpipe);
- quitsock(peer->trpipe);
- peer->trpipe = NULL;
- peer->transfer = NULL;
+ peerdetach(peer);
peer->close = 1;
}
return;
}
dctransgotdata(peer->transfer, peer);
+ sockread(peer->trpipe);
}
static void trpiperead(struct socket *sk, struct dcpeer *peer)
{
peer->state = PEER_SYNC;
dctransgotdata(peer->transfer, peer);
- CBUNREG(peer->transfer, trans_filterout, peer);
+ peerdetach(peer);
+ if(peer->state != PEER_CMD)
+ peer->close = 1;
}
static struct socket *mktrpipe(struct dcpeer *peer)
struct socket *sk;
sk = netsockpipe();
+ sk->pnext = peer->sk;
sk->data = peer;
sk->readcb = (void (*)(struct socket *, void *))trpiperead;
sk->writecb = (void (*)(struct socket *, void *))trpipewrite;
new = smalloc(sizeof(*new));
memset(new, 0, sizeof(*new));
- new->transfer = NULL;
getsock(sk);
new->sk = sk;
if(confgetint("dc", "dcppemu"))
peer->next->prev = peer->prev;
if(peer->prev != NULL)
peer->prev->next = peer->next;
- if(peer->trpipe != NULL) {
- closesock(peer->trpipe);
- quitsock(peer->trpipe);
- }
if(peer->transfer != NULL)
- {
- CBUNREG(peer->transfer, trans_filterout, peer);
- if(peer->transfer->dir == TRNSD_UP)
- peer->transfer->close = 1;
- if(peer->transfer->dir == TRNSD_DOWN)
- resettransfer(peer->transfer);
- }
+ peerdetach(peer);
if(peer->timeout != NULL)
canceltimer(peer->timeout);
if(peer->sk->data == peer)
struct qcommand *qcmd;
hub = (struct dchub *)fn->data;
- putsock(hub->sk);
+ quitsock(hub->sk);
while((qcmd = ulqcmd(&hub->queue)) != NULL)
freeqcmd(qcmd);
if(hub->supports != NULL)