* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
- * Inspire is copyright (C) 2002-2004 ChatSpike-Dev.
+ * Inspire is copyright (C) 2002-2006 ChatSpike-Dev.
* E-mail:
* <brain@chatspike.net>
* <Craig@chatspike.net>
#include "inspstring.h"
#include "commands.h"
#include "helperfuncs.h"
-
-extern ServerConfig* Config;
+#include "typedefs.h"
+#include "socketengine.h"
+#include "hashcomp.h"
+#include "message.h"
+#include "wildcard.h"
+#include "xline.h"
+
+extern InspIRCd* ServerInstance;
+extern int WHOWAS_STALE;
+extern int WHOWAS_MAX;
+extern std::vector<Module*> modules;
+extern std::vector<ircd_module*> factory;
+extern std::vector<InspSocket*> module_sockets;
+extern int MODCOUNT;
+extern InspSocket* socket_ref[65535];
extern time_t TIME;
+extern userrec* fd_ref_table[65536];
+extern ServerConfig *Config;
+extern user_hash clientlist;
+extern whowas_hash whowas;
+extern std::vector<userrec*> local_users;
+
std::vector<userrec*> all_opers;
+template<typename T> inline string ConvToStr(const T &in)
+{
+ stringstream tmp;
+ if (!(tmp << in)) return string();
+ return tmp.str();
+}
+
userrec::userrec()
{
// the PROPER way to do it, AVOID bzero at *ALL* costs
- strcpy(nick,"");
- strcpy(ip,"127.0.0.1");
- timeout = 0;
- strcpy(ident,"");
- strcpy(host,"");
- strcpy(dhost,"");
- strcpy(fullname,"");
- strcpy(modes,"");
+ *nick = *ident = *host = *dhost = *fullname = *modes = *awaymsg = *oper = *ip = 0;
server = (char*)FindServerNamePtr(Config->ServerName);
- strcpy(awaymsg,"");
- strcpy(oper,"");
reset_due = TIME;
- lines_in = 0;
- fd = lastping = signon = idle_lastmsg = nping = registered = 0;
- flood = port = bytes_in = bytes_out = cmds_in = cmds_out = 0;
- haspassed = false;
- dns_done = false;
+ lines_in = fd = lastping = signon = idle_lastmsg = nping = registered = 0;
+ timeout = flood = port = bytes_in = bytes_out = cmds_in = cmds_out = 0;
+ haspassed = dns_done = false;
recvq = "";
sendq = "";
chans.clear();
{
for (InvitedList::iterator i = invites.begin(); i != invites.end(); i++)
{
- if (i->channel)
+ irc::string compare = i->channel;
+ if (compare == channel)
{
- irc::string compare = i->channel;
- if (compare == channel)
- {
- return true;
- }
+ return true;
}
}
return false;
invites.push_back(i);
}
-void userrec::RemoveInvite(std::string &channel)
+void userrec::RemoveInvite(irc::string &channel)
{
log(DEBUG,"Removing invites");
if (invites.size())
{
for (InvitedList::iterator i = invites.begin(); i != invites.end(); i++)
{
- if (i->channel)
+ irc::string compare = i->channel;
+ if (compare == channel)
{
- irc::string compare = i->channel;
- if (compare == channel)
- {
- invites.erase(i);
- return;
- }
- }
+ invites.erase(i);
+ return;
+ }
}
}
}
return;
if (sendq.length() + data.length() > (unsigned)this->sendqmax)
{
- WriteOpers("*** User %s SendQ of %d exceeds connect class maximum of %d",this->nick,sendq.length() + data.length(),this->sendqmax);
+ /* Fix by brain - Set the error text BEFORE calling writeopers, because
+ * if we dont it'll recursively call here over and over again trying
+ * to repeatedly add the text to the sendq!
+ */
this->SetWriteError("SendQ exceeded");
+ WriteOpers("*** User %s SendQ of %d exceeds connect class maximum of %d",this->nick,sendq.length() + data.length(),this->sendqmax);
return;
}
std::stringstream stream;
log(DEBUG,"closing fd %lu",(unsigned long)user->fd);
if (user->registered == 7) {
- FOREACH_MOD OnUserQuit(user,reason);
+ FOREACH_MOD(I_OnUserQuit,OnUserQuit(user,reason));
WriteCommonExcept(user,"QUIT :%s",reason);
}
user->FlushWriteBuf();
- FOREACH_MOD OnUserDisconnect(user);
+ FOREACH_MOD(I_OnUserDisconnect,OnUserDisconnect(user));
if (user->fd > -1)
{
- FOREACH_MOD OnRawSocketClose(user->fd);
- SE->DelFd(user->fd);
+ if (Config->GetIOHook(user->port))
+ {
+ Config->GetIOHook(user->port)->OnRawSocketClose(user->fd);
+ }
+ ServerInstance->SE->DelFd(user->fd);
user->CloseSocket();
}
{
log(DEBUG,"deleting user hash value %lu",(unsigned long)user);
if (user->fd > -1)
+ {
fd_ref_table[user->fd] = NULL;
+ if (find(local_users.begin(),local_users.end(),user) != local_users.end())
+ {
+ local_users.erase(find(local_users.begin(),local_users.end(),user));
+ log(DEBUG,"Delete local user");
+ }
+ }
clientlist.erase(iter);
}
delete user;
user->FlushWriteBuf();
if (user->registered == 7) {
- FOREACH_MOD OnUserQuit(user,reason);
+ FOREACH_MOD(I_OnUserQuit,OnUserQuit(user,reason));
WriteCommonExcept(user,"QUIT :%s",reason);
}
- FOREACH_MOD OnUserDisconnect(user);
+ FOREACH_MOD(I_OnUserDisconnect,OnUserDisconnect(user));
if (user->fd > -1)
{
- FOREACH_MOD OnRawSocketClose(user->fd);
- SE->DelFd(user->fd);
+ if (Config->GetIOHook(user->port))
+ {
+ Config->GetIOHook(user->port)->OnRawSocketClose(user->fd);
+ }
+ ServerInstance->SE->DelFd(user->fd);
user->CloseSocket();
}
{
log(DEBUG,"deleting user hash value %lu",(unsigned long)user);
if (user->fd > -1)
+ {
fd_ref_table[user->fd] = NULL;
+ if (find(local_users.begin(),local_users.end(),user) != local_users.end())
+ {
+ log(DEBUG,"Delete local user");
+ local_users.erase(find(local_users.begin(),local_users.end(),user));
+ }
+ }
clientlist.erase(iter);
}
delete user;
*/
clientlist[tempnick] = new userrec();
- NonBlocking(socket);
log(DEBUG,"AddClient: %lu %s %d %s",(unsigned long)socket,host,port,ip);
clientlist[tempnick]->fd = socket;
for (ClassVector::iterator i = Config->Classes.begin(); i != Config->Classes.end(); i++)
{
- if (match(clientlist[tempnick]->host,i->host) && (i->type == CC_ALLOW))
+ if (match(clientlist[tempnick]->host,i->host.c_str()) && (i->type == CC_ALLOW))
{
class_regtimeout = (unsigned long)i->registration_timeout;
class_flood = i->flood;
}
}
fd_ref_table[socket] = clientlist[tempnick];
- SE->AddFd(socket,true,X_ESTAB_CLIENT);
+ local_users.push_back(clientlist[tempnick]);
+ ServerInstance->SE->AddFd(socket,true,X_ESTAB_CLIENT);
}
void FullConnectUser(userrec* user)
{
- stats->statsConnects++;
+ ServerInstance->stats->statsConnects++;
user->idle_lastmsg = TIME;
log(DEBUG,"ConnectUser: %s",user->nick);
v << " TOPICLEN=" << MAXTOPIC << " KICKLEN=" << MAXKICK << " MAXTARGETS=20 AWAYLEN=" << MAXAWAY << " CHANMODES=ohvb,k,l,psmnti NETWORK=";
v << Config->Network;
std::string data005 = v.str();
- FOREACH_MOD On005Numeric(data005);
+ FOREACH_MOD(I_On005Numeric,On005Numeric(data005));
// anfl @ #ratbox, efnet reminded me that according to the RFC this cant contain more than 13 tokens per line...
// so i'd better split it :)
std::stringstream out(data005);
// fix 3 by brain, move registered = 7 below these so that spurious modes and host changes dont go out
// onto the network and produce 'fake direction'
- FOREACH_MOD OnUserConnect(user);
- FOREACH_MOD OnGlobalConnect(user);
+ FOREACH_MOD(I_OnUserConnect,OnUserConnect(user));
+ FOREACH_MOD(I_OnGlobalConnect,OnGlobalConnect(user));
user->registered = 7;
WriteOpers("*** Client connecting on port %lu: %s!%s@%s [%s]",(unsigned long)user->port,user->nick,user->ident,user->host,user->ip);
}
}
}
+/* re-allocates a nick in the user_hash after they change nicknames,
+ * returns a pointer to the new user as it may have moved */
+
+userrec* ReHashNick(char* Old, char* New)
+{
+ //user_hash::iterator newnick;
+ user_hash::iterator oldnick = clientlist.find(Old);
+
+ log(DEBUG,"ReHashNick: %s %s",Old,New);
+
+ if (!strcasecmp(Old,New))
+ {
+ log(DEBUG,"old nick is new nick, skipping");
+ return oldnick->second;
+ }
+
+ if (oldnick == clientlist.end()) return NULL; /* doesnt exist */
+
+ log(DEBUG,"ReHashNick: Found hashed nick %s",Old);
+
+ userrec* olduser = oldnick->second;
+ clientlist[New] = olduser;
+ clientlist.erase(oldnick);
+
+ log(DEBUG,"ReHashNick: Nick rehashed as %s",New);
+
+ return clientlist[New];
+}
+
+void force_nickchange(userrec* user,const char* newnick)
+{
+ char nick[MAXBUF];
+ int MOD_RESULT = 0;
+
+ *nick = 0;
+
+ FOREACH_RESULT(I_OnUserPreNick,OnUserPreNick(user,newnick));
+ if (MOD_RESULT) {
+ ServerInstance->stats->statsCollisions++;
+ kill_link(user,"Nickname collision");
+ return;
+ }
+ if (matches_qline(newnick))
+ {
+ ServerInstance->stats->statsCollisions++;
+ kill_link(user,"Nickname collision");
+ return;
+ }
+
+ if (user)
+ {
+ if (newnick)
+ {
+ strncpy(nick,newnick,MAXBUF);
+ }
+ if (user->registered == 7)
+ {
+ char* pars[1];
+ pars[0] = nick;
+ std::string cmd = "NICK";
+ ServerInstance->Parser->CallHandler(cmd,pars,1,user);
+ }
+ }
+}
+