#include "commands.h"
#include "xline.h"
#include "inspstring.h"
-#include "dnsqueue.h"
#include "helperfuncs.h"
#include "hashcomp.h"
#include "socketengine.h"
FOREACH_MOD(I_OnRehash,OnRehash(""));
}
-void InspIRCd::SetSignals()
+void InspIRCd::SetSignals(bool SEGVHandler)
{
signal (SIGALRM, SIG_IGN);
signal (SIGHUP, Rehash);
signal (SIGPIPE, SIG_IGN);
signal (SIGTERM, Exit);
- signal (SIGSEGV, Error);
+ if (SEGVHandler)
+ signal (SIGSEGV, Error);
}
bool InspIRCd::DaemonSeed()
InspIRCd::InspIRCd(int argc, char** argv)
{
+ bool SEGVHandler = false;
+
this->Start();
module_sockets.clear();
this->startup_time = time(NULL);
{
printf("WARNING: The `-nolimit' option is deprecated, and now on by default. This behaviour may change in the future.\n");
}
+ else if (!strcmp(argv[i],"-notraceback"))
+ {
+ SEGVHandler = false;
+ }
else if (!strcmp(argv[i],"-logfile"))
{
if (argc > i+1)
printf("ERROR: The -logfile parameter must be followed by a log file name and path.\n");
Exit(ERROR);
}
+ i++;
+ }
+ else
+ {
+ printf("Usage: %s [-nofork] [-nolog] [-debug] [-wait] [-nolimit] [-notraceback] [-logfile <filename>]\n",argv[0]);
+ Exit(ERROR);
}
}
}
this->stats = new serverstats();
this->Parser = new CommandParser();
Config->ClearStack();
- Config->Read(true,NULL);
+ Config->Read(true, NULL);
CheckRoot();
this->ModeGrok = new ModeParser();
AddServerName(Config->ServerName);
memset(&Config->implement_lists,0,sizeof(Config->implement_lists));
printf("\n");
- this->SetSignals();
+ this->SetSignals(SEGVHandler);
if (!Config->nofork)
{
if (!this->DaemonSeed())
}
// found the module
+ log(DEBUG,"Removing dependent commands...");
+ Parser->RemoveCommands(filename);
log(DEBUG,"Deleting module...");
this->EraseModule(j);
log(DEBUG,"Erasing module entry...");
this->EraseFactory(j);
- log(DEBUG,"Removing dependent commands...");
- Parser->RemoveCommands(filename);
log(DEFAULT,"Module %s unloaded",filename);
MODCOUNT--;
BuildISupport();
return false;
}
}
- ircd_module* a = new ircd_module(modfile);
- factory[MODCOUNT+1] = a;
- if (factory[MODCOUNT+1]->LastError())
- {
- log(DEFAULT,"Unable to load %s: %s",modfile,factory[MODCOUNT+1]->LastError());
- snprintf(MODERR,MAXBUF,"Loader/Linker error: %s",factory[MODCOUNT+1]->LastError());
- return false;
- }
try
{
- if (factory[MODCOUNT+1]->factory)
+ ircd_module* a = new ircd_module(modfile);
+ factory[MODCOUNT+1] = a;
+ if (factory[MODCOUNT+1]->LastError())
+ {
+ log(DEFAULT,"Unable to load %s: %s",modfile,factory[MODCOUNT+1]->LastError());
+ snprintf(MODERR,MAXBUF,"Loader/Linker error: %s",factory[MODCOUNT+1]->LastError());
+ return false;
+ }
+ if ((int)factory[MODCOUNT+1]->factory != -1)
{
Module* m = factory[MODCOUNT+1]->factory->CreateModule(MyServer);
modules[MODCOUNT+1] = m;
else
{
log(DEFAULT,"Unable to load %s",modfile);
- snprintf(MODERR,MAXBUF,"Factory function failed!");
+ snprintf(MODERR,MAXBUF,"Factory function failed: Probably missing init_module() entrypoint.");
return false;
}
}
case X_ESTAB_DNS:
/* Handles instances of the Resolver class,
- * a simple class extended by modules for
+ * a simple class extended by modules and the core for
* nonblocking resolving of addresses.
*/
-
- dns_deal_with_classes(activefds[activefd]);
+ this->Res->MarshallReads(activefds[activefd]);
break;
case X_LISTEN:
- log(DEBUG,"Type: X_LISTEN_MODULE: fd=%d",activefds[activefd]);
+ log(DEBUG,"Type: X_LISTEN: fd=%d",activefds[activefd]);
/* It's a listener */
uslen = sizeof(sock_us);
}
stats->statsAccept++;
#ifdef IPV6
+ log(DEBUG,"Add ipv6 client");
AddClient(incomingSockfd, in_port, false, client.sin6_addr);
#else
+ log(DEBUG,"Add ipv4 client");
AddClient(incomingSockfd, in_port, false, client.sin_addr);
#endif
- log(DEBUG,"Adding client on port %lu fd=%lu",(unsigned long)in_port,(unsigned long)incomingSockfd);
+ log(DEBUG,"Adding client on port %d fd=%d",in_port,incomingSockfd);
}
else
{
- log(DEBUG,"Accept failed on fd %lu: %s",(unsigned long)incomingSockfd,strerror(errno));
+ log(DEBUG,"Accept failed on fd %d: %s",incomingSockfd,strerror(errno));
shutdown(incomingSockfd,2);
close(incomingSockfd);
stats->statsRefused++;
int InspIRCd::Run()
{
/* Until THIS point, ServerInstance == NULL */
-
- init_dns();
+
+ this->Res = new DNS();
LoadAllModules(this);
/* Just in case no modules were loaded - fix for bug #101 */
this->BuildISupport();
- printf("\nInspIRCd is now running!\n");
-
- if (!Config->nofork)
+ if (!stats->BoundPortCount)
{
- fclose(stdout);
- fclose(stderr);
- fclose(stdin);
+ printf("\nI couldn't bind any ports! Are you sure you didn't start InspIRCd twice?\n");
+ Exit(ERROR);
}
/* Add the listening sockets used for client inbound connections
* to the socket engine
*/
+ log(DEBUG,"%d listeners",stats->BoundPortCount);
for (unsigned long count = 0; count < stats->BoundPortCount; count++)
- SE->AddFd(Config->openSockfd[count],true,X_LISTEN);
+ {
+ log(DEBUG,"Add listener: %d",Config->openSockfd[count]);
+ if (!SE->AddFd(Config->openSockfd[count],true,X_LISTEN))
+ {
+ printf("\nEH? Could not add listener to socketengine. You screwed up, aborting.\n");
+ Exit(ERROR);
+ }
+ }
+
+ if (!Config->nofork)
+ {
+ fclose(stdout);
+ fclose(stderr);
+ fclose(stdin);
+ }
+
+ printf("\nInspIRCd is now running!\n");
this->WritePID(Config->PID);
int main(int argc, char** argv)
{
- /* TEST SUITE FOR TOKENSTREAM
- *
- * Expected output:
- *
- * String: 'PRIVMSG #test FOO BAR'
- * Token 0 = 'PRIVMSG'
- * Token 1 = '#test'
- * Token 2 = 'FOO'
- * Token 3 = 'BAR'
- * String: 'PRIVMSG #test :FOO BAR BAZ'
- * Token 0 = 'PRIVMSG'
- * Token 1 = '#test'
- * Token 2 = 'FOO BAR BAZ'
- * String: ':PRIVMSG #test :FOO BAR BAZ'
- * Token 0 = ':PRIVMSG'
- * String: 'AAAAAAA'
- * Token 0 = 'AAAAAAA'
- * String: ''
- * NumItems = 0
- *
- std::string a = "PRIVMSG #test FOO BAR";
- printf("String: '%s'\n",a.c_str());
- irc::tokenstream test(a);
- printf("Token 0 = '%s'\n",test.GetToken().c_str());
- printf("Token 1 = '%s'\n",test.GetToken().c_str());
- printf("Token 2 = '%s'\n",test.GetToken().c_str());
- printf("Token 3 = '%s'\n",test.GetToken().c_str());
- printf("Token 4 = '%s'\n",test.GetToken().c_str());
-
- std::string b = "PRIVMSG #test :FOO BAR BAZ";
- printf("String: '%s'\n",b.c_str());
- irc::tokenstream test2(b);
- printf("Token 0 = '%s'\n",test2.GetToken().c_str());
- printf("Token 1 = '%s'\n",test2.GetToken().c_str());
- printf("Token 2 = '%s'\n",test2.GetToken().c_str());
- printf("Token 3 = '%s'\n",test2.GetToken().c_str());
-
- std::string c = ":PRIVMSG #test :FOO BAR BAZ";
- printf("String: '%s'\n",c.c_str());
- irc::tokenstream test3(c);
- printf("Token 0 = '%s'\n",test3.GetToken().c_str());
-
- c = "AAAAAAA";
- printf("String: '%s'\n",c.c_str());
- irc::tokenstream test4(c);
- printf("Token 0 = '%s'\n",test4.GetToken().c_str());
- printf("Token 1 = '%s'\n",test4.GetToken().c_str());
-
- c = "";
- printf("String: '%s'\n",c.c_str());
- irc::tokenstream test5(c);
- printf("Token 0 = '%s'\n",test5.GetToken().c_str());
-
- exit(0);
- */
+ /* This is a MatchCIDR() test suite -
+ printf("Should be 0: %d\n",MatchCIDR("127.0.0.1","1.2.3.4/8"));
+ printf("Should be 1: %d\n",MatchCIDR("127.0.0.1","127.0.0.0/8"));
+ printf("Should be 1: %d\n",MatchCIDR("127.0.0.1","127.0.0.0/18"));
+ printf("Should be 0: %d\n",MatchCIDR("3ffe::0","2fc9::0/16"));
+ printf("Should be 1: %d\n",MatchCIDR("3ffe:1:3::0", "3ffe:1::0/32"));
+ exit(0); */
+
try
{
ServerInstance = new InspIRCd(argc, argv);