/* Now with added unF! ;) */
+using namespace std;
+
#include "inspircd.h"
#include "inspircd_io.h"
#include "inspircd_util.h"
#include "dynamic.h"
#include "wildcard.h"
-using namespace std;
-
#ifdef GCC3
#define nspace __gnu_cxx
#else
bool IsDenied(userrec *user);
void AddWhoWas(userrec* u);
+std::stringstream config_f(stringstream::in | stringstream::out);
void safedelete(userrec *p)
{
char dbg[MAXBUF],pauseval[MAXBUF],Value[MAXBUF],timeout[MAXBUF];
ConnectClass c;
- ConfValue("server","name",0,ServerName);
- ConfValue("server","description",0,ServerDesc);
- ConfValue("server","network",0,Network);
- ConfValue("admin","name",0,AdminName);
- ConfValue("admin","email",0,AdminEmail);
- ConfValue("admin","nick",0,AdminNick);
- ConfValue("files","motd",0,motd);
- ConfValue("files","rules",0,rules);
- ConfValue("power","diepass",0,diepass);
- ConfValue("power","pause",0,pauseval);
- ConfValue("power","restartpass",0,restartpass);
- ConfValue("options","prefixquit",0,PrefixQuit);
- ConfValue("die","value",0,DieValue);
- ConfValue("options","loglevel",0,dbg);
+ LoadConf(CONFIG_FILE,&config_f);
+
+ ConfValue("server","name",0,ServerName,&config_f);
+ ConfValue("server","description",0,ServerDesc,&config_f);
+ ConfValue("server","network",0,Network,&config_f);
+ ConfValue("admin","name",0,AdminName,&config_f);
+ ConfValue("admin","email",0,AdminEmail,&config_f);
+ ConfValue("admin","nick",0,AdminNick,&config_f);
+ ConfValue("files","motd",0,motd,&config_f);
+ ConfValue("files","rules",0,rules,&config_f);
+ ConfValue("power","diepass",0,diepass,&config_f);
+ ConfValue("power","pause",0,pauseval,&config_f);
+ ConfValue("power","restartpass",0,restartpass,&config_f);
+ ConfValue("options","prefixquit",0,PrefixQuit,&config_f);
+ ConfValue("die","value",0,DieValue,&config_f);
+ ConfValue("options","loglevel",0,dbg,&config_f);
if (!strcmp(dbg,"debug"))
LogLevel = DEBUG;
if (!strcmp(dbg,"verbose"))
readfile(RULES,rules);
log(DEBUG,"Reading connect classes");
Classes.clear();
- for (int i = 0; i < ConfValueEnum("connect"); i++)
+ for (int i = 0; i < ConfValueEnum("connect",&config_f); i++)
{
strcpy(Value,"");
- ConfValue("connect","allow",i,Value);
- ConfValue("connect","timeout",i,timeout);
+ ConfValue("connect","allow",i,Value,&config_f);
+ ConfValue("connect","timeout",i,timeout,&config_f);
if (strcmp(Value,""))
{
strcpy(c.host,Value);
c.type = CC_ALLOW;
strcpy(Value,"");
- ConfValue("connect","password",i,Value);
+ ConfValue("connect","password",i,Value,&config_f);
strcpy(c.pass,Value);
c.registration_timeout = 90; // default is 2 minutes
if (atoi(timeout)>0)
}
else
{
- ConfValue("connect","deny",i,Value);
+ ConfValue("connect","deny",i,Value,&config_f);
strcpy(c.host,Value);
c.type = CC_DENY;
Classes.push_back(c);
/* add a channel to a user, creating the record for it if needed and linking
* it to the user record */
-chanrec* add_channel(userrec *user, char* cname, char* key)
+chanrec* add_channel(userrec *user, const char* cn, const char* key)
{
-
- if ((!user) || (!cname))
+ if ((!user) || (!cn))
{
log(DEFAULT,"*** BUG *** add_channel was given an invalid parameter");
return 0;
int i = 0;
chanrec* Ptr;
int created = 0;
+ char cname[MAXBUF];
+
+ strncpy(cname,cn,MAXBUF);
// we MUST declare this wherever we use FOREACH_RESULT
int MOD_RESULT = 0;
/* remove a channel from a users record, and remove the record from memory
* if the channel has become empty */
-chanrec* del_channel(userrec *user, char* cname, char* reason)
+chanrec* del_channel(userrec *user, const char* cname, const char* reason)
{
if ((!user) || (!cname))
{
}
-void kill_link(userrec *user,char* reason)
+void kill_link(userrec *user,const char* r)
{
user_hash::iterator iter = clientlist.find(user->nick);
+
+ char reason[MAXBUF];
+
+ strncpy(reason,r,MAXBUF);
if (strlen(reason)>MAXQUIT)
{
WriteCommonExcept(user,"QUIT :%s",reason);
}
- /* push the socket on a stack of sockets due to be closed at the next opportunity */
+ /* push the socket on a stack of sockets due to be closed at the next opportunity
+ * 'Client exited' is an exception to this as it means the client side has already
+ * closed the socket, we don't need to do it.
+ */
fd_reap.push_back(user->fd);
bool do_purge = false;
void handle_pass(char **parameters, int pcnt, userrec *user)
{
+ // Check to make sure they havnt registered -- Fix by FCS
+ if (user->registered == 7)
+ {
+ WriteServ(user->fd,"462 %s :You may not reregister",user->nick);
+ return;
+ }
if (!strcasecmp(parameters[0],Passwd(user)))
{
user->haspassed = true;
{
if (!c)
{
- WriteServ(user->fd,"401 %s %s :No suck nick/channel",user->nick, parameters[1]);
+ WriteServ(user->fd,"401 %s %s :No such nick/channel",user->nick, parameters[1]);
}
else
{
WriteServ(user->fd,"482 %s %s :You must be at least a half-operator to change modes on this channel",user->nick, c->name);
return;
}
-
- u->InviteTo(c->name);
- WriteFrom(u->fd,user,"INVITE %s :%s",u->nick,c->name);
- WriteServ(user->fd,"341 %s %s %s",user->nick,u->nick,c->name);
}
+ if (has_channel(u,c))
+ {
+ WriteServ(user->fd,"443 %s %s %s :Is already on channel %s",user->nick,u->nick,c->name,c->name);
+ return;
+ }
+ u->InviteTo(c->name);
+ WriteFrom(u->fd,user,"INVITE %s :%s",u->nick,c->name);
+ WriteServ(user->fd,"341 %s %s %s",user->nick,u->nick,c->name);
}
void handle_topic(char **parameters, int pcnt, userrec *user)
exit(status);
}
+
int main (int argc, char *argv[])
{
Start();
WriteServ(user->fd,"404 %s %s :Cannot send to channel (+m)", user->nick, chan->name);
return;
}
+
+ int MOD_RESULT = 0;
+
+ FOREACH_RESULT(OnUserPreMessage(user,chan,TYPE_CHANNEL,std::string(parameters[1])));
+ if (MOD_RESULT) {
+ return;
+ }
+
ChanExceptSender(chan, user, "PRIVMSG %s :%s", chan->name, parameters[1]);
}
else
/* auto respond with aweh msg */
WriteServ(user->fd,"301 %s %s :%s",user->nick,dest->nick,dest->awaymsg);
}
+
+ int MOD_RESULT = 0;
+
+ FOREACH_RESULT(OnUserPreMessage(user,dest,TYPE_USER,std::string(parameters[1])));
+ if (MOD_RESULT) {
+ return;
+ }
+
WriteTo(user, dest, "PRIVMSG %s :%s", dest->nick, parameters[1]);
}
else
WriteServ(user->fd,"404 %s %s :Cannot send to channel (+m)", user->nick, chan->name);
return;
}
+
+ int MOD_RESULT = 0;
+
+ FOREACH_RESULT(OnUserPreNotice(user,chan,TYPE_CHANNEL,std::string(parameters[1])));
+ if (MOD_RESULT) {
+ return;
+ }
+
WriteChannel(chan, user, "NOTICE %s :%s", chan->name, parameters[1]);
}
else
dest = Find(parameters[0]);
if (dest)
{
+ int MOD_RESULT = 0;
+
+ FOREACH_RESULT(OnUserPreNotice(user,dest,TYPE_USER,std::string(parameters[1])));
+ if (MOD_RESULT) {
+ return;
+ }
+
WriteTo(user, dest, "NOTICE %s :%s", dest->nick, parameters[1]);
}
else
if ((!strcmp(parameters[0],"0")) || (!strcmp(parameters[0],"*")) && (!strcmp(parameters[1],"o")))
{
Ptr = user->chans[0].channel;
- printf(user->chans[0].channel->name);
for (user_hash::const_iterator i = clientlist.begin(); i != clientlist.end(); i++)
{
if ((common_channels(user,i->second)) && (isnick(i->second->nick)))
for (int i = 0; i < module_names.size(); i++)
{
Version V = modules[i]->GetVersion();
- WriteServ(user->fd,"900 0x%08lx %d.%d.%d.%d :%s",modules[i],V.Major,V.Minor,V.Revision,V.Build,module_names[i].c_str());
+ WriteServ(user->fd,"900 %s :0x%08lx %d.%d.%d.%d %s",user->nick,modules[i],V.Major,V.Minor,V.Revision,V.Build,module_names[i].c_str());
}
}
/* stats o */
if (!strcasecmp(parameters[0],"o"))
{
- for (int i = 0; i < ConfValueEnum("oper"); i++)
+ for (int i = 0; i < ConfValueEnum("oper",&config_f); i++)
{
char LoginName[MAXBUF];
char HostName[MAXBUF];
char OperType[MAXBUF];
- ConfValue("oper","name",i,LoginName);
- ConfValue("oper","host",i,HostName);
- ConfValue("oper","type",i,OperType);
+ ConfValue("oper","name",i,LoginName,&config_f);
+ ConfValue("oper","host",i,HostName,&config_f);
+ ConfValue("oper","type",i,OperType,&config_f);
WriteServ(user->fd,"243 %s O %s * %s %s 0",user->nick,HostName,LoginName,OperType);
}
}
int LinkPort;
bool found = false;
- for (int i = 0; i < ConfValueEnum("link"); i++)
+ for (int i = 0; i < ConfValueEnum("link",&config_f); i++)
{
- ConfValue("link","name",i,Link_ServerName);
- ConfValue("link","ipaddr",i,Link_IPAddr);
- ConfValue("link","port",i,Link_Port);
- ConfValue("link","sendpass",i,Link_Pass);
+ ConfValue("link","name",i,Link_ServerName,&config_f);
+ ConfValue("link","ipaddr",i,Link_IPAddr,&config_f);
+ ConfValue("link","port",i,Link_Port,&config_f);
+ ConfValue("link","sendpass",i,Link_Pass,&config_f);
log(DEBUG,"(%d) Comparing against name='%s', ipaddr='%s', port='%s', recvpass='%s'",i,Link_ServerName,Link_IPAddr,Link_Port,Link_Pass);
LinkPort = atoi(Link_Port);
if (match(Link_ServerName,parameters[0])) {
char Hostname[MAXBUF];
int i,j;
- for (i = 0; i < ConfValueEnum("oper"); i++)
+ for (i = 0; i < ConfValueEnum("oper",&config_f); i++)
{
- ConfValue("oper","name",i,LoginName);
- ConfValue("oper","password",i,Password);
+ ConfValue("oper","name",i,LoginName,&config_f);
+ ConfValue("oper","password",i,Password,&config_f);
if ((!strcmp(LoginName,parameters[0])) && (!strcmp(Password,parameters[1])))
{
/* correct oper credentials */
- ConfValue("oper","type",i,OperType);
+ ConfValue("oper","type",i,OperType,&config_f);
WriteOpers("*** %s (%s@%s) is now an IRC operator of type %s",user->nick,user->ident,user->host,OperType);
WriteServ(user->fd,"381 %s :You are now an IRC operator of type %s",user->nick,OperType);
WriteServ(user->fd,"MODE %s :+o",user->nick);
- for (j =0; j < ConfValueEnum("type"); j++)
+ for (j =0; j < ConfValueEnum("type",&config_f); j++)
{
- ConfValue("type","name",j,TypeName);
+ ConfValue("type","name",j,TypeName,&config_f);
if (!strcmp(TypeName,OperType))
{
/* found this oper's opertype */
- ConfValue("type","host",j,Hostname);
+ ConfValue("type","host",j,Hostname,&config_f);
strncpy(user->dhost,Hostname,256);
}
}
WriteServ(user->fd,"491 %s :Invalid oper credentials",user->nick);
WriteOpers("*** WARNING! Failed oper attempt by %s!%s@%s!",user->nick,user->ident,user->host);
}
-
+
void handle_nick(char **parameters, int pcnt, userrec *user)
{
if (pcnt < 1)
log(DEBUG,"exit nickchange: %s",user->nick);
}
+void force_nickchange(userrec* user,const char* newnick)
+{
+ char nick[MAXBUF];
+ strcpy(nick,"");
+
+ if (user)
+ {
+ if (newnick)
+ {
+ strncpy(nick,newnick,MAXBUF);
+ }
+ if (user->registered == 7)
+ {
+ char* pars[1];
+ pars[0] = nick;
+ handle_nick(pars,1,user);
+ }
+ }
+}
+
+
int process_parameters(char **command_p,char *parameters)
{
int i = 0;
{
return;
}
+
+ int total_params = 0;
+ if (strlen(cmd)>2)
+ {
+ for (int q = 0; q < strlen(cmd)-1; q++)
+ {
+ if ((cmd[q] == ' ') && (cmd[q+1] == ':'))
+ {
+ total_params++;
+ // found a 'trailing', we dont count them after this.
+ break;
+ }
+ if (cmd[q] == ' ')
+ total_params++;
+ }
+ }
+
+ // another phidjit bug...
+ if (total_params > 126)
+ {
+ kill_link(user,"Protocol violation");
+ return;
+ }
+
strcpy(temp,cmd);
string tmp = cmd;
{
/* no parameters, lets skip the formalities and not chop up
* the string */
+ log(DEBUG,"About to preprocess command with no params");
items = 0;
command_p[0] = NULL;
parameters = NULL;
{
cmd[i] = toupper(cmd[i]);
}
+ log(DEBUG,"Preprocess done");
}
else
{
cmd_found = 0;
- log(DEBUG,"Second processing point");
-
if (strlen(command)>MAXCOMMAND)
{
- command[MAXCOMMAND-1] = '\0';
- WriteOpers("Possible command-flood from %s, sending excessively long commands.",user->nick);
+ kill_link(user,"Protocol violation");
+ return;
+ }
+
+ for (int x = 0; x < strlen(command); x++)
+ {
+ if (((command[x] < 'A') || (command[x] > 'Z')) && (command[x] != '.'))
+ {
+ if (((command[x] < '0') || (command[x]> '9')) && (command[x] != '-'))
+ {
+ kill_link(user,"Protocol violation");
+ return;
+ }
+ }
}
for (i = 0; i != cmdlist.size(); i++)
{
if (strcmp(cmdlist[i].command,""))
{
- if (!strcmp(command, cmdlist[i].command))
+ if (strlen(command)>=(strlen(cmdlist[i].command))) if (!strncmp(command, cmdlist[i].command,MAXCOMMAND))
{
log(DEBUG,"Found matching command");
cmd_found = 1;
return;
}
- /* if the command isnt USER, PASS, or NICK, and nick is empty,
- * deny command! */
- if ((strcmp(command,"USER")) && (strcmp(command,"NICK")) && (strcmp(command,"PASS")))
+ /* if the command isnt USER, PASS, or NICK, and nick is empty,
+ * deny command! */
+ if ((strncmp(command,"USER",4)) && (strncmp(command,"NICK",4)) && (strncmp(command,"PASS",4)))
{
if ((!isnick(user->nick)) || (user->registered != 7))
{
void SetupCommandTable(void)
{
- createcommand("USER",handle_user,0,4);
- createcommand("NICK",handle_nick,0,1);
- createcommand("QUIT",handle_quit,0,0);
- createcommand("VERSION",handle_version,0,0);
- createcommand("PING",handle_ping,0,1);
- createcommand("PONG",handle_pong,0,1);
- createcommand("ADMIN",handle_admin,0,0);
- createcommand("PRIVMSG",handle_privmsg,0,2);
- createcommand("INFO",handle_info,0,0);
- createcommand("TIME",handle_time,0,0);
- createcommand("WHOIS",handle_whois,0,1);
- createcommand("WALLOPS",handle_wallops,'o',1);
- createcommand("NOTICE",handle_notice,0,2);
- createcommand("JOIN",handle_join,0,1);
- createcommand("NAMES",handle_names,0,1);
- createcommand("PART",handle_part,0,1);
- createcommand("KICK",handle_kick,0,2);
- createcommand("MODE",handle_mode,0,1);
- createcommand("TOPIC",handle_topic,0,1);
- createcommand("WHO",handle_who,0,1);
- createcommand("MOTD",handle_motd,0,0);
- createcommand("RULES",handle_join,0,0);
- createcommand("OPER",handle_oper,0,2);
- createcommand("LIST",handle_list,0,0);
- createcommand("DIE",handle_die,'o',1);
- createcommand("RESTART",handle_restart,'o',1);
- createcommand("KILL",handle_kill,'o',2);
- createcommand("REHASH",handle_rehash,'o',0);
- createcommand("LUSERS",handle_lusers,0,0);
- createcommand("STATS",handle_stats,0,1);
- createcommand("USERHOST",handle_userhost,0,1);
- createcommand("AWAY",handle_away,0,0);
- createcommand("ISON",handle_ison,0,0);
- createcommand("SUMMON",handle_summon,0,0);
- createcommand("USERS",handle_users,0,0);
- createcommand("INVITE",handle_invite,0,2);
- createcommand("PASS",handle_pass,0,1);
- createcommand("TRACE",handle_trace,'o',0);
- createcommand("WHOWAS",handle_whowas,0,1);
- createcommand("CONNECT",handle_connect,'o',1);
- createcommand("SQUIT",handle_squit,'o',1);
- createcommand("MODULES",handle_modules,'o',0);
+ createcommand("USER",handle_user,0,4);
+ createcommand("NICK",handle_nick,0,1);
+ createcommand("QUIT",handle_quit,0,0);
+ createcommand("VERSION",handle_version,0,0);
+ createcommand("PING",handle_ping,0,1);
+ createcommand("PONG",handle_pong,0,1);
+ createcommand("ADMIN",handle_admin,0,0);
+ createcommand("PRIVMSG",handle_privmsg,0,2);
+ createcommand("INFO",handle_info,0,0);
+ createcommand("TIME",handle_time,0,0);
+ createcommand("WHOIS",handle_whois,0,1);
+ createcommand("WALLOPS",handle_wallops,'o',1);
+ createcommand("NOTICE",handle_notice,0,2);
+ createcommand("JOIN",handle_join,0,1);
+ createcommand("NAMES",handle_names,0,1);
+ createcommand("PART",handle_part,0,1);
+ createcommand("KICK",handle_kick,0,2);
+ createcommand("MODE",handle_mode,0,1);
+ createcommand("TOPIC",handle_topic,0,1);
+ createcommand("WHO",handle_who,0,1);
+ createcommand("MOTD",handle_motd,0,0);
+ createcommand("RULES",handle_rules,0,0);
+ createcommand("OPER",handle_oper,0,2);
+ createcommand("LIST",handle_list,0,0);
+ createcommand("DIE",handle_die,'o',1);
+ createcommand("RESTART",handle_restart,'o',1);
+ createcommand("KILL",handle_kill,'o',2);
+ createcommand("REHASH",handle_rehash,'o',0);
+ createcommand("LUSERS",handle_lusers,0,0);
+ createcommand("STATS",handle_stats,0,1);
+ createcommand("USERHOST",handle_userhost,0,1);
+ createcommand("AWAY",handle_away,0,0);
+ createcommand("ISON",handle_ison,0,0);
+ createcommand("SUMMON",handle_summon,0,0);
+ createcommand("USERS",handle_users,0,0);
+ createcommand("INVITE",handle_invite,0,2);
+ createcommand("PASS",handle_pass,0,1);
+ createcommand("TRACE",handle_trace,'o',0);
+ createcommand("WHOWAS",handle_whowas,0,1);
+ createcommand("CONNECT",handle_connect,'o',1);
+ createcommand("SQUIT",handle_squit,'o',1);
+ createcommand("MODULES",handle_modules,'o',0);
}
void process_buffer(userrec *user)
int LinkPort = 0;
// search for a corresponding <link> block in the config files
- for (int i = 0; i < ConfValueEnum("link"); i++)
+ for (int i = 0; i < ConfValueEnum("link",&config_f); i++)
{
- ConfValue("link","name",i,Link_ServerName);
- ConfValue("link","ipaddr",i,Link_IPAddr);
- ConfValue("link","port",i,Link_Port);
- ConfValue("link","recvpass",i,Link_Pass);
- ConfValue("link","sendpass",i,Link_SendPass);
+ ConfValue("link","name",i,Link_ServerName,&config_f);
+ ConfValue("link","ipaddr",i,Link_IPAddr,&config_f);
+ ConfValue("link","port",i,Link_Port,&config_f);
+ ConfValue("link","recvpass",i,Link_Pass,&config_f);
+ ConfValue("link","sendpass",i,Link_SendPass,&config_f);
log(DEBUG,"(%d) Comparing against name='%s', ipaddr='%s', port='%s', recvpass='%s'",i,Link_ServerName,Link_IPAddr,Link_Port,Link_Pass);
LinkPort = atoi(Link_Port);
if (!strcasecmp(Link_ServerName,servername)) {
int LinkPort = 0;
// search for a corresponding <link> block in the config files
- for (int i = 0; i < ConfValueEnum("link"); i++)
+ for (int i = 0; i < ConfValueEnum("link",&config_f); i++)
{
- ConfValue("link","name",i,Link_ServerName);
- ConfValue("link","ipaddr",i,Link_IPAddr);
- ConfValue("link","port",i,Link_Port);
- ConfValue("link","recvpass",i,Link_Pass);
- ConfValue("link","sendpass",i,Link_SendPass);
+ ConfValue("link","name",i,Link_ServerName,&config_f);
+ ConfValue("link","ipaddr",i,Link_IPAddr,&config_f);
+ ConfValue("link","port",i,Link_Port,&config_f);
+ ConfValue("link","recvpass",i,Link_Pass,&config_f);
+ ConfValue("link","sendpass",i,Link_SendPass,&config_f);
log(DEBUG,"(%d) Comparing against name='%s', ipaddr='%s', port='%s', recvpass='%s'",i,Link_ServerName,Link_IPAddr,Link_Port,Link_Pass);
LinkPort = atoi(Link_Port);
if (!strcasecmp(Link_ServerName,servername)) {
int InspIRCd(void)
{
- struct sockaddr_in client, server;
- char addrs[MAXBUF][255];
- int openSockfd[MAXSOCKS], incomingSockfd, result = TRUE;
- socklen_t length;
- int count = 0, scanDetectTrigger = TRUE, showBanner = FALSE;
- int selectResult = 0;
- char *temp, configToken[MAXBUF], stuff[MAXBUF], Addr[MAXBUF], Type[MAXBUF];
- char resolvedHost[MAXBUF];
- fd_set selectFds;
- struct timeval tv;
-
- log_file = fopen("ircd.log","a+");
- if (!log_file)
- {
- printf("ERROR: Could not write to logfile ircd.log, bailing!\n\n");
- Exit(ERROR);
- }
-
- log(DEBUG,"InspIRCd: startup: begin");
- log(DEBUG,"$Id$");
- if (geteuid() == 0)
- {
- printf("WARNING!!! You are running an irc server as ROOT!!! DO NOT DO THIS!!!\n\n");
- Exit(ERROR);
- log(DEBUG,"InspIRCd: startup: not starting with UID 0!");
- }
- SetupCommandTable();
- log(DEBUG,"InspIRCd: startup: default command table set up");
-
- ReadConfig();
- if (strcmp(DieValue,""))
- {
- printf("WARNING: %s\n\n",DieValue);
- exit(0);
- }
- log(DEBUG,"InspIRCd: startup: read config");
-
- int count2 = 0, count3 = 0;
- for (count = 0; count < ConfValueEnum("bind"); count++)
- {
- ConfValue("bind","port",count,configToken);
- ConfValue("bind","address",count,Addr);
- ConfValue("bind","type",count,Type);
- if (!strcmp(Type,"servers"))
- {
- char Default[MAXBUF];
- strcpy(Default,"no");
- ConfValue("bind","default",count,Default);
- if (strchr(Default,'y'))
- {
- defaultRoute = count3;
- log(DEBUG,"InspIRCd: startup: binding '%s:%s' is default server route",Addr,configToken);
- }
- me[count3] = new serverrec(ServerName,100L,false);
- me[count3]->CreateListener(Addr,atoi(configToken));
- count3++;
+ struct sockaddr_in client, server;
+ char addrs[MAXBUF][255];
+ int openSockfd[MAXSOCKS], incomingSockfd, result = TRUE;
+ socklen_t length;
+ int count = 0, scanDetectTrigger = TRUE, showBanner = FALSE;
+ int selectResult = 0;
+ char *temp, configToken[MAXBUF], stuff[MAXBUF], Addr[MAXBUF], Type[MAXBUF];
+ char resolvedHost[MAXBUF];
+ fd_set selectFds;
+ struct timeval tv;
+
+ log_file = fopen("ircd.log","a+");
+ if (!log_file)
+ {
+ printf("ERROR: Could not write to logfile ircd.log, bailing!\n\n");
+ Exit(ERROR);
}
- else
+
+ log(DEBUG,"InspIRCd: startup: begin");
+ log(DEBUG,"$Id$");
+ if (geteuid() == 0)
{
- ports[count2] = atoi(configToken);
- strcpy(addrs[count2],Addr);
- count2++;
+ printf("WARNING!!! You are running an irc server as ROOT!!! DO NOT DO THIS!!!\n\n");
+ Exit(ERROR);
+ log(DEBUG,"InspIRCd: startup: not starting with UID 0!");
}
- log(DEBUG,"InspIRCd: startup: read binding %s:%s [%s] from config",Addr,configToken, Type);
- }
- portCount = count2;
- UDPportCount = count3;
-
- log(DEBUG,"InspIRCd: startup: read %d total client ports and %d total server ports",portCount,UDPportCount);
-
- log(DEBUG,"InspIRCd: startup: InspIRCd is now running!");
-
- printf("\n");
-
- /* BugFix By Craig! :p */
- count2 = 0;
- for (count = 0; count2 < ConfValueEnum("module"); count2++)
- {
- char modfile[MAXBUF];
- ConfValue("module","name",count,configToken);
- sprintf(modfile,"%s/%s",MOD_PATH,configToken);
- printf("Loading module... \033[1;37m%s\033[0;37m\n",modfile);
- log(DEBUG,"InspIRCd: startup: Loading module: %s",modfile);
- /* If The File Doesnt exist, Trying to load it
- * Will Segfault the IRCd.. So, check to see if
- * it Exists, Before Proceeding. */
- if (FileExists(modfile))
- {
- factory[count] = new ircd_module(modfile);
- if (factory[count]->LastError())
- {
- log(DEBUG,"Unable to load %s: %s",modfile,factory[count]->LastError());
- sprintf("Unable to load %s: %s\nExiting...\n",modfile,factory[count]->LastError());
- Exit(ERROR);
+ SetupCommandTable();
+ log(DEBUG,"InspIRCd: startup: default command table set up");
+
+ ReadConfig();
+ if (strcmp(DieValue,""))
+ {
+ printf("WARNING: %s\n\n",DieValue);
+ exit(0);
+ }
+ log(DEBUG,"InspIRCd: startup: read config");
+
+ int count2 = 0, count3 = 0;
+
+ for (count = 0; count < ConfValueEnum("bind",&config_f); count++)
+ {
+ ConfValue("bind","port",count,configToken,&config_f);
+ ConfValue("bind","address",count,Addr,&config_f);
+ ConfValue("bind","type",count,Type,&config_f);
+ if (!strcmp(Type,"servers"))
+ {
+ char Default[MAXBUF];
+ strcpy(Default,"no");
+ ConfValue("bind","default",count,Default,&config_f);
+ if (strchr(Default,'y'))
+ {
+ defaultRoute = count3;
+ log(DEBUG,"InspIRCd: startup: binding '%s:%s' is default server route",Addr,configToken);
+ }
+ me[count3] = new serverrec(ServerName,100L,false);
+ me[count3]->CreateListener(Addr,atoi(configToken));
+ count3++;
}
- if (factory[count]->factory)
+ else
{
- modules[count] = factory[count]->factory->CreateModule();
- /* save the module and the module's classfactory, if
- * this isnt done, random crashes can occur :/ */
- module_names.push_back(modfile);
+ ports[count2] = atoi(configToken);
+ strcpy(addrs[count2],Addr);
+ count2++;
+ }
+ log(DEBUG,"InspIRCd: startup: read binding %s:%s [%s] from config",Addr,configToken, Type);
+ }
+ portCount = count2;
+ UDPportCount = count3;
+
+ log(DEBUG,"InspIRCd: startup: read %d total client ports and %d total server ports",portCount,UDPportCount);
+
+ log(DEBUG,"InspIRCd: startup: InspIRCd is now running!");
+
+ printf("\n");
+
+ /* BugFix By Craig! :p */
+ count2 = 0;
+ for (count = 0; count2 < ConfValueEnum("module",&config_f); count2++)
+ {
+ char modfile[MAXBUF];
+ ConfValue("module","name",count,configToken,&config_f);
+ sprintf(modfile,"%s/%s",MOD_PATH,configToken,&config_f);
+ printf("Loading module... \033[1;37m%s\033[0;37m\n",modfile);
+ log(DEBUG,"InspIRCd: startup: Loading module: %s",modfile);
+ /* If The File Doesnt exist, Trying to load it
+ * Will Segfault the IRCd.. So, check to see if
+ * it Exists, Before Proceeding. */
+ if (FileExists(modfile))
+ {
+ factory[count] = new ircd_module(modfile);
+ if (factory[count]->LastError())
+ {
+ log(DEBUG,"Unable to load %s: %s",modfile,factory[count]->LastError());
+ sprintf("Unable to load %s: %s\nExiting...\n",modfile,factory[count]->LastError());
+ Exit(ERROR);
+ }
+ if (factory[count]->factory)
+ {
+ modules[count] = factory[count]->factory->CreateModule();
+ /* save the module and the module's classfactory, if
+ * this isnt done, random crashes can occur :/ */
+ module_names.push_back(modfile);
+ }
+ else
+ {
+ log(DEBUG,"Unable to load %s",modfile);
+ sprintf("Unable to load %s\nExiting...\n",modfile);
+ Exit(ERROR);
+ }
+ /* Increase the Count */
+ count++;
}
else
{
- log(DEBUG,"Unable to load %s",modfile);
- sprintf("Unable to load %s\nExiting...\n",modfile);
- Exit(ERROR);
+ log(DEBUG,"InspIRCd: startup: Module Not Found %s",modfile);
+ printf("Module Not Found: \033[1;37m%s\033[0;37m, Skipping\n",modfile);
}
- /* Increase the Count */
- count++;
+ }
+ MODCOUNT = count - 1;
+ log(DEBUG,"Total loaded modules: %d",MODCOUNT+1);
+
+ printf("\nInspIRCd is now running!\n");
+
+ startup_time = time(NULL);
+
+ if (nofork)
+ {
+ log(VERBOSE,"Not forking as -nofork was specified");
}
else
{
- log(DEBUG,"InspIRCd: startup: Module Not Found %s",modfile);
- printf("Module Not Found: \033[1;37m%s\033[0;37m, Skipping\n",modfile);
+ if (DaemonSeed() == ERROR)
+ {
+ log(DEBUG,"InspIRCd: startup: can't daemonise");
+ printf("ERROR: could not go into daemon mode. Shutting down.\n");
+ Exit(ERROR);
+ }
+ }
+
+
+ /* setup select call */
+ FD_ZERO(&selectFds);
+ log(DEBUG,"InspIRCd: startup: zero selects");
+ log(VERBOSE,"InspIRCd: startup: portCount = %d", portCount);
+
+ for (count = 0; count < portCount; count++)
+ {
+ if ((openSockfd[boundPortCount] = OpenTCPSocket()) == ERROR)
+ {
+ log(DEBUG,"InspIRCd: startup: bad fd %d",openSockfd[boundPortCount]);
+ return(ERROR);
+ }
+ if (BindSocket(openSockfd[boundPortCount],client,server,ports[count],addrs[count]) == ERROR)
+ {
+ log(DEBUG,"InspIRCd: startup: failed to bind port %d",ports[count]);
+ }
+ else /* well we at least bound to one socket so we'll continue */
+ {
+ boundPortCount++;
+ }
}
- }
- MODCOUNT = count - 1;
- log(DEBUG,"Total loaded modules: %d",MODCOUNT+1);
-
- printf("\nInspIRCd is now running!\n");
-
- startup_time = time(NULL);
-
- if (nofork)
- {
- log(VERBOSE,"Not forking as -nofork was specified");
- }
- else
- {
- if (DaemonSeed() == ERROR)
+
+ log(DEBUG,"InspIRCd: startup: total bound ports %d",boundPortCount);
+
+ /* if we didn't bind to anything then abort */
+ if (boundPortCount == 0)
{
- log(DEBUG,"InspIRCd: startup: can't daemonise");
- printf("ERROR: could not go into daemon mode. Shutting down.\n");
- Exit(ERROR);
- }
- }
-
-
- /* setup select call */
- FD_ZERO(&selectFds);
- log(DEBUG,"InspIRCd: startup: zero selects");
- log(VERBOSE,"InspIRCd: startup: portCount = %d", portCount);
-
- for (count = 0; count < portCount; count++)
- {
- if ((openSockfd[boundPortCount] = OpenTCPSocket()) == ERROR)
- {
- log(DEBUG,"InspIRCd: startup: bad fd %d",openSockfd[boundPortCount]);
- return(ERROR);
- }
- if (BindSocket(openSockfd[boundPortCount],client,server,ports[count],addrs[count]) == ERROR)
- {
- log(DEBUG,"InspIRCd: startup: failed to bind port %d",ports[count]);
- }
- else /* well we at least bound to one socket so we'll continue */
- {
- boundPortCount++;
- }
- }
-
- log(DEBUG,"InspIRCd: startup: total bound ports %d",boundPortCount);
-
- /* if we didn't bind to anything then abort */
- if (boundPortCount == 0)
- {
- log(DEBUG,"InspIRCd: startup: no ports bound, bailing!");
- return (ERROR);
- }
-
- length = sizeof (client);
- int flip_flop = 0, udp_port = 0;
- char udp_msg[MAXBUF], udp_host[MAXBUF];
-
- /* main loop for multiplexing/resetting */
- for (;;)
- {
- /* set up select call */
- for (count = 0; count < boundPortCount; count++)
- {
- FD_SET (openSockfd[count], &selectFds);
- }
+ log(DEBUG,"InspIRCd: startup: no ports bound, bailing!");
+ return (ERROR);
+ }
- /* added timeout! select was waiting forever... wank... :/ */
- tv.tv_usec = 0;
-
- flip_flop++;
- reap_counter++;
- if (flip_flop > 20)
- {
- tv.tv_usec = 1;
- flip_flop = 0;
- }
+ length = sizeof (client);
+ int flip_flop = 0, udp_port = 0;
+ char udp_msg[MAXBUF], udp_host[MAXBUF];
+
+ /* main loop for multiplexing/resetting */
+ for (;;)
+ {
+ /* set up select call */
+ for (count = 0; count < boundPortCount; count++)
+ {
+ FD_SET (openSockfd[count], &selectFds);
+ }
+
+ /* added timeout! select was waiting forever... wank... :/ */
+ tv.tv_usec = 0;
+
+ flip_flop++;
+ reap_counter++;
+ if (flip_flop > 20)
+ {
+ tv.tv_usec = 1;
+ flip_flop = 0;
+ }
- vector<int>::iterator niterator;
+ vector<int>::iterator niterator;
- // *FIX* Instead of closing sockets in kill_link when they receive the ERROR :blah line, we should queue
- // them in a list, then reap the list every second or so.
- if (reap_counter>5000) {
- if (fd_reap.size() > 0) {
- for( int n = 0; n < fd_reap.size(); n++)
- {
- Blocking(fd_reap[n]);
- close(fd_reap[n]);
- NonBlocking(fd_reap[n]);
+ // *FIX* Instead of closing sockets in kill_link when they receive the ERROR :blah line, we should queue
+ // them in a list, then reap the list every second or so.
+ if (reap_counter>5000) {
+ if (fd_reap.size() > 0) {
+ for( int n = 0; n < fd_reap.size(); n++)
+ {
+ Blocking(fd_reap[n]);
+ close(fd_reap[n]);
+ NonBlocking(fd_reap[n]);
+ }
}
+ fd_reap.clear();
+ reap_counter=0;
}
- fd_reap.clear();
- reap_counter=0;
- }
- tv.tv_sec = 0;
- selectResult = select(MAXSOCKS, &selectFds, NULL, NULL, &tv);
-
- for (int x = 0; x != UDPportCount; x++)
- {
- long theirkey = 0;
- if (me[x]->RecvPacket(udp_msg, udp_host, udp_port, theirkey))
- {
- if (strlen(udp_msg)<1) {
- log(DEBUG,"Invalid datagram from %s:%d:%d [route%d]",udp_host,udp_port,me[x]->port,x);
- }
- else {
+ tv.tv_sec = 0;
+ selectResult = select(MAXSOCKS, &selectFds, NULL, NULL, &tv);
+
+ for (int x = 0; x != UDPportCount; x++)
+ {
+ long theirkey = 0;
+ if (me[x]->RecvPacket(udp_msg, udp_host, udp_port, theirkey))
+ {
+ if (strlen(udp_msg)<1) {
+ log(DEBUG,"Invalid datagram from %s:%d:%d [route%d]",udp_host,udp_port,me[x]->port,x);
+ }
+ else
+ {
FOREACH_MOD OnPacketReceive(udp_msg);
// Packets must go back via the route they arrived on :)
handle_link_packet(theirkey, udp_msg, udp_host, udp_port, me[x]);
- }
- }
- }
+ }
+ }
+ }
- for (user_hash::iterator count2 = clientlist.begin(); count2 != clientlist.end(); count2++)
+ for (user_hash::iterator count2 = clientlist.begin(); count2 != clientlist.end(); count2++)
{
char data[MAXBUF];
{
// until the buffer is at 509 chars anything can be inserted into it.
- if (strlen(count2->second->inbuf) < 509) {
+ if ((strlen(count2->second->inbuf) < 509) && (data[0] != '\0')) {
strncat(count2->second->inbuf, data, result);
}
count2->second->inbuf[509] = '\r';
count2->second->inbuf[510] = '\n';
count2->second->inbuf[511] = '\0';
+ process_buffer(count2->second);
+ break;
}
if (strchr(count2->second->inbuf, '\n') || strchr(count2->second->inbuf, '\r') || (strlen(count2->second->inbuf) > 509))
break;
else
{
- if (strlen(count2->second->inbuf)<513)
+ if (strlen(count2->second->inbuf)<512)
{
// double check the length before processing!
process_buffer(count2->second);
}
+ else
+ {
+ strcpy(count2->second->inbuf,"");
+ }
break;
}
}
}
}
}
-
- /* select is reporting a waiting socket. Poll them all to find out which */
- if (selectResult > 0)
- {
- char target[MAXBUF], resolved[MAXBUF];
- for (count = 0; count < boundPortCount; count++)
- {
- if (FD_ISSET (openSockfd[count], &selectFds))
- {
- incomingSockfd = accept (openSockfd[count], (struct sockaddr *) &client, &length);
-
- address_cache::iterator iter = IP.find(client.sin_addr);
- bool iscached = false;
- if (iter == IP.end())
- {
- /* ip isn't in cache, add it */
- strncpy (target, (char *) inet_ntoa (client.sin_addr), MAXBUF);
- if(CleanAndResolve(resolved, target) != TRUE)
- {
- strncpy(resolved,target,MAXBUF);
- }
- /* hostname now in 'target' */
- IP[client.sin_addr] = new string(resolved);
- /* hostname in cache */
- }
- else
- {
- /* found ip (cached) */
- strncpy(resolved, iter->second->c_str(), MAXBUF);
- iscached = true;
- }
-
- if (incomingSockfd < 0)
- {
- WriteOpers("*** WARNING: Accept failed on port %d (%s)", ports[count],target);
- log(DEBUG,"InspIRCd: accept failed: %d",ports[count]);
- break;
- }
-
- AddClient(incomingSockfd, resolved, ports[count], iscached);
- log(DEBUG,"InspIRCd: adding client on port %d fd=%d",ports[count],incomingSockfd);
- break;
- }
-
- }
- }
- }
-
- /* not reached */
- close (incomingSockfd);
+
+ /* select is reporting a waiting socket. Poll them all to find out which */
+ if (selectResult > 0)
+ {
+ char target[MAXBUF], resolved[MAXBUF];
+ for (count = 0; count < boundPortCount; count++)
+ {
+ if (FD_ISSET (openSockfd[count], &selectFds))
+ {
+ incomingSockfd = accept (openSockfd[count], (struct sockaddr *) &client, &length);
+
+ address_cache::iterator iter = IP.find(client.sin_addr);
+ bool iscached = false;
+ if (iter == IP.end())
+ {
+ /* ip isn't in cache, add it */
+ strncpy (target, (char *) inet_ntoa (client.sin_addr), MAXBUF);
+ if(CleanAndResolve(resolved, target) != TRUE)
+ {
+ strncpy(resolved,target,MAXBUF);
+ }
+ /* hostname now in 'target' */
+ IP[client.sin_addr] = new string(resolved);
+ /* hostname in cache */
+ }
+ else
+ {
+ /* found ip (cached) */
+ strncpy(resolved, iter->second->c_str(), MAXBUF);
+ iscached = true;
+ }
+
+ if (incomingSockfd < 0)
+ {
+ WriteOpers("*** WARNING: Accept failed on port %d (%s)", ports[count],target);
+ log(DEBUG,"InspIRCd: accept failed: %d",ports[count]);
+ break;
+ }
+ AddClient(incomingSockfd, resolved, ports[count], iscached);
+ log(DEBUG,"InspIRCd: adding client on port %d fd=%d",ports[count],incomingSockfd);
+ break;
+ }
+ }
+ }
+}
+/* not reached */
+close (incomingSockfd);
}