#include <sstream>
#include <vector>
#include <deque>
-#include <sched.h>
#ifdef THREADED_DNS
#include <pthread.h>
#endif
#include "socketengine.h"
#include "userprocess.h"
#include "socket.h"
-#include "dns.h"
#include "typedefs.h"
#include "command_parse.h"
extern std::vector<Module*> modules;
extern std::vector<ircd_module*> factory;
+
std::vector<InspSocket*> module_sockets;
std::vector<userrec*> local_users;
int openSockfd[MAXSOCKS];
sockaddr_in client,server;
socklen_t length;
-extern Module* IOHookModule;
-extern InspSocket* socket_ref[65535];
+extern InspSocket* socket_ref[MAX_DESCRIPTORS];
time_t TIME = time(NULL), OLDTIME = time(NULL);
-SocketEngine* SE = NULL;
-
// This table references users by file descriptor.
// its an array to make it VERY fast, as all lookups are referenced
// by an integer, meaning there is no need for a scan/search operation.
userrec* fd_ref_table[65536];
-serverstats* stats = new serverstats;
Server* MyServer = new Server;
ServerConfig *Config = new ServerConfig;
-CommandParser *Parser = NULL;
user_hash clientlist;
chan_hash chanlist;
return single;
}
-
+void InspIRCd::MakeLowerMap()
+{
+ // initialize the lowercase mapping table
+ for (unsigned int cn = 0; cn < 256; cn++)
+ lowermap[cn] = cn;
+ // lowercase the uppercase chars
+ for (unsigned int cn = 65; cn < 91; cn++)
+ lowermap[cn] = tolower(cn);
+ // now replace the specific chars for scandanavian comparison
+ lowermap[(unsigned)'['] = '{';
+ lowermap[(unsigned)']'] = '}';
+ lowermap[(unsigned)'\\'] = '|';
+}
InspIRCd::InspIRCd(int argc, char** argv)
{
}
strlcpy(Config->MyExecutable,argv[0],MAXBUF);
-
- // initialize the lowercase mapping table
- for (unsigned int cn = 0; cn < 256; cn++)
- lowermap[cn] = cn;
- // lowercase the uppercase chars
- for (unsigned int cn = 65; cn < 91; cn++)
- lowermap[cn] = tolower(cn);
- // now replace the specific chars for scandanavian comparison
- lowermap[(unsigned)'['] = '{';
- lowermap[(unsigned)']'] = '}';
- lowermap[(unsigned)'\\'] = '|';
+ this->MakeLowerMap();
OpenLog(argv, argc);
Config->ClearStack();
Config->Read(true,NULL);
CheckRoot();
- Parser = new CommandParser;
- Parser->SetupCommandTable();
+ this->ModeGrok = new ModeParser();
+ this->Parser = new CommandParser();
+ this->stats = new serverstats();
AddServerName(Config->ServerName);
CheckDie();
stats->BoundPortCount = BindPorts();
+ for(int t = 0; t < 255; t++)
+ Config->global_implementation[t] = 0;
+
+ memset(&Config->implement_lists,0,sizeof(Config->implement_lists));
+
printf("\n");
+ SetSignals();
if (!Config->nofork)
{
if (DaemonSeed() == ERROR)
SE = new SocketEngine();
/* We must load the modules AFTER initializing the socket engine, now */
- LoadAllModules();
-
- printf("\nInspIRCd is now running!\n");
return;
}
}
+void InspIRCd::BuildISupport()
+{
+ // 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 << " MAXBANS=60 NICKLEN=" << NICKMAX;
+ v << " CASEMAPPING=rfc1459 STATUSMSG=@+ CHARSET=ascii TOPICLEN=" << MAXTOPIC << " KICKLEN=" << MAXKICK << " MAXTARGETS=20 AWAYLEN=";
+ v << MAXAWAY << " CHANMODES=ohvb,k,l,psmnti NETWORK=" << Config->Network;
+ Config->data005 = v.str();
+ FOREACH_MOD(I_On005Numeric,On005Numeric(Config->data005));
+}
+
bool InspIRCd::UnloadModule(const char* filename)
{
std::string filename_str = filename;
{
modules[j]->OnCleanup(TYPE_USER,u->second);
}
- FOREACH_MOD OnUnloadModule(modules[j],Config->module_names[j]);
+
+ for(int t = 0; t < 255; t++)
+ {
+ Config->global_implementation[t] -= Config->implement_lists[j][t];
+ }
+
+ FOREACH_MOD(I_OnUnloadModule,OnUnloadModule(modules[j],Config->module_names[j]));
// found the module
log(DEBUG,"Deleting module...");
erase_module(j);
Parser->RemoveCommands(filename);
log(DEFAULT,"Module %s unloaded",filename);
MODCOUNT--;
+ BuildISupport();
return true;
}
}
{
char modfile[MAXBUF];
#ifdef STATIC_LINK
- snprintf(modfile,MAXBUF,"%s",filename);
+ strlcpy(modfile,filename,MAXBUF);
#else
snprintf(modfile,MAXBUF,"%s/%s",Config->ModPath,filename);
#endif
/* save the module and the module's classfactory, if
* this isnt done, random crashes can occur :/ */
Config->module_names.push_back(filename);
+
+ char* x = &Config->implement_lists[MODCOUNT+1][0];
+ for(int t = 0; t < 255; t++)
+ x[t] = 0;
+
+ modules[MODCOUNT+1]->Implements(x);
+
+ for(int t = 0; t < 255; t++)
+ {
+ Config->global_implementation[t] += Config->implement_lists[MODCOUNT+1][t];
+ if (Config->implement_lists[MODCOUNT+1][t])
+ {
+ log(DEBUG,"Add global implementation: %d %d => %d",MODCOUNT+1,t,Config->global_implementation[t]);
+ }
+ }
}
else
{
}
#endif
MODCOUNT++;
- FOREACH_MOD OnLoadModule(modules[MODCOUNT],filename_str);
+ FOREACH_MOD(I_OnLoadModule,OnLoadModule(modules[MODCOUNT],filename_str));
+ BuildISupport();
return true;
}
int InspIRCd::Run()
{
bool expire_run = false;
- std::vector<int> activefds;
+ int activefds[MAX_DESCRIPTORS];
int incomingSockfd;
int in_port;
userrec* cu = NULL;
char* target;
unsigned int numberactive;
sockaddr_in sock_us; // our port number
- socklen_t uslen; // length of our port number
+ socklen_t uslen; // length of our port number
+
+ /* Until THIS point, ServerInstance == NULL */
+
+ LoadAllModules(this);
+ printf("\nInspIRCd is now running!\n");
+
if (!Config->nofork)
{
freopen("/dev/null","w",stdout);
if (((TIME % 8) == 0) && (!expire_run))
{
expire_lines();
- FOREACH_MOD OnBackgroundTimer(TIME);
+ FOREACH_MOD(I_OnBackgroundTimer,OnBackgroundTimer(TIME));
expire_run = true;
continue;
}
- if ((TIME % 8) == 1)
+ else if ((TIME % 8) == 1)
+ {
expire_run = false;
+ }
/* Once a second, do the background processing */
if (TIME != OLDTIME)
- while (DoBackgroundUserStuff(TIME));
+ DoBackgroundUserStuff(TIME);
/* Call the socket engine to wait on the active
* file descriptors. The socket engine has everything's
* descriptors in its list... dns, modules, users,
* servers... so its nice and easy, just one call.
*/
- SE->Wait(activefds);
+ if (!(numberactive = SE->Wait(activefds)))
+ continue;
/**
* Now process each of the fd's. For users, we have a fast
* listening ports or module sockets though, things could get
* ugly.
*/
- numberactive = activefds.size();
for (unsigned int activefd = 0; activefd < numberactive; activefd++)
{
int socket_type = SE->GetType(activefds[activefd]);
*/
if (incomingSockfd >= 0)
{
- if (IOHookModule)
+ NonBlocking(incomingSockfd);
+ if (Config->GetIOHook(in_port))
{
- IOHookModule->OnRawSocketAccept(incomingSockfd, target, in_port);
+ Config->GetIOHook(in_port)->OnRawSocketAccept(incomingSockfd, target, in_port);
}
stats->statsAccept++;
AddClient(incomingSockfd, target, in_port, false, target);