#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;
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;
/* 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())
{
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;