fclose(stream);
}
-static void hashread(struct socket *sk, void *uudata)
+static int hashread(struct socket *sk, void *uudata)
{
static char *hashbuf;
static size_t hashbufsize = 0, hashbufdata = 0;
struct hashcache *hc;
if((buf = sockgetinbuf(sk, &bufsize)) == NULL)
- return;
+ return(0);
bufcat(hashbuf, buf, bufsize);
free(buf);
while((lp = memchr(hashbuf, '\n', hashbufdata)) != NULL)
}
memmove(hashbuf, lp, hashbufdata -= (lp - hashbuf));
}
+ return(0);
}
static void hashexit(pid_t pid, int status, struct socket *outsock)
close(fd);
close(pfd[1]);
outsock = wrapsock(pfd[0]);
- outsock->readcb = hashread;
+ CBREG(outsock, socket_read, hashread, NULL, NULL);
childcallback(hashjob, (void (*)(pid_t, int, void *))hashexit, outsock);
return(0);
}
if(fn->sk != NULL)
{
fn->sk->close = 1;
- if(fn->sk->data == fn)
- {
- fn->sk->data = NULL;
- putfnetnode(fn);
- }
putsock(fn->sk);
fn->sk = NULL;
}
}
-void getfnetnode(struct fnetnode *fn)
+struct fnetnode *getfnetnode(struct fnetnode *fn)
{
fn->refcount++;
#ifdef DEBUG
fprintf(stderr, "getfnetnode on id %i at %p, refcount=%i\n", fn->id, fn, fn->refcount);
#endif
+ return(fn);
}
void putfnetnode(struct fnetnode *fn)
putfnetnode(fn);
}
-static void conncb(struct socket *sk, int err, struct fnetnode *data)
+static int conncb(struct socket *sk, int err, struct fnetnode *data)
{
if(err != 0)
{
killfnetnode(data);
putfnetnode(data);
- return;
+ return(1);
}
data->sk = sk;
fnetsetstate(data, FNN_HS);
socksettos(sk, confgetint("fnet", "fntos"));
data->fnet->connect(data);
putfnetnode(data);
+ return(1);
}
static void resolvecb(struct sockaddr *addr, int addrlen, struct fnetnode *data)
killfnetnode(data);
putfnetnode(data);
} else {
- netcsconn(addr, addrlen, (void (*)(struct socket *, int, void *))conncb, data);
+ netcsconn(addr, addrlen, (int (*)(struct socket *, int, void *))conncb, data);
}
}
struct fnetnode *fnetinitconnect(wchar_t *name, wchar_t *owner, char *addr, struct wcspair *args);
void linkfnetnode(struct fnetnode *fn);
void unlinkfnetnode(struct fnetnode *fn);
-void getfnetnode(struct fnetnode *fn);
+struct fnetnode *getfnetnode(struct fnetnode *fn);
void putfnetnode(struct fnetnode *fn);
void killfnetnode(struct fnetnode *fn);
struct fnetpeer *fnetaddpeer(struct fnetnode *fn, wchar_t *id, wchar_t *nick);
flog(LOG_DEBUG, "unknown adc command: %ls", qcmd->args[0]);
}
-static void hubread(struct socket *sk, struct fnetnode *fn)
+static int hubread(struct socket *sk, struct fnetnode *fn)
{
int ret;
struct adchub *hub;
hub = fn->data;
if((newbuf = sockgetinbuf(sk, &datalen)) == NULL)
- return;
+ return(0);
if(hub->inbufdata > 1024)
hub->inbufdata = 0;
bufcat(hub->inbuf, newbuf, datalen);
if(errno == EILSEQ) {
flog(LOG_DEBUG, "adc fnetnode %i sent illegal utf-8 sequence", fn->id);
killfnetnode(fn);
- return;
+ return(0);
} else if(errno == EINVAL) {
break;
} else if(errno == E2BIG) {
/* continue; */
} else {
flog(LOG_WARNING, "bug? iconv returned unexpected error: %s", strerror(errno));
- return;
+ return(0);
}
}
}
newqcmd(&hub->queue, parseadc(hub->cb));
memmove(hub->cb, p, (hub->cbdata -= (p - hub->cb)) * sizeof(*(hub->cb)));
}
+ return(0);
}
-static void huberr(struct socket *sk, int err, struct fnetnode *fn)
+static int huberr(struct socket *sk, int err, struct fnetnode *fn)
{
killfnetnode(fn);
+ return(0);
}
static void hubconnect(struct fnetnode *fn)
{
struct adchub *hub;
- fn->sk->readcb = (void (*)(struct socket *, void *))hubread;
- fn->sk->errcb = (void (*)(struct socket *, int, void *))huberr;
- fn->sk->data = fn;
- getfnetnode(fn);
+ CBREG(fn->sk, socket_read, (int (*)(struct socket *, void *))hubread, (void (*)(void *))putfnetnode, fn);
+ CBREG(fn->sk, socket_err, (int (*)(struct socket *, int, void *))huberr, (void (*)(void *))putfnetnode, fn);
hub = smalloc(sizeof(*hub));
memset(hub, 0, sizeof(*hub));
static char *xmlbz2listname = NULL;
static struct timer *listwritetimer = NULL;
-static void peerconnect(struct socket *sk, int err, struct fnetnode *fn);
+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 freedcpeer(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 transread(struct dcpeer *peer);
+static void transerr(struct dcpeer *peer);
+static int 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), (void (*)(struct socket *, int, void *))peerconnect, fn);
+ newsk = netcsconn((struct sockaddr *)&addr, sizeof(addr), (int (*)(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);
- peer->sk->writecb = (void (*)(struct socket *, void *))transwrite;
+ CBREG(peer->sk, socket_write, (int (*)(struct socket *, void *))transwrite, NULL, peer);
}
static void cmd_filelength(struct socket *sk, struct dcpeer *peer, char *cmd, char *args)
goto out;
}
startdl(peer);
- if(peer->inbufdata > 0)
- {
- sockpushdata(sk, peer->inbuf, peer->inbufdata);
- peer->inbufdata = 0;
- transread(sk, peer);
- }
+ transread(peer);
} else {
/* We certainly didn't request this...*/
freedcpeer(peer);
return;
}
startdl(peer);
- if(peer->inbufdata > 0)
- {
- sockpushdata(sk, peer->inbuf, peer->inbufdata);
- peer->inbufdata = 0;
- transread(sk, peer);
- }
+ transread(peer);
}
/*
static void dctransdetach(struct transfer *transfer, struct dcpeer *peer)
{
- CBUNREG(transfer, trans_filterout, peer);
+ CBUNREG(transfer, trans_filterout, trresumecb, peer);
if(peer->freeing)
return;
peer->transfer = NULL;
transfersetstate(transfer, TRNS_HS);
socksettos(peer->sk, confgetint("fnet", "fnptos"));
transfer->flags.b.minislot = 0;
- peer->sk->writecb = NULL;
+ CBUNREG(peer->sk, socket_write, transwrite, peer);
}
}
}
peer->sk->ignread = 0;
}
-static void transread(struct socket *sk, struct dcpeer *peer)
+static void transread(struct dcpeer *peer)
{
- void *buf;
- size_t bufsize;
+ size_t num;
struct transfer *transfer;
- if((buf = sockgetinbuf(sk, &bufsize)) == NULL)
- return;
if(peer->transfer == NULL)
{
- free(buf);
freedcpeer(peer);
return;
}
- transferputdata(peer->transfer, buf, bufsize);
- free(buf);
+ 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);
if(peer->transfer->curpos >= peer->transfer->size)
{
transfer = peer->transfer;
return;
}
if(transferdatasize(peer->transfer) > 65535)
- sk->ignread = 1;
+ peer->sk->ignread = 1;
}
-static void transerr(struct socket *sk, int err, struct dcpeer *peer)
+static void transerr(struct dcpeer *peer)
{
struct transfer *transfer;
if((transfer = peer->transfer) == NULL)
- {
- freedcpeer(peer);
return;
- }
transferdetach(transfer);
transferendofdata(transfer);
}
-static void transwrite(struct socket *sk, struct dcpeer *peer)
+static int transwrite(struct socket *sk, struct dcpeer *peer)
{
if((peer->state != PEER_TRNS) && (peer->state != PEER_SYNC))
- return;
+ return(1);
if(peer->transfer == NULL)
{
freedcpeer(peer);
- return;
+ return(1);
}
dctransgotdata(peer->transfer, peer);
+ return(0);
}
-static void udpread(struct socket *sk, void *data)
+static int 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;
+ return(0);
buf = srealloc(buf, buflen + 1);
buf[buflen] = 0;
if(!strncmp(buf, "$SR ", 4))
if((p2 = strchr(p, ' ')) == NULL)
{
free(buf);
- return;
+ return(0);
}
*p2 = 0;
p = p2 + 1;
if((p2 = strchr(p, 5)) == NULL)
{
free(buf);
- return;
+ return(0);
}
*p2 = 0;
p = p2 + 1;
if((p2 = strchr(p, ' ')) == NULL)
{
free(buf);
- return;
+ return(0);
}
*p2 = 0;
size = atoi(p);
if((p2 = strchr(p, '/')) == NULL)
{
free(buf);
- return;
+ return(0);
}
*p2 = 0;
slots = atoi(p);
if((p2 = strchr(p, 5)) == NULL)
{
free(buf);
- return;
+ return(0);
}
p = p2 + 1;
hubname = p;
if((p2 = strstr(p, " (")) == NULL)
{
free(buf);
- return;
+ return(0);
}
*p2 = 0;
p = p2 + 2;
if((p2 = strchr(p, ':')) == NULL)
{
free(buf);
- return;
+ return(0);
}
*(p2++) = 0;
hubaddr.sin_family = AF_INET;
if(!inet_aton(p, &hubaddr.sin_addr))
{
free(buf);
- return;
+ return(0);
}
p = p2;
if((p2 = strchr(p, ')')) == NULL)
{
free(buf);
- return;
+ return(0);
}
*p2 = 0;
hubaddr.sin_port = htons(atoi(p));
if((wfile = icmbstowcs(filename, DCCHARSET)) == NULL)
{
free(buf);
- return;
+ return(0);
}
myfn = NULL;
hash = NULL;
if((wnick = icmbstowcs(nick, (hub == NULL)?DCCHARSET:(hub->charset))) == NULL)
{
free(buf);
- return;
+ return(0);
}
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);
- if(peer->sk->data == peer)
- peer->sk->data = NULL;
- peer->sk->readcb = NULL;
- peer->sk->writecb = NULL;
- peer->sk->errcb = NULL;
+ /* XXX: Unregister transwrite from peer->sk->socket_write? */
+ CBUNREG(peer->sk, socket_read, peerread, peer);
+ CBUNREG(peer->sk, socket_err, peererror, peer);
putsock(peer->sk);
endcompress(peer);
if(peer->supports != NULL)
static void hubconnect(struct fnetnode *fn)
{
- fn->sk->readcb = (void (*)(struct socket *, void *))hubread;
- fn->sk->errcb = (void (*)(struct socket *, int, void *))huberr;
- getfnetnode(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->data = newdchub(fn);
- fn->sk->data = fn;
return;
}
struct qcommand *qcmd;
hub = (struct dchub *)fn->data;
- if((fn->sk != NULL) && (fn->sk->data == fn))
+ if(fn->sk != NULL)
{
- fn->sk->data = NULL;
- putfnetnode(fn);
+ CBUNREG(fn->sk, socket_read, hubread, fn);
+ CBUNREG(fn->sk, socket_err, huberr, fn);
}
if(hub == NULL)
return;
.filebasename = dcbasename
};
-static void peerread(struct socket *sk, struct dcpeer *peer)
+static void cmdread(struct dcpeer *peer)
{
- char *newbuf, *p;
- size_t datalen;
+ 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;
+ size_t datalen;
+
if((newbuf = sockgetinbuf(sk, &datalen)) == NULL)
- return;
+ return(0);
sizebuf2(peer->inbuf, peer->inbufdata + datalen, 1);
memcpy(peer->inbuf + peer->inbufdata, newbuf, datalen);
free(newbuf);
peer->inbufdata += datalen;
if(peer->state == PEER_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;
- }
- }
+ cmdread(peer);
+ } else if(peer->state == PEER_TRNS) {
+ transread(peer);
} else if(peer->state == PEER_TTHL) {
handletthl(peer);
}
+ return(0);
}
-static void peererror(struct socket *sk, int err, struct dcpeer *peer)
+static int peererror(struct socket *sk, int err, struct dcpeer *peer)
{
+ if(peer->state == PEER_TRNS)
+ transerr(peer);
freedcpeer(peer);
+ return(0);
}
-static void peerconnect(struct socket *sk, int err, struct fnetnode *fn)
+static int peerconnect(struct socket *sk, int err, struct fnetnode *fn)
{
struct dcpeer *peer;
struct dchub *hub;
{
putfnetnode(fn);
putsock(sk);
- return;
+ return(1);
}
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;
+ CBREG(sk, socket_read, (int (*)(struct socket *, void *))peerread, NULL, peer);
+ CBREG(sk, socket_err, (int (*)(struct socket *, int, void *))peererror, NULL, 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 void peeraccept(struct socket *sk, struct socket *newsk, void *data)
+static int peeraccept(struct socket *sk, struct socket *newsk, void *data)
{
struct dcpeer *peer;
peer = newdcpeer(newsk);
peer->accepted = 1;
- newsk->readcb = (void (*)(struct socket *, void *))peerread;
- newsk->errcb = (void (*)(struct socket *, int, void *))peererror;
- newsk->data = peer;
+ CBREG(sk, socket_read, (int (*)(struct socket *, void *))peerread, NULL, peer);
+ CBREG(sk, socket_err, (int (*)(struct socket *, int, void *))peererror, NULL, 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);
}
- newsock->readcb = udpread;
+ CBREG(newsock, socket_read, udpread, NULL, NULL);
if(udpsock != NULL)
putsock(udpsock);
udpsock = newsock;
flog(LOG_CRIT, "could not create DC UDP socket: %s", strerror(errno));
return(1);
}
- udpsock->readcb = udpread;
+ CBREG(udpsock, socket_read, udpread, NULL, NULL);
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");
new->inbuf.d.f = new->inbuf.d.l = NULL;
break;
}
- new->conncb = NULL;
- new->errcb = NULL;
- new->readcb = NULL;
- new->writecb = NULL;
- new->acceptcb = NULL;
+ CBCHAININIT(new, socket_conn);
+ CBCHAININIT(new, socket_err);
+ CBCHAININIT(new, socket_read);
+ CBCHAININIT(new, socket_write);
+ CBCHAININIT(new, socket_accept);
new->next = sockets;
new->prev = NULL;
if(sockets != NULL)
if(--(sk->refcount) == 0)
{
+ CBCHAINFREE(sk, socket_conn);
+ CBCHAINFREE(sk, socket_err);
+ CBCHAINFREE(sk, socket_read);
+ CBCHAINFREE(sk, socket_write);
+ CBCHAINFREE(sk, socket_accept);
switch(sk->type)
{
case SOCK_STREAM:
{
if((errno == EINTR) || (errno == EAGAIN))
return;
- if(sk->errcb != NULL)
- sk->errcb(sk, errno, sk->data);
+ CBCHAINDOCB(sk, socket_err, sk, errno);
closesock(sk);
return;
}
if(ret == 0)
{
- if(sk->errcb != NULL)
- sk->errcb(sk, 0, sk->data);
+ CBCHAINDOCB(sk, socket_err, sk, 0);
closesock(sk);
return;
}
sk->inbuf.s.datasize += ret;
- if(sk->readcb != NULL)
- sk->readcb(sk, sk->data);
+ CBCHAINDOCB(sk, socket_read, sk);
break;
case SOCK_DGRAM:
if(ioctl(sk->fd, SIOCINQ, &inq))
free(dbuf);
if((errno == EINTR) || (errno == EAGAIN))
return;
- if(sk->errcb != NULL)
- sk->errcb(sk, errno, sk->data);
+ CBCHAINDOCB(sk, socket_err, sk, errno);
closesock(sk);
return;
}
free(dbuf);
if(!((sk->family == AF_INET) || (sk->family == AF_INET6)))
{
- if(sk->errcb != NULL)
- sk->errcb(sk, 0, sk->data);
+ CBCHAINDOCB(sk, socket_err, sk, 0);
closesock(sk);
}
return;
else
sk->inbuf.d.f = dbuf;
sk->inbuf.d.l = dbuf;
- if(sk->readcb != NULL)
- sk->readcb(sk, sk->data);
+ CBCHAINDOCB(sk, socket_read, sk);
break;
}
}
if(ret > 0)
{
memmove(sk->outbuf.s.buf, ((char *)sk->outbuf.s.buf) + ret, sk->outbuf.s.datasize -= ret);
- if(sk->writecb != NULL)
- sk->writecb(sk, sk->data);
+ CBCHAINDOCB(sk, socket_write, sk);
}
break;
case SOCK_DGRAM:
free(dbuf->data);
free(dbuf->addr);
free(dbuf);
- if(sk->writecb != NULL)
- sk->writecb(sk, sk->data);
+ CBCHAINDOCB(sk, socket_write, sk);
break;
}
}
* netcslisten() instead.
*/
-struct socket *netcslistenlocal(int type, struct sockaddr *name, socklen_t namelen, void (*func)(struct socket *, struct socket *, void *), void *data)
+struct socket *netcslistenlocal(int type, struct sockaddr *name, socklen_t namelen, int (*func)(struct socket *, struct socket *, void *), void *data)
{
struct socket *sk;
int intbuf;
putsock(sk);
return(NULL);
}
- sk->acceptcb = func;
- sk->data = data;
+ if(func != NULL)
+ CBREG(sk, socket_accept, func, NULL, data);
return(sk);
}
-struct socket *netcslisten(int type, struct sockaddr *name, socklen_t namelen, void (*func)(struct socket *, struct socket *, void *), void *data)
+struct socket *netcslisten(int type, struct sockaddr *name, socklen_t namelen, int (*func)(struct socket *, struct socket *, void *), void *data)
{
if(confgetint("net", "mode") == 1)
{
return(NULL);
}
-struct socket *netcstcplisten(int port, int local, void (*func)(struct socket *, struct socket *, void *), void *data)
+struct socket *netcstcplisten(int port, int local, int (*func)(struct socket *, struct socket *, void *), void *data)
{
struct sockaddr_in addr;
#ifdef HAVE_IPV6
struct sockaddr_in6 addr6;
#endif
- struct socket *(*csfunc)(int, struct sockaddr *, socklen_t, void (*)(struct socket *, struct socket *, void *), void *);
+ struct socket *(*csfunc)(int, struct sockaddr *, socklen_t, int (*)(struct socket *, struct socket *, void *), void *);
struct socket *ret;
if(local)
sk->ignread = 1;
}
-struct socket *netcsconn(struct sockaddr *addr, socklen_t addrlen, void (*func)(struct socket *, int, void *), void *data)
+struct socket *netcsconn(struct sockaddr *addr, socklen_t addrlen, int (*func)(struct socket *, int, void *), void *data)
{
struct socket *sk;
int mode;
if(errno == EINPROGRESS)
{
sk->state = SOCK_SYN;
- sk->conncb = func;
- sk->data = data;
+ if(func != NULL)
+ CBREG(sk, socket_conn, func, NULL, data);
return(sk);
}
putsock(sk);
{
sslen = sizeof(ss);
if((newfd = accept(sk->fd, (struct sockaddr *)&ss, &sslen)) < 0)
- {
- if(sk->errcb != NULL)
- sk->errcb(sk, errno, sk->data);
- }
+ CBCHAINDOCB(sk, socket_err, sk, errno);
newsk = newsock(sk->type);
newsk->fd = newfd;
newsk->family = sk->family;
memcpy(newsk->remote = smalloc(sslen), &ss, sslen);
newsk->remotelen = sslen;
putsock(newsk);
- if(sk->acceptcb != NULL)
- sk->acceptcb(sk, newsk, sk->data);
+ CBCHAINDOCB(sk, socket_accept, sk, newsk);
}
if(pfds[i].revents & POLLERR)
{
retlen = sizeof(ret);
getsockopt(sk->fd, SOL_SOCKET, SO_ERROR, &ret, &retlen);
- if(sk->errcb != NULL)
- sk->errcb(sk, ret, sk->data);
+ CBCHAINDOCB(sk, socket_err, sk, ret);
continue;
}
break;
{
retlen = sizeof(ret);
getsockopt(sk->fd, SOL_SOCKET, SO_ERROR, &ret, &retlen);
- if(sk->conncb != NULL)
- sk->conncb(sk, ret, sk->data);
+ CBCHAINDOCB(sk, socket_conn, sk, ret);
closesock(sk);
continue;
}
if(pfds[i].revents & (POLLIN | POLLOUT))
{
sk->state = SOCK_EST;
- if(sk->conncb != NULL)
- sk->conncb(sk, 0, sk->data);
+ CBCHAINDOCB(sk, socket_conn, sk, 0);
}
break;
case SOCK_EST:
{
retlen = sizeof(ret);
getsockopt(sk->fd, SOL_SOCKET, SO_ERROR, &ret, &retlen);
- if(sk->errcb != NULL)
- sk->errcb(sk, ret, sk->data);
+ CBCHAINDOCB(sk, socket_err, sk, ret);
closesock(sk);
continue;
}
}
if(pfds[i].revents & POLLHUP)
{
- if(sk->errcb != NULL)
- sk->errcb(sk, 0, sk->data);
+ CBCHAINDOCB(sk, socket_err, sk, 0);
closesock(sk);
unlinksock(sk);
continue;
#include <sys/socket.h>
+#include <utils.h>
+
#define SOCK_LST 0 /* Listening */
#define SOCK_SYN 1 /* Connecting */
#define SOCK_EST 2 /* Established */
size_t datasize;
} s;
} inbuf;
+ /*
void (*conncb)(struct socket *sk, int err, void *data);
void (*errcb)(struct socket *sk, int err, void *data);
void (*readcb)(struct socket *sk, void *data);
void (*writecb)(struct socket *sk, void *data);
void (*acceptcb)(struct socket *sk, struct socket *newsk, void *data);
void *data;
+ */
+ CBCHAIN(socket_conn, struct socket *sk, int err);
+ CBCHAIN(socket_err, struct socket *sk, int err);
+ CBCHAIN(socket_read, struct socket *sk);
+ CBCHAIN(socket_write, struct socket *sk);
+ CBCHAIN(socket_accept, struct socket *sk, struct socket *newsk);
};
void putsock(struct socket *sk);
void getsock(struct socket *sk);
-struct socket *netcslisten(int type, struct sockaddr *name, socklen_t namelen, void (*func)(struct socket *, struct socket *, void *), void *data);
-struct socket *netcslistenlocal(int type, struct sockaddr *name, socklen_t namelen, void (*func)(struct socket *, struct socket *, void *), void *data);
-struct socket *netcstcplisten(int port, int local, void (*func)(struct socket *, struct socket *, void *), void *data);
-struct socket *netcsconn(struct sockaddr *addr, socklen_t addrlen, void (*func)(struct socket *, int, void *), void *data);
+struct socket *netcslisten(int type, struct sockaddr *name, socklen_t namelen, int (*func)(struct socket *, struct socket *, void *), void *data);
+struct socket *netcslistenlocal(int type, struct sockaddr *name, socklen_t namelen, int (*func)(struct socket *, struct socket *, void *), void *data);
+struct socket *netcstcplisten(int port, int local, int (*func)(struct socket *, struct socket *, void *), void *data);
+struct socket *netcsconn(struct sockaddr *addr, socklen_t addrlen, int (*func)(struct socket *, int, void *), void *data);
int pollsocks(int timeout);
void sockqueue(struct socket *sk, void *data, size_t size);
size_t sockqueuesize(struct socket *sk);
#include "client.h"
static void killfilter(struct transfer *transfer);
+static int transferread(struct socket *sk, struct transfer *transfer);
+static int transferwrite(struct socket *sk, struct transfer *transfer);
+static int transfererr(struct socket *sk, int errno, struct transfer *transfer);
+static int filterread(struct socket *sk, struct transfer *transfer);
unsigned long long bytesupload = 0;
unsigned long long bytesdownload = 0;
free(transfer->exitstatus);
if(transfer->localend != NULL)
{
- transfer->localend->readcb = NULL;
- transfer->localend->writecb = NULL;
- transfer->localend->errcb = NULL;
+ CBUNREG(transfer->localend, socket_read, transferread, transfer);
+ CBUNREG(transfer->localend, socket_write, transferwrite, transfer);
+ CBUNREG(transfer->localend, socket_err, transfererr, transfer);
putsock(transfer->localend);
}
if(transfer->filterout != NULL)
{
- transfer->filterout->readcb = NULL;
- transfer->filterout->writecb = NULL;
- transfer->filterout->errcb = NULL;
+ CBUNREG(transfer->filterout, socket_read, filterread, transfer);
putsock(transfer->filterout);
}
if(transfer->fn != NULL)
transfer->timeout = 0;
}
-static void transferread(struct socket *sk, struct transfer *transfer)
+static int transferread(struct socket *sk, struct transfer *transfer)
{
if(sockgetdatalen(sk) >= 65536)
sk->ignread = 1;
if((transfer->iface != NULL) && (transfer->iface->gotdata != NULL))
transfer->iface->gotdata(transfer, transfer->ifacedata);
+ return(0);
}
-static void transferwrite(struct socket *sk, struct transfer *transfer)
+static int transferwrite(struct socket *sk, struct transfer *transfer)
{
if((transfer->iface != NULL) && (transfer->iface->wantdata != NULL))
transfer->iface->wantdata(transfer, transfer->ifacedata);
+ return(0);
}
-static void transfererr(struct socket *sk, int errno, struct transfer *transfer)
+static int transfererr(struct socket *sk, int errno, struct transfer *transfer)
{
if((transfer->iface != NULL) && (transfer->iface->endofdata != NULL))
transfer->iface->endofdata(transfer, transfer->ifacedata);
+ return(0);
}
void transferputdata(struct transfer *transfer, void *buf, size_t size)
if(transfer->curpos >= transfer->size)
{
transfersetstate(transfer, TRNS_DONE);
- transfer->localend->readcb = NULL;
- transfer->localend->writecb = NULL;
- transfer->localend->errcb = NULL;
+ CBUNREG(transfer->localend, socket_read, transferread, transfer);
+ CBUNREG(transfer->localend, socket_write, transferwrite, transfer);
+ CBUNREG(transfer->localend, socket_err, transfererr, transfer);
putsock(transfer->localend);
transfer->localend = NULL;
} else {
if(transfer->localend != NULL)
putsock(transfer->localend);
getsock(transfer->localend = sk);
- sk->data = transfer;
- sk->readcb = (void (*)(struct socket *, void *))transferread;
- sk->writecb = (void (*)(struct socket *, void *))transferwrite;
- sk->errcb = (void (*)(struct socket *, int, void *))transfererr;
+ CBREG(sk, socket_read, (int (*)(struct socket *, void *))transferread, NULL, transfer);
+ CBREG(sk, socket_write, (int (*)(struct socket *, void *))transferwrite, NULL, transfer);
+ CBREG(sk, socket_err, (int (*)(struct socket *, int, void *))transfererr, NULL, transfer);
}
static int tryreq(struct transfer *transfer)
}
if(transfer->localend)
{
- transfer->localend->readcb = NULL;
- transfer->localend->writecb = NULL;
- transfer->localend->errcb = NULL;
+ CBUNREG(transfer->localend, socket_read, transferread, transfer);
+ CBUNREG(transfer->localend, socket_write, transferwrite, transfer);
+ CBUNREG(transfer->localend, socket_err, transfererr, transfer);
putsock(transfer->localend);
transfer->localend = NULL;
}
if(transfer->filterout)
{
- transfer->filterout->readcb = NULL;
+ CBUNREG(transfer->filterout, socket_read, filterread, transfer);
putsock(transfer->filterout);
transfer->filterout = NULL;
}
}
}
-static void filterread(struct socket *sk, struct transfer *transfer)
+static int filterread(struct socket *sk, struct transfer *transfer)
{
char *buf, *p, *p2;
size_t bufsize;
wchar_t *cmd, *arg;
if((buf = sockgetinbuf(sk, &bufsize)) == NULL)
- return;
+ return(0);
bufcat(transfer->filterbuf, buf, bufsize);
free(buf);
while((p = memchr(transfer->filterbuf, '\n', transfer->filterbufdata)) != NULL)
}
memmove(transfer->filterbuf, p, transfer->filterbufdata -= (p - transfer->filterbuf));
}
+ return(0);
}
static void filterexit(pid_t pid, int status, void *data)
transfer->filter = pid;
transfersetlocalend(transfer, insock);
getsock(transfer->filterout = outsock);
- outsock->data = transfer;
- outsock->readcb = (void (*)(struct socket *, void *))filterread;
+ CBREG(outsock, socket_read, (int (*)(struct socket *, void *))filterread, NULL, transfer);
putsock(insock);
putsock(outsock);
free(filtername);
size_t cwsize, cwdata;
};
+static int uiread(struct socket *sk, struct uidata *data);
+static int uierror(struct socket *sk, int err, struct uidata *data);
static int srcheta(struct search *srch, void *uudata);
static int srchcommit(struct search *srch, void *uudata);
static int srchres(struct search *srch, struct srchres *sr, void *uudata);
sq(sk, 0, L"200", L"Search cancelled", NULL);
}
-static void fcmdread(struct socket *sk, struct uidata *data)
+static int fcmdread(struct socket *sk, struct uidata *data)
{
char *buf;
size_t bufsize;
if((buf = sockgetinbuf(sk, &bufsize)) == NULL)
- return;
+ return(0);
bufcat(data->fcmdbuf, buf, bufsize);
free(buf);
+ return(0);
}
-static void fcmderr(struct socket *sk, int err, struct uidata *data)
+static int fcmderr(struct socket *sk, int err, struct uidata *data)
{
wchar_t *wbuf, *p, *p2;
}
data->fcmdbufsize = data->fcmdbufdata = 0;
sq(data->sk, 0, L"505", L"An error occurred on the pipe to the filtercmd", L"%%s", strerror(err), NULL);
- return;
+ return(0);
}
putsock(data->fcmdsk);
data->fcmdsk = NULL;
if(wbuf == NULL)
{
sq(data->sk, 0, L"504", L"Filtercmd sent data which could not be converted from the local charset", NULL);
- return;
+ return(0);
}
p = wbuf;
for(p2 = wcschr(p, L'\n'); p2 != NULL; p2 = wcschr(p, L'\n'))
sq(data->sk, 0, L"200", L"%%ls", p, NULL);
}
free(wbuf);
+ return(0);
}
static void cmd_filtercmd(struct socket *sk, struct uidata *data, int argc, wchar_t **argv)
data->fcmdbuf = NULL;
}
data->fcmdbufsize = data->fcmdbufdata = 0;
- data->fcmdsk->data = data;
- data->fcmdsk->readcb = (void (*)(struct socket *, void *))fcmdread;
- data->fcmdsk->errcb = (void (*)(struct socket *, int, void *))fcmderr;
+ CBREG(data->fcmdsk, socket_read, (int (*)(struct socket *, void *))fcmdread, NULL, NULL);
+ CBREG(data->fcmdsk, socket_err, (int (*)(struct socket *, int, void *))fcmderr, NULL, NULL);
}
static void cmd_lstrarg(struct socket *sk, struct uidata *data, int argc, wchar_t **argv)
data->prev->next = data->next;
if(data == actives)
actives = data->next;
- data->sk->readcb = NULL;
- data->sk->errcb = NULL;
+ CBUNREG(data->sk, socket_read, uiread, data);
+ CBUNREG(data->sk, socket_err, uierror, data);
putsock(data->sk);
while((qcmd = unlinkqcmd(data)) != NULL)
freequeuecmd(qcmd);
return(data);
}
-static void uiread(struct socket *sk, struct uidata *data)
+static int uiread(struct socket *sk, struct uidata *data)
{
int ret, done;
char *newbuf;
if(data->indata > 1024)
data->indata = 0;
if((newbuf = sockgetinbuf(sk, &datalen)) == NULL)
- return;
+ return(0);
sizebuf(&data->inbuf, &data->inbufsize, data->indata + datalen, 1, 1);
memcpy(data->inbuf + data->indata, newbuf, datalen);
free(newbuf);
break;
}
}
+ return(0);
}
-static void uierror(struct socket *sk, int err, struct uidata *data)
+static int uierror(struct socket *sk, int err, struct uidata *data)
{
if(err)
flog(LOG_WARNING, "error occurred on UI socket: %s", strerror(err));
freeuidata(data);
+ return(0);
}
-static void uiaccept(struct socket *sk, struct socket *newsk, void *data)
+static int uiaccept(struct socket *sk, struct socket *newsk, void *data)
{
struct uidata *uidata;
- newsk->data = uidata = newuidata(newsk);
+ uidata = newuidata(newsk);
socksettos(newsk, confgetint("ui", "uitos"));
if(uidata == NULL)
- return;
- newsk->errcb = (void (*)(struct socket *, int, void *))uierror;
- newsk->readcb = (void (*)(struct socket *, void *))uiread;
+ return(0);
+ CBREG(newsk, socket_err, (int (*)(struct socket *, int, void *))uierror, NULL, data);
+ CBREG(newsk, socket_read, (int (*)(struct socket *, void *))uiread, NULL, data);
queuecmd(uidata, &commands[0], 0, NULL);
+ return(0);
}
static int srcheta(struct search *srch, void *uudata)