#include <sys/errno.h>
#include <sys/ioctl.h>
#include <sys/utsname.h>
+#ifdef USE_KQUEUE
+#include <sys/types.h>
+#include <sys/event.h>
+#include <sys/time.h>
+#endif
#include <cstdio>
#include <time.h>
#include <string>
using namespace std;
+#ifdef USE_KQUEUE
+extern int kq;
+#endif
+
extern int MODCOUNT;
extern std::vector<Module*> modules;
extern std::vector<ircd_module*> factory;
extern char MyExecutable[1024];
extern int boundPortCount;
extern int portCount;
-extern int UDPportCount;
+extern int SERVERportCount;
extern int ports[MAXSOCKS];
extern int defaultRoute;
typedef nspace::hash_map<std::string, userrec*, nspace::hash<string>, StrHashComp> user_hash;
typedef nspace::hash_map<std::string, chanrec*, nspace::hash<string>, StrHashComp> chan_hash;
typedef nspace::hash_map<in_addr,string*, nspace::hash<in_addr>, InAddr_HashComp> address_cache;
+typedef nspace::hash_map<std::string, WhoWasUser*, nspace::hash<string>, StrHashComp> whowas_hash;
typedef std::deque<command_t> command_table;
extern user_hash clientlist;
extern chan_hash chanlist;
-extern user_hash whowas;
+extern whowas_hash whowas;
extern command_table cmdlist;
extern file_cache MOTD;
extern file_cache RULES;
}
else
{
- if (c->inviteonly)
+ if (c->binarymodes & CM_INVITEONLY)
{
WriteServ(user->fd,"401 %s %s :No such nick/channel",user->nick, parameters[0]);
}
return;
}
- if (c->inviteonly)
+ if (c->binarymodes & CM_INVITEONLY)
{
if (cstatus(user,c) < STATUS_HOP)
{
Ptr = FindChan(parameters[0]);
if (Ptr)
{
- if (((Ptr) && (!has_channel(user,Ptr))) && (Ptr->secret))
+ if (((Ptr) && (!has_channel(user,Ptr))) && (Ptr->binarymodes & CM_SECRET))
{
WriteServ(user->fd,"442 %s %s :You're not on that channel!",user->nick, Ptr->name);
return;
WriteServ(user->fd,"442 %s %s :You're not on that channel!",user->nick, Ptr->name);
return;
}
- if ((Ptr->topiclock) && (cstatus(user,Ptr)<STATUS_HOP))
+ if ((Ptr->binarymodes & CM_TOPICLOCK) && (cstatus(user,Ptr)<STATUS_HOP))
{
WriteServ(user->fd,"482 %s %s :You must be at least a half-operator to change modes on this channel", user->nick, Ptr->name);
return;
c = FindChan(parameters[0]);
if (c)
{
- if (((c) && (!has_channel(user,c))) && (c->secret))
+ if (((c) && (!has_channel(user,c))) && (c->binarymodes & CM_SECRET))
{
WriteServ(user->fd,"442 %s %s :You're not on that channel!",user->nick, c->name);
return;
chan = FindChan(parameters[0]);
if (chan)
{
- if ((chan->noexternal) && (!has_channel(user,chan)))
+ if ((chan->binarymodes & CM_NOEXTERNAL) && (!has_channel(user,chan)))
{
WriteServ(user->fd,"404 %s %s :Cannot send to channel (no external messages)", user->nick, chan->name);
return;
}
- if ((chan->moderated) && (cstatus(user,chan)<STATUS_VOICE))
+ if ((chan->binarymodes & CM_MODERATED) && (cstatus(user,chan)<STATUS_VOICE))
{
WriteServ(user->fd,"404 %s %s :Cannot send to channel (+m)", user->nick, chan->name);
return;
chan = FindChan(parameters[0]);
if (chan)
{
- if ((chan->noexternal) && (!has_channel(user,chan)))
+ if ((chan->binarymodes & CM_NOEXTERNAL) && (!has_channel(user,chan)))
{
WriteServ(user->fd,"404 %s %s :Cannot send to channel (no external messages)", user->nick, chan->name);
return;
}
- if ((chan->moderated) && (cstatus(user,chan)<STATUS_VOICE))
+ if ((chan->binarymodes & CM_MODERATED) && (cstatus(user,chan)<STATUS_VOICE))
{
WriteServ(user->fd,"404 %s %s :Cannot send to channel (+m)", user->nick, chan->name);
return;
WriteServ(user->fd,"311 %s %s %s %s * :%s",user->nick, dest->nick, dest->ident, dest->dhost, dest->fullname);
if ((user == dest) || (strchr(user->modes,'o')))
{
- WriteServ(user->fd,"378 %s %s :is connecting from *@%s",user->nick, dest->nick, dest->host);
+ WriteServ(user->fd,"378 %s %s :is connecting from *@%s %s",user->nick, dest->nick, dest->host, dest->ip);
}
char* cl = chlist(dest,user);
if (strcmp(cl,""))
/* push the socket on a stack of sockets due to be closed at the next opportunity */
if (user->fd > -1)
{
- shutdown(user->fd,2);
- close(user->fd);
+#ifdef USE_KQUEUE
+ struct kevent ke;
+ EV_SET(&ke, user->fd, EVFILT_READ, EV_DELETE, 0, 0, NULL);
+ int i = kevent(kq, &ke, 1, 0, 0, NULL);
+ if (i == -1)
+ {
+ log(DEBUG,"kqueue: Failed to remove user from queue!");
+ }
+#endif
+ shutdown(user->fd,2);
+ close(user->fd);
}
if (iter != clientlist.end())
for (chan_hash::const_iterator i = chanlist.begin(); i != chanlist.end(); i++)
{
// if the channel is not private/secret, OR the user is on the channel anyway
- if (((!i->second->c_private) && (!i->second->secret)) || (has_channel(user,i->second)))
+ if (((!(i->second->binarymodes & CM_PRIVATE)) && (!(i->second->binarymodes & CM_SECRET))) || (has_channel(user,i->second)))
{
WriteServ(user->fd,"322 %s %s %d :[+%s] %s",user->nick,i->second->name,usercount_i(i->second),chanmodes(i->second),i->second->topic);
}
void handle_whowas(char **parameters, int pcnt, userrec* user)
{
- user_hash::iterator i = whowas.find(parameters[0]);
+ whowas_hash::iterator i = whowas.find(parameters[0]);
if (i == whowas.end())
{
bool is_uline(const char* server)
{
+ if (!server)
+ return false;
+ if (!(*server))
+ return true;
char ServName[MAXBUF];
for (int i = 0; i < ConfValueEnum("uline",&config_f); i++)
{
if ((user) && (u))
{
- WriteTo(user, u, "KILL %s :%s!%s!%s!%s (%s)", u->nick, source->name, ServerName, user->dhost,user->nick,reason);
- WriteOpers("*** Remote kill from %s by %s: %s!%s@%s (%s)",source->name,user->nick,u->nick,u->ident,u->host,reason);
- snprintf(kreason,MAXBUF,"[%s] Killed (From: '%s' (%s))",source->name,user->nick,reason);
+ WriteTo(user, u, "KILL %s :%s!%s!%s!%s (%s)", u->nick, tcp_host, ServerName, user->dhost,user->nick,reason);
+ WriteOpers("*** Remote kill from %s by %s: %s!%s@%s (%s)",tcp_host,user->nick,u->nick,u->ident,u->host,reason);
+ snprintf(kreason,MAXBUF,"[%s] Killed (From: '%s' (%s))",tcp_host,user->nick,reason);
kill_link(u,kreason);
}
}
strlcpy(clientlist[nick]->server, server,256);
strlcpy(clientlist[nick]->ident, ident,10); // +1 char to compensate for tilde
strlcpy(clientlist[nick]->fullname, gecos,128);
- strlcpy(clientlist[nick]->ip,ipaddr,32);
+ strlcpy(clientlist[nick]->ip,ipaddr,16);
clientlist[nick]->signon = TS;
clientlist[nick]->nping = 0; // this is ignored for a remote user anyway.
clientlist[nick]->lastping = 1;
}
-void handle_link_packet(char* udp_msg, char* tcp_host, serverrec *serv)
+void handle_link_packet(char* tcp_msg, char* tcp_host, serverrec *serv)
{
- if ((!strncmp(udp_msg,"USER ",5)) || (!strncmp(udp_msg,"NICK ",5)) || (!strncmp(udp_msg,"PASS ",5)) || (!strncmp(udp_msg,"SERVER ",7)))
+ if ((!strncmp(tcp_msg,"USER ",5)) || (!strncmp(tcp_msg,"NICK ",5)) || (!strncmp(tcp_msg,"PASS ",5)) || (!strncmp(tcp_msg,"SERVER ",7)))
{
// a user on a server port, just close their connection.
RemoveServer(tcp_host);
}
char response[10240];
- char token = udp_msg[0];
- char* old = udp_msg;
+ char token = tcp_msg[0];
+ char* old = tcp_msg;
+
+ if (!strncmp(tcp_msg,"PING",4))
+ {
+ // some muppet of a server is sending PING. We don't know what PING is. drop it silently.
+ return;
+ }
- if ((token != ':') && (strlen(udp_msg)>1) && (udp_msg[1] != ' '))
+ if ((token != ':') && (strlen(tcp_msg)>1) && (tcp_msg[1] != ' '))
{
- WriteOpers("*** Discarded %d chars illegal data from %s",strlen(udp_msg),tcp_host);
+ WriteOpers("*** Discarded %d chars illegal data from %s",strlen(tcp_msg),tcp_host);
}
if (token == ':') // leading :servername or details - strip them off (services does this, sucky)
{
- char* src = udp_msg+1;
- while (udp_msg[0] != ' ')
- udp_msg++;
- udp_msg[0] = 0;
- udp_msg++;
- char* comd = udp_msg;
- while (udp_msg[0] != ' ')
- udp_msg++;
- udp_msg[0] = 0;
- udp_msg++;
+ char* src = tcp_msg+1;
+ while (tcp_msg[0] != ' ')
+ tcp_msg++;
+ tcp_msg[0] = 0;
+ tcp_msg++;
+ char* comd = tcp_msg;
+ while (tcp_msg[0] != ' ')
+ tcp_msg++;
+ tcp_msg[0] = 0;
+ tcp_msg++;
char data[MAXBUF];
char source[MAXBUF];
char command[MAXBUF];
- strlcpy(data,udp_msg,512);
+ strlcpy(data,tcp_msg,512);
strlcpy(source,src,MAXBUF);
strlcpy(command,comd,MAXBUF);
- udp_msg = old;
+ tcp_msg = old;
// unused numeric:
// :services-dev.chatspike.net 433 Craig Craig :Nickname is registered to someone else
}
if (!strcmp(command,"NOTICE"))
{
- snprintf(udp_msg,MAXBUF,"V %s %s",source,data);
- log(DEBUG,"Rewrote NOTICE from services to: '%s'",udp_msg);
- token = udp_msg[0];
+ snprintf(tcp_msg,MAXBUF,"V %s %s",source,data);
+ log(DEBUG,"Rewrote NOTICE from services to: '%s'",tcp_msg);
+ token = tcp_msg[0];
}
if (!strcmp(command,"QUIT"))
{
- if ((!udp_msg) || (!strcmp(data,"")) || (strcmp(data,":")))
+ if ((!tcp_msg) || (!strcmp(data,"")) || (strcmp(data,":")))
{
strcpy(data,":No reason");
}
{
strcpy(data,":No reason");
}
- snprintf(udp_msg,MAXBUF,"Q %s %s",source,data);
- log(DEBUG,"Rewrote QUIT from services to: '%s'",udp_msg);
- token = udp_msg[0];
+ snprintf(tcp_msg,MAXBUF,"Q %s %s",source,data);
+ log(DEBUG,"Rewrote QUIT from services to: '%s'",tcp_msg);
+ token = tcp_msg[0];
}
if (!strcmp(command,"SQUIT"))
{
- snprintf(udp_msg,MAXBUF,"& %s",source);
- log(DEBUG,"Rewrote SQUIT from services to: '%s'",udp_msg);
- token = udp_msg[0];
+ snprintf(tcp_msg,MAXBUF,"& %s",source);
+ log(DEBUG,"Rewrote SQUIT from services to: '%s'",tcp_msg);
+ token = tcp_msg[0];
}
if (!strcmp(command,"SVSMODE"))
{
- snprintf(udp_msg,MAXBUF,"m %s %s",source,data);
- log(DEBUG,"Rewrote SVSMODE from services to: '%s'",udp_msg);
- token = udp_msg[0];
+ snprintf(tcp_msg,MAXBUF,"m %s %s",source,data);
+ log(DEBUG,"Rewrote SVSMODE from services to: '%s'",tcp_msg);
+ token = tcp_msg[0];
}
if (!strcmp(command,"SVS2MODE"))
{
- snprintf(udp_msg,MAXBUF,"m %s %s",source,data);
- log(DEBUG,"Rewrote SVS2MODE from services to: '%s'",udp_msg);
- token = udp_msg[0];
+ snprintf(tcp_msg,MAXBUF,"m %s %s",source,data);
+ log(DEBUG,"Rewrote SVS2MODE from services to: '%s'",tcp_msg);
+ token = tcp_msg[0];
}
// todo: this wont work without u:lines
// in give_ops etc allow nick on a u:lined serv to do just about anything
if (!strcmp(command,"MODE"))
{
- snprintf(udp_msg,MAXBUF,"m %s %s",source,data);
- log(DEBUG,"Rewrote MODE from services to: '%s'",udp_msg);
- token = udp_msg[0];
+ snprintf(tcp_msg,MAXBUF,"m %s %s",source,data);
+ log(DEBUG,"Rewrote MODE from services to: '%s'",tcp_msg);
+ token = tcp_msg[0];
}
if (!strcmp(command,"KICK"))
{
- snprintf(udp_msg,MAXBUF,"k %s %s",source,data);
- log(DEBUG,"Rewrote KICK from services to: '%s'",udp_msg);
- token = udp_msg[0];
+ snprintf(tcp_msg,MAXBUF,"k %s %s",source,data);
+ log(DEBUG,"Rewrote KICK from services to: '%s'",tcp_msg);
+ token = tcp_msg[0];
}
if (!strcmp(command,"KILL"))
{
- snprintf(udp_msg,MAXBUF,"K %s %s",source,data);
- log(DEBUG,"Rewrote KILL from services to: '%s'",udp_msg);
- token = udp_msg[0];
+ snprintf(tcp_msg,MAXBUF,"K %s %s",source,data);
+ log(DEBUG,"Rewrote KILL from services to: '%s'",tcp_msg);
+ token = tcp_msg[0];
}
if (!strcmp(command,"SVSJOIN"))
{
- snprintf(udp_msg,MAXBUF,"J %s",data);
- NetSendToOne(tcp_host,udp_msg);
+ snprintf(tcp_msg,MAXBUF,"J %s",data);
+ NetSendToOne(tcp_host,tcp_msg);
char* nick = strtok(data," ");
char* chan = strtok(NULL," ");
- log(DEBUG,"Rewrote SVSJOIN from services to: '%s'",udp_msg);
+ log(DEBUG,"Rewrote SVSJOIN from services to: '%s'",tcp_msg);
userrec* u = Find(nick);
if (u)
{
add_channel(u,chan,"",true);
}
- token = udp_msg[0];
+ token = tcp_msg[0];
}
}
- char* params = udp_msg + 2;
+ char* params = tcp_msg + 2;
char finalparam[1024];
strcpy(finalparam," :xxxx");
- if (strstr(udp_msg," :")) {
- strlcpy(finalparam,strstr(udp_msg," :"),1024);
+ if (strstr(tcp_msg," :")) {
+ strlcpy(finalparam,strstr(tcp_msg," :"),1024);
}