* | 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 "message.h"
#include "wildcard.h"
#include "xline.h"
+#include "cull_list.h"
extern InspIRCd* ServerInstance;
extern int WHOWAS_STALE;
extern std::vector<ircd_module*> factory;
extern std::vector<InspSocket*> module_sockets;
extern int MODCOUNT;
-extern InspSocket* socket_ref[65535];
+extern InspSocket* socket_ref[MAX_DESCRIPTORS];
extern time_t TIME;
-extern SocketEngine* SE;
-extern userrec* fd_ref_table[65536];
-extern serverstats* stats;
+extern userrec* fd_ref_table[MAX_DESCRIPTORS];
extern ServerConfig *Config;
extern user_hash clientlist;
extern whowas_hash whowas;
-extern Module* IOHookModule;
-std::vector<userrec*> local_users;
+extern std::vector<userrec*> local_users;
std::vector<userrec*> all_opers;
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();
{
}
+void userrec::MakeHost(char* nhost)
+{
+ /* This is much faster than snprintf */
+ char* t = nhost;
+ for(char* n = ident; n; n++)
+ *t++ = *n;
+ *t++ = '@';
+ for(char* n = host; n; n++)
+ *t++ = *n;
+ *t = 0;
+}
+
void userrec::CloseSocket()
{
shutdown(this->fd,2);
char* userrec::GetFullHost()
{
static char result[MAXBUF];
- snprintf(result,MAXBUF,"%s!%s@%s",nick,ident,dhost);
+ char* t = result;
+ for(char* n = nick; n; n++)
+ *t++ = *n;
+ *t++ = '!';
+ for(char* n = ident; n; n++)
+ *t++ = *n;
+ *t++ = '@';
+ for(char* n = dhost; n; n++)
+ *t++ = *n;
+ *t = 0;
return result;
}
char* userrec::GetFullRealHost()
{
static char fresult[MAXBUF];
- snprintf(fresult,MAXBUF,"%s!%s@%s",nick,ident,host);
+ char* t = fresult;
+ for(char* n = nick; n; n++)
+ *t++ = *n;
+ *t++ = '!';
+ for(char* n = ident; n; n++)
+ *t++ = *n;
+ *t++ = '@';
+ for(char* n = host; n; n++)
+ *t++ = *n;
+ *t = 0;
return fresult;
}
// send AS MUCH OF THE USERS SENDQ as we are able to (might not be all of it)
void userrec::FlushWriteBuf()
{
- if (sendq.length())
+ if ((sendq.length()) && (this->fd != FD_MAGIC_NUMBER))
{
char* tb = (char*)this->sendq.c_str();
int n_sent = write(this->fd,tb,this->sendq.length());
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)
{
- if (IOHookModule)
+ if (Config->GetIOHook(user->port))
{
- IOHookModule->OnRawSocketClose(user->fd);
+ Config->GetIOHook(user->port)->OnRawSocketClose(user->fd);
}
- SE->DelFd(user->fd);
+ ServerInstance->SE->DelFd(user->fd);
user->CloseSocket();
}
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)
{
- if (IOHookModule)
+ if (Config->GetIOHook(user->port))
{
- IOHookModule->OnRawSocketClose(user->fd);
+ Config->GetIOHook(user->port)->OnRawSocketClose(user->fd);
}
- SE->DelFd(user->fd);
+ ServerInstance->SE->DelFd(user->fd);
user->CloseSocket();
}
strlcpy(a->dhost,u->dhost,160);
strlcpy(a->host,u->host,160);
strlcpy(a->fullname,u->fullname,MAXGECOS);
- strlcpy(a->server,u->server,256);
+ if (u->server)
+ strlcpy(a->server,u->server,256);
a->signon = u->signon;
/* MAX_WHOWAS: max number of /WHOWAS items
*/
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;
for (int i = 0; i < MAXCHANS; i++)
clientlist[tempnick]->chans.push_back(a);
- if (clientlist.size() > Config->SoftLimit)
+ if (local_users.size() > Config->SoftLimit)
{
kill_link(clientlist[tempnick],"No more connections allowed");
return;
}
- if (clientlist.size() >= MAXCLIENTS)
+ if (local_users.size() >= MAXCLIENTS)
{
kill_link(clientlist[tempnick],"No more connections allowed");
return;
// irc server at once (or the irc server otherwise initiating this many connections, files etc)
// which for the time being is a physical impossibility (even the largest networks dont have more
// than about 10,000 users on ONE server!)
- if ((unsigned)socket > 65534)
+ if ((unsigned)socket > MAX_DESCRIPTORS)
{
kill_link(clientlist[tempnick],"Server is full");
return;
}
fd_ref_table[socket] = clientlist[tempnick];
local_users.push_back(clientlist[tempnick]);
- SE->AddFd(socket,true,X_ESTAB_CLIENT);
+ ServerInstance->SE->AddFd(socket,true,X_ESTAB_CLIENT);
+
+ WriteServ(clientlist[tempnick]->fd,"NOTICE Auth :*** Looking up your hostname...");
}
-void FullConnectUser(userrec* user)
+void FullConnectUser(userrec* user, CullList* Goners)
{
- stats->statsConnects++;
+ ServerInstance->stats->statsConnects++;
user->idle_lastmsg = TIME;
log(DEBUG,"ConnectUser: %s",user->nick);
- if ((strcmp(Passwd(user),"")) && (!user->haspassed))
- {
- kill_link(user,"Invalid password");
- return;
- }
- if (IsDenied(user))
+ ConnectClass a = GetClass(user);
+
+ if (a.type == CC_DENY)
+ {
+ Goners->AddItem(user,"Unauthorised connection");
+ return;
+ }
+ if ((*(a.pass.c_str())) && (!user->haspassed))
{
- kill_link(user,"Unauthorised connection");
+ Goners->AddItem(user,"Invalid password");
return;
}
{
char reason[MAXBUF];
snprintf(reason,MAXBUF,"G-Lined: %s",r);
- kill_link_silent(user,reason);
+ Goners->AddItem(user,reason);
return;
}
r = matches_kline(user->host);
{
char reason[MAXBUF];
snprintf(reason,MAXBUF,"K-Lined: %s",r);
- kill_link_silent(user,reason);
+ Goners->AddItem(user,reason);
return;
}
}
WriteServ(user->fd,"001 %s :Welcome to the %s IRC Network %s!%s@%s",user->nick,Config->Network,user->nick,user->ident,user->host);
WriteServ(user->fd,"002 %s :Your host is %s, running version %s",user->nick,Config->ServerName,VERSION);
WriteServ(user->fd,"003 %s :This server was created %s %s",user->nick,__TIME__,__DATE__);
- WriteServ(user->fd,"004 %s %s %s iowghraAsORVSxNCWqBzvdHtGI lvhopsmntikrRcaqOALQbSeKVfHGCuzN",user->nick,Config->ServerName,VERSION);
- // the neatest way to construct the initial 005 numeric, considering the number of configure constants to go in it...
- std::stringstream v;
- v << "WALLCHOPS MODES=13 CHANTYPES=# PREFIX=(ohv)@%+ MAP SAFELIST MAXCHANNELS=" << MAXCHANS;
- v << " MAXBANS=60 NICKLEN=" << NICKMAX;
- 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);
+ WriteServ(user->fd,"004 %s %s %s iowghrasxRVSCWBG lvhopsmntikrcaqbegIOLQRSKVHGCNT vhobeIaqglk",user->nick,Config->ServerName,VERSION);
// 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);
+ std::stringstream out(Config->data005);
std::string token = "";
std::string line5 = "";
int token_counter = 0;
// 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);
}
-
-/* shows the message of the day, and any other on-logon stuff */
-void ConnectUser(userrec *user)
-{
- // dns is already done, things are fast. no need to wait for dns to complete just pass them straight on
- if ((user->dns_done) && (user->registered >= 3) && (AllModulesReportReady(user)))
- {
- FullConnectUser(user);
- }
-}
-
/* re-allocates a nick in the user_hash after they change nicknames,
* returns a pointer to the new user as it may have moved */
char nick[MAXBUF];
int MOD_RESULT = 0;
- strcpy(nick,"");
+ *nick = 0;
- FOREACH_RESULT(OnUserPreNick(user,newnick));
+ FOREACH_RESULT(I_OnUserPreNick,OnUserPreNick(user,newnick));
if (MOD_RESULT) {
- stats->statsCollisions++;
+ ServerInstance->stats->statsCollisions++;
kill_link(user,"Nickname collision");
return;
}
if (matches_qline(newnick))
{
- stats->statsCollisions++;
+ ServerInstance->stats->statsCollisions++;
kill_link(user,"Nickname collision");
return;
}
{
char* pars[1];
pars[0] = nick;
- handle_nick(pars,1,user);
+ std::string cmd = "NICK";
+ ServerInstance->Parser->CallHandler(cmd,pars,1,user);
}
}
}