static char *xmlbz2listname = NULL;
static struct timer *listwritetimer = NULL;
-static int peerconnect(struct socket *sk, int err, struct fnetnode *fn);
-static int peerread(struct socket *sk, struct dcpeer *peer);
-static int peererror(struct socket *sk, int err, struct dcpeer *peer);
+static void peerconnect(struct socket *sk, int err, struct fnetnode *fn);
static void freedcpeer(struct dcpeer *peer);
-static void transread(struct dcpeer *peer);
-static void transerr(struct dcpeer *peer);
-static int transwrite(struct socket *sk, struct dcpeer *peer);
+static void transread(struct socket *sk, struct dcpeer *peer);
+static void transerr(struct socket *sk, int err, struct dcpeer *peer);
+static void transwrite(struct socket *sk, struct dcpeer *peer);
static void updatehmlist(void);
static void updatexmllist(void);
static void updatexmlbz2list(void);
addr.sin_port = htons(atoi(p));
if(!inet_aton(args, &addr.sin_addr))
return;
- newsk = netcsconn((struct sockaddr *)&addr, sizeof(addr), (int (*)(struct socket *, int, void *))peerconnect, fn);
+ newsk = netcsconn((struct sockaddr *)&addr, sizeof(addr), (void (*)(struct socket *, int, void *))peerconnect, fn);
getfnetnode(fn);
hubhandleaction(sk, fn, cmd, args);
}
canceltimer(peer->timeout);
peer->state = PEER_TRNS;
transferstartdl(peer->transfer, peer->sk);
+ peer->sk->readcb = (void (*)(struct socket *, void *))transread;
+ peer->sk->errcb = (void (*)(struct socket *, int, void *))transerr;
}
static void startul(struct dcpeer *peer)
canceltimer(peer->timeout);
peer->state = PEER_TRNS;
transferstartul(peer->transfer, peer->sk);
- CBREG(peer->sk, socket_write, (int (*)(struct socket *, void *))transwrite, NULL, peer);
+ peer->sk->writecb = (void (*)(struct socket *, void *))transwrite;
}
static void cmd_filelength(struct socket *sk, struct dcpeer *peer, char *cmd, char *args)
goto out;
}
startdl(peer);
- transread(peer);
+ if(peer->inbufdata > 0)
+ {
+ sockpushdata(sk, peer->inbuf, peer->inbufdata);
+ peer->inbufdata = 0;
+ transread(sk, peer);
+ }
} else {
/* We certainly didn't request this...*/
freedcpeer(peer);
return;
}
startdl(peer);
- transread(peer);
+ if(peer->inbufdata > 0)
+ {
+ sockpushdata(sk, peer->inbuf, peer->inbufdata);
+ peer->inbufdata = 0;
+ transread(sk, peer);
+ }
}
/*
static void dctransdetach(struct transfer *transfer, struct dcpeer *peer)
{
- CBUNREG(transfer, trans_filterout, trresumecb, peer);
+ CBUNREG(transfer, trans_filterout, peer);
if(peer->freeing)
return;
peer->transfer = NULL;
transfersetstate(transfer, TRNS_HS);
socksettos(peer->sk, confgetint("fnet", "fnptos"));
transfer->flags.b.minislot = 0;
- CBUNREG(peer->sk, socket_write, transwrite, peer);
+ peer->sk->writecb = NULL;
}
}
}
peer->sk->ignread = 0;
}
-static void transread(struct dcpeer *peer)
+static void transread(struct socket *sk, struct dcpeer *peer)
{
- size_t num;
+ void *buf;
+ size_t bufsize;
struct transfer *transfer;
+ if((buf = sockgetinbuf(sk, &bufsize)) == NULL)
+ return;
if(peer->transfer == NULL)
{
+ free(buf);
freedcpeer(peer);
return;
}
- if(peer->inbufsize > peer->transfer->size - peer->transfer->curpos)
- num = peer->transfer->size - peer->transfer->curpos;
- else
- num = peer->inbufsize;
- transferputdata(peer->transfer, peer->inbuf, num);
- memmove(peer->inbuf, peer->inbuf + num, peer->inbufsize -= num);
+ transferputdata(peer->transfer, buf, bufsize);
+ free(buf);
if(peer->transfer->curpos >= peer->transfer->size)
{
transfer = peer->transfer;
return;
}
if(transferdatasize(peer->transfer) > 65535)
- peer->sk->ignread = 1;
+ sk->ignread = 1;
}
-static void transerr(struct dcpeer *peer)
+static void transerr(struct socket *sk, int err, struct dcpeer *peer)
{
struct transfer *transfer;
if((transfer = peer->transfer) == NULL)
+ {
+ freedcpeer(peer);
return;
+ }
transferdetach(transfer);
transferendofdata(transfer);
}
-static int transwrite(struct socket *sk, struct dcpeer *peer)
+static void transwrite(struct socket *sk, struct dcpeer *peer)
{
if((peer->state != PEER_TRNS) && (peer->state != PEER_SYNC))
- return(1);
+ return;
if(peer->transfer == NULL)
{
freedcpeer(peer);
- return(1);
+ return;
}
dctransgotdata(peer->transfer, peer);
- return(0);
}
-static int udpread(struct socket *sk, void *data)
+static void udpread(struct socket *sk, void *data)
{
char *buf, *p, *p2, *hashbuf;
size_t buflen, hashlen;
struct hash *hash;
if((buf = sockgetinbuf(sk, &buflen)) == NULL)
- return(0);
+ return;
buf = srealloc(buf, buflen + 1);
buf[buflen] = 0;
if(!strncmp(buf, "$SR ", 4))
if((p2 = strchr(p, ' ')) == NULL)
{
free(buf);
- return(0);
+ return;
}
*p2 = 0;
p = p2 + 1;
if((p2 = strchr(p, 5)) == NULL)
{
free(buf);
- return(0);
+ return;
}
*p2 = 0;
p = p2 + 1;
if((p2 = strchr(p, ' ')) == NULL)
{
free(buf);
- return(0);
+ return;
}
*p2 = 0;
size = atoi(p);
if((p2 = strchr(p, '/')) == NULL)
{
free(buf);
- return(0);
+ return;
}
*p2 = 0;
slots = atoi(p);
if((p2 = strchr(p, 5)) == NULL)
{
free(buf);
- return(0);
+ return;
}
p = p2 + 1;
hubname = p;
if((p2 = strstr(p, " (")) == NULL)
{
free(buf);
- return(0);
+ return;
}
*p2 = 0;
p = p2 + 2;
if((p2 = strchr(p, ':')) == NULL)
{
free(buf);
- return(0);
+ return;
}
*(p2++) = 0;
hubaddr.sin_family = AF_INET;
if(!inet_aton(p, &hubaddr.sin_addr))
{
free(buf);
- return(0);
+ return;
}
p = p2;
if((p2 = strchr(p, ')')) == NULL)
{
free(buf);
- return(0);
+ return;
}
*p2 = 0;
hubaddr.sin_port = htons(atoi(p));
if((wfile = icmbstowcs(filename, DCCHARSET)) == NULL)
{
free(buf);
- return(0);
+ return;
}
myfn = NULL;
hash = NULL;
if((wnick = icmbstowcs(nick, (hub == NULL)?DCCHARSET:(hub->charset))) == NULL)
{
free(buf);
- return(0);
+ return;
}
sr = newsrchres(&dcnet, wfile, wnick);
if(sr->peernick != NULL)
freesrchres(sr);
}
free(buf);
- return(0);
}
static void hubread(struct socket *sk, struct fnetnode *fn)
}
if(peer->timeout != NULL)
canceltimer(peer->timeout);
- /* XXX: Unregister transwrite from peer->sk->socket_write? */
- CBUNREG(peer->sk, socket_read, peerread, peer);
- CBUNREG(peer->sk, socket_err, peererror, peer);
+ if(peer->sk->data == peer)
+ peer->sk->data = NULL;
+ peer->sk->readcb = NULL;
+ peer->sk->writecb = NULL;
+ peer->sk->errcb = NULL;
putsock(peer->sk);
endcompress(peer);
if(peer->supports != NULL)
static void hubconnect(struct fnetnode *fn)
{
- CBREG(fn->sk, socket_read, (int (*)(struct socket *, void *))hubread, (void (*)(void *))putfnetnode, getfnetnode(fn));
- CBREG(fn->sk, socket_err, (int (*)(struct socket *, int, void *))huberr, (void (*)(void *))putfnetnode, getfnetnode(fn));
+ fn->sk->readcb = (void (*)(struct socket *, void *))hubread;
+ fn->sk->errcb = (void (*)(struct socket *, int, void *))huberr;
+ getfnetnode(fn);
fn->data = newdchub(fn);
+ fn->sk->data = fn;
return;
}
struct qcommand *qcmd;
hub = (struct dchub *)fn->data;
- if(fn->sk != NULL)
+ if((fn->sk != NULL) && (fn->sk->data == fn))
{
- CBUNREG(fn->sk, socket_read, hubread, fn);
- CBUNREG(fn->sk, socket_err, huberr, fn);
+ fn->sk->data = NULL;
+ putfnetnode(fn);
}
if(hub == NULL)
return;
.filebasename = dcbasename
};
-static void cmdread(struct dcpeer *peer)
+static void peerread(struct socket *sk, struct dcpeer *peer)
{
- char *p;
- struct command *cmd;
-
- p = peer->inbuf;
- while((peer->inbufdata > 0) && (p = memchr(peer->inbuf, '|', peer->inbufdata)) != NULL)
- {
- *(p++) = 0;
- 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)] == ' ') || (peer->inbuf[strlen(cmd->name)] == '|')))
- break;
- }
- memmove(peer->inbuf, p, peer->inbufdata -= p - peer->inbuf);
- if(cmd->stop)
- {
- peer->state = PEER_STOP;
- break;
- }
- }
-}
-
-static int peerread(struct socket *sk, struct dcpeer *peer)
-{
- char *newbuf;
+ char *newbuf, *p;
size_t datalen;
+ struct command *cmd;
if((newbuf = sockgetinbuf(sk, &datalen)) == NULL)
- return(0);
+ return;
sizebuf2(peer->inbuf, peer->inbufdata + datalen, 1);
memcpy(peer->inbuf + peer->inbufdata, newbuf, datalen);
free(newbuf);
peer->inbufdata += datalen;
if(peer->state == PEER_CMD)
{
- cmdread(peer);
- } else if(peer->state == PEER_TRNS) {
- transread(peer);
+ p = peer->inbuf;
+ while((peer->inbufdata > 0) && (p = memchr(peer->inbuf, '|', peer->inbufdata)) != NULL)
+ {
+ *(p++) = 0;
+ 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)] == ' ') || (peer->inbuf[strlen(cmd->name)] == '|')))
+ break;
+ }
+ memmove(peer->inbuf, p, peer->inbufdata -= p - peer->inbuf);
+ if(cmd->stop)
+ {
+ peer->state = PEER_STOP;
+ break;
+ }
+ }
} else if(peer->state == PEER_TTHL) {
handletthl(peer);
}
- return(0);
}
-static int peererror(struct socket *sk, int err, struct dcpeer *peer)
+static void peererror(struct socket *sk, int err, struct dcpeer *peer)
{
- if(peer->state == PEER_TRNS)
- transerr(peer);
freedcpeer(peer);
- return(0);
}
-static int peerconnect(struct socket *sk, int err, struct fnetnode *fn)
+static void peerconnect(struct socket *sk, int err, struct fnetnode *fn)
{
struct dcpeer *peer;
struct dchub *hub;
{
putfnetnode(fn);
putsock(sk);
- return(1);
+ return;
}
hub = fn->data;
peer = newdcpeer(sk);
peer->fn = fn;
peer->accepted = 0;
peer->dcppemu = hub->dcppemu;
- CBREG(sk, socket_read, (int (*)(struct socket *, void *))peerread, NULL, peer);
- CBREG(sk, socket_err, (int (*)(struct socket *, int, void *))peererror, NULL, peer);
+ 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);
- return(1);
}
-static int peeraccept(struct socket *sk, struct socket *newsk, void *data)
+static void peeraccept(struct socket *sk, struct socket *newsk, void *data)
{
struct dcpeer *peer;
peer = newdcpeer(newsk);
peer->accepted = 1;
- CBREG(sk, socket_read, (int (*)(struct socket *, void *))peerread, NULL, peer);
- CBREG(sk, socket_err, (int (*)(struct socket *, int, void *))peererror, NULL, peer);
+ newsk->readcb = (void (*)(struct socket *, void *))peerread;
+ 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);
- return(0);
}
static void updatehmlist(void)
flog(LOG_WARNING, "could not create new DC UDP socket, reverting to old: %s", strerror(errno));
return(0);
}
- CBREG(newsock, socket_read, udpread, NULL, NULL);
+ newsock->readcb = udpread;
if(udpsock != NULL)
putsock(udpsock);
udpsock = newsock;
flog(LOG_CRIT, "could not create DC UDP socket: %s", strerror(errno));
return(1);
}
- CBREG(udpsock, socket_read, udpread, NULL, NULL);
+ udpsock->readcb = udpread;
addr.sin_port = htons(confgetint("dc", "tcpport"));
if((tcpsock = netcslisten(SOCK_STREAM, (struct sockaddr *)&addr, sizeof(addr), peeraccept, NULL)) == NULL)
flog(LOG_INFO, "could not listen to a remote address, going into passive mode");