#include <bzlib.h>
#include <zlib.h>
#include <sys/stat.h>
+#include <stdint.h>
#ifdef HAVE_CONFIG_H
#include <config.h>
* considering it was developed without i18n support under Windows */
#define DCCHARSET "windows-1252"
-#ifdef DCPP_MASQUERADE
-/*
- * I honestly don't want to pretend being a client that I'm not, but
- * there are so many hubs that simply do not accept any clients
- * outside their whitelists, for no obvious reasons, so I feel that I
- * am left with little choice. Anyhow, as long as I actually support
- * all the features that my faked DC++ version does, there should be
- * very little harm done.
- */
-#define DCIDTAG "++"
-#define DCIDTAGV "0.674"
-#define DCIDFULL "DC++ 0.674"
-#else
-#define DCIDTAG "Dolda"
-#define DCIDTAGV VERSION
-#define DCIDFULL "DoldaConnect " VERSION
-#endif
-
#define PEER_CMD 0
#define PEER_STOP 1
#define PEER_TRNS 2
static struct fnet dcnet;
static struct transferiface dctransfer;
static struct socket *udpsock = NULL;
-static struct socket *tcpsock = NULL;
+static struct lport *tcpsock = NULL;
static struct dcpeer *peers = NULL;
int numdcpeers = 0;
static struct dcexppeer *expected = NULL;
size_t buflen;
int termnum, satisfied, skipcheck;
int level, tersat[32];
- wchar_t *terms[32];
+ wchar_t *terms[32], *lname;
char hashtth[24];
hub = fn->data;
goto out;
prefix = sprintf2("$SR %s ", hub->nativenick);
infix = sprintf2(" %i/%i\005", slotsleft(), confgetint("transfer", "slots"));
- postfix = sprintf2(" (%s)\005%s|", formataddress(hub->sk->remote, hub->sk->remotelen), args + 4);
+ postfix = sprintf2(" (%s)\005%s|", formatsockpeer(hub->sk), args + 4);
dsk = sk;
getsock(dsk);
} else {
addr.sin_port = htons(atoi(p2));
prefix = sprintf2("$SR %s ", hub->nativenick);
infix = sprintf2(" %i/%i\005", slotsleft(), confgetint("transfer", "slots"));
- postfix = sprintf2(" (%s)|", formataddress(hub->sk->remote, hub->sk->remotelen));
- netdgramconn(dsk = netdupsock(udpsock), (struct sockaddr *)&addr, sizeof(addr));
+ postfix = sprintf2(" (%s)|", formatsockpeer(hub->sk));
+ dsk = netdgramconn(udpsock, (struct sockaddr *)&addr, sizeof(addr));
}
minsize = maxsize = -1;
memcpy(hashtth, buf, 24);
free(buf);
} else {
- if((terms[termnum] = icmbstowcs(p, hub->charset)) != NULL)
+ if((terms[termnum] = icmbstowcs(p, hub->charset)) != NULL) {
+ wcslower(terms[termnum]);
termnum++;
+ }
}
}
p = p2 + 1;
}
if(!skipcheck)
{
+ lname = wcslower(swcsdup(node->name));
for(i = 0; i < termnum; i++)
{
if(tersat[i] >= 0)
continue;
- if(wcsexists(node->name, terms[i]))
+ if(wcsstr(lname, terms[i]))
{
tersat[i] = level;
satisfied++;
break;
}
}
+ free(lname);
}
if(!skipcheck && (satisfied == termnum))
{
if(tcpsock == NULL)
return;
- if(sockgetremotename2(tcpsock, sk, &addr, &addrlen) < 0)
+ if(getremotename2(tcpsock, sk, &addr, &addrlen) < 0)
return;
if(addr->sa_family == AF_INET)
qstrf(sk, "$ConnectToMe %s %s|", nick, formataddress(addr, addrlen));
{
sockpushdata(sk, peer->inbuf, peer->inbufdata);
peer->inbufdata = 0;
- transread(sk, peer);
}
} else {
/* We certainly didn't request this...*/
{
sockpushdata(sk, peer->inbuf, peer->inbufdata);
peer->inbufdata = 0;
- transread(sk, peer);
}
}
static void dcwantdata(struct transfer *transfer, struct dcpeer *peer)
{
if(transferdatasize(transfer) < 65536)
- peer->sk->ignread = 0;
+ sockblock(peer->sk, 0);
}
static void transread(struct socket *sk, struct dcpeer *peer)
return;
}
if(transferdatasize(peer->transfer) > 65535)
- sk->ignread = 1;
+ sockblock(sk, 1);
}
static void transerr(struct socket *sk, int err, struct dcpeer *peer)
size_t buflen, hashlen;
char *nick, *filename, *hubname;
struct sockaddr_in hubaddr;
+ struct sockaddr *addrbuf;
off_t size;
int slots;
struct fnetnode *fn, *myfn;
{
for(fn = fnetnodes; fn != NULL; fn = fn->next)
{
- if((fn->fnet == &dcnet) && ((hub = fn->data) != NULL))
+ if((fn->fnet == &dcnet) && ((hub = fn->data) != NULL) && !sockpeeraddr(hub->sk, &addrbuf, NULL))
{
- if((hub->sk != NULL) && addreq(hub->sk->remote, (struct sockaddr *)&hubaddr))
+ if((hub->sk != NULL) && addreq(addrbuf, (struct sockaddr *)&hubaddr))
{
myfn = fn;
break;
}
+ free(addrbuf);
}
}
}
free(newbuf);
p = hub->inbuf;
hub->inbufdata += datalen;
- while((datalen > 0) && ((p2 = memchr(p, '|', datalen)) != NULL))
+ while((p - hub->inbuf < hub->inbufdata) && ((p2 = memchr(p, '|', hub->inbufdata - (p - hub->inbuf))) != NULL))
{
*(p2++) = 0;
for(cmd = hubcmds; cmd->handler != NULL; cmd++)
}
if((cmd->limit == 0) || (hub->queue.size < cmd->limit))
newqcmd(&hub->queue, p);
- datalen -= p2 - p;
p = p2;
}
memmove(hub->inbuf, p, hub->inbufdata -= p - hub->inbuf);
if(hub->queue.size > 1000)
- sk->ignread = 1;
+ sockblock(sk, 1);
}
static void huberr(struct socket *sk, int err, struct fnetnode *fn)
peer->transfer->close = 1;
if(peer->transfer->dir == TRNSD_DOWN)
resettransfer(peer->transfer);
- transferdetach(peer->transfer);
}
if(peer->timeout != NULL)
canceltimer(peer->timeout);
struct dchub *hub;
hub = (struct dchub *)fn->data;
- hub->sk->close = 1;
-}
-
-static wchar_t *dcbasename(wchar_t *filename)
-{
- wchar_t *ret;
-
- if((ret = wcsrchr(filename, L'/')) != NULL)
- return(ret + 1);
- return(filename);
+ closesock(hub->sk);
}
static struct transferiface dctransfer =
.reqconn = hubreqconn,
.sendchat = hubsendchat,
.search = hubsearch,
- .filebasename = dcbasename
};
static void peerread(struct socket *sk, struct dcpeer *peer)
break;
} else {
if(peer->queue.size > 50)
- sk->ignread = 1;
+ sockblock(sk, 1);
}
}
} else if(peer->state == PEER_TTHL) {
handletthl(peer);
}
if(peer->inbufdata > 500000)
- sk->ignread = 1;
+ sockblock(sk, 1);
}
static void peererror(struct socket *sk, int err, struct dcpeer *peer)
sendpeerlock(peer);
}
-static void peeraccept(struct socket *sk, struct socket *newsk, void *data)
+static void peeraccept(struct lport *lp, struct socket *newsk, void *data)
{
struct dcpeer *peer;
char *buf, *buf2, numbuf[32];
size_t bufsize, bufdata;
int fd, ibuf;
+ FILE *out;
bufdata = 0;
buf = smalloc(bufsize = 65536);
free(hmlistname);
hmlistname = NULL;
} else {
+ out = fdopen(fd, "w");
/*
* I do not want to implement a good Huffman encoder, and it's not
* like Huffman encoding actually yields any impressive results
* for DC file lists anyway, so I'll just output a bogus
* tree. Implement a good encoder if you want to.
*/
- write(fd, "HE3\r\0", 5);
- write(fd, &bufdata, 4);
+ fwrite("HE3\r\0", 1, 5, out);
+ fwrite(&bufdata, 4, 1, out); /* XXX: Endian unsafe */
ibuf = 256;
- write(fd, &ibuf, 2);
+ fwrite(&ibuf, 2, 1, out);
ibuf = 8;
for(i = 0; i < 256; i++)
{
- write(fd, &i, 1);
- write(fd, &ibuf, 1);
+ fwrite(&i, 1, 1, out);
+ fwrite(&ibuf, 1, 1, out);
}
for(i = 0; i < 256; i++)
- write(fd, &i, 1);
+ fwrite(&i, 1, 1, out);
for(buf2 = buf; bufdata > 0;)
{
- if((ret = write(fd, buf2, bufdata)) < 0)
+ if((ret = fwrite(buf2, 1, bufdata, out)) < 0)
{
flog(LOG_WARNING, "could not write file list: %s", strerror(errno));
break;
bufdata -= ret;
buf2 += ret;
}
- close(fd);
+ fclose(out);
}
free(buf);
}
quota--;
}
if(hub->queue.size < 1000)
- hub->sk->ignread = 0;
+ sockblock(hub->sk, 0);
if(quota < 1)
break;
}
quota--;
}
if((peer->queue.size < 50) && (peer->inbufdata < 500000))
- peer->sk->ignread = 0;
+ sockblock(peer->sk, 0);
if(quota < 1)
break;
}
static int updatetcpport(struct configvar *var, void *uudata)
{
struct sockaddr_in addr;
- struct socket *newsock;
+ struct lport *newsock;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
if((newsock = 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");
if(tcpsock != NULL)
- putsock(tcpsock);
+ closelport(tcpsock);
tcpsock = newsock;
return(0);
}
if(udpsock != NULL)
putsock(udpsock);
if(tcpsock != NULL)
- putsock(tcpsock);
+ closelport(tcpsock);
addr.sin_family = AF_INET;
memset(&addr.sin_addr, 0, sizeof(addr.sin_addr));
addr.sin_port = htons(confgetint("dc", "udpport"));