const char* InspIRCd::FindServerNamePtr(const std::string &servername)
{
servernamelist::iterator iter = find(servernames.begin(), servernames.end(), servername);
-
+
if(iter == servernames.end())
- {
+ {
AddServerName(servername);
iter = --servernames.end();
}
}
stats->BoundPortCount = 0;
+ /* Close all client sockets, or the new process inherits them */
+ for (std::vector<userrec*>::const_iterator i = this->local_users.begin(); i != this->local_users.end(); i++)
+ {
+ (*i)->SetWriteError("Server shutdown");
+ (*i)->CloseSocket();
+ }
+
/* We do this more than once, so that any service providers get a
* chance to be unhooked by the modules using them, but then get
* a chance to be removed themsleves.
this->UnloadModule(mymodnames[k].c_str());
}
- /* Close all client sockets, or the new process inherits them */
- for (std::vector<userrec*>::const_iterator i = this->local_users.begin(); i != this->local_users.end(); i++)
- (*i)->CloseSocket();
-
/* Close logging */
this->Logger->Close();
}
/* Figure out our filename (if theyve renamed it, we're boned) */
std::string me = Config->MyDir + "/inspircd";
- if (execv(me.c_str(), Config->argv) == -1)
+ char* argv[10];
+ int endp = 2;
+ argv[0] = Config->argv[0];
+ argv[1] = "--restart";
+ if (Config->forcedebug)
+ argv[endp++] = "--debug";
+ if (Config->nofork)
+ argv[endp++] = "--nofork";
+ if (!Config->writelog)
+ argv[endp++] = "--nolog";
+ if (*this->LogFileName)
+ {
+ argv[endp++] = "--logfile";
+ argv[endp++] = this->LogFileName;
+ }
+
+ argv[endp] = NULL;
+
+ if (execv(me.c_str(), argv) == -1)
{
/* Will raise a SIGABRT if not trapped */
throw CoreException(std::string("Failed to execv()! error: ") + strerror(errno));
void InspIRCd::Rehash(int status)
{
- SI->WriteOpers("Rehashing config file %s due to SIGHUP",ServerConfig::CleanFilename(CONFIG_FILE));
+ SI->WriteOpers("*** Rehashing config file %s due to SIGHUP",ServerConfig::CleanFilename(CONFIG_FILE));
SI->CloseLog();
SI->OpenLog(SI->Config->argv, SI->Config->argc);
SI->RehashUsersAndChans();
SI->Config->Read(false,NULL);
SI->ResetMaxBans();
SI->Res->Rehash();
+ SI->BuildISupport();
FOREACH_MOD_I(SI,I_OnRehash,OnRehash(NULL,""));
}
/* Leaves us with just the path */
fname = confpath.substr(0, pos) + std::string("/") + fname;
}
- }
+ }
std::ofstream outfile(fname.c_str());
if (outfile.is_open())
{
}
InspIRCd::InspIRCd(int argc, char** argv)
- : ModCount(-1), duration_m(60), duration_h(60*60), duration_d(60*60*24), duration_w(60*60*24*7), duration_y(60*60*24*365)
+ : ModCount(-1), duration_m(60), duration_h(60*60), duration_d(60*60*24), duration_w(60*60*24*7), duration_y(60*60*24*365), GlobalCulls(this)
{
int found_ports = 0;
FailedPortList pl;
- int do_nofork = 0, do_debug = 0, do_nolog = 0; /* flag variables */
+ int do_nofork = 0, do_debug = 0, do_nolog = 0, do_restart = 0; /* flag variables */
char c = 0;
modules.resize(255);
{ "logfile", required_argument, NULL, 'f' },
{ "debug", no_argument, &do_debug, 1 },
{ "nolog", no_argument, &do_nolog, 1 },
+ { "restart", no_argument, &do_restart, 1 },
{ 0, 0, 0, 0 }
};
break;
default:
/* Unknown parameter! DANGER, INTRUDER.... err.... yeah. */
- printf("Usage: %s [--nofork] [--nolog] [--debug] [--logfile <filename>]\n", argv[0]);
+ printf("Usage: %s [--nofork] [--nolog] [--debug] [--logfile <filename>] [--restart]\n", argv[0]);
Exit(EXIT_STATUS_ARGV);
break;
}
this->OpenLog(argv, argc);
this->stats = new serverstats();
- this->Timers = new TimerManager();
+ this->Timers = new TimerManager(this);
this->Parser = new CommandParser(this);
this->XLines = new XLineManager(this);
Config->ClearStack();
Config->Read(true, NULL);
this->CheckRoot();
this->Modes = new ModeParser(this);
- this->AddServerName(Config->ServerName);
+ this->AddServerName(Config->ServerName);
CheckDie();
InitializeDisabledCommands(Config->DisabledCommands, this);
stats->BoundPortCount = BindPorts(true, found_ports, pl);
printf("\n");
this->SetSignals();
+
if (!Config->nofork)
{
if (!this->DaemonSeed())
{
printf("ERROR: could not go into daemon mode. Shutting down.\n");
+ Log(DEFAULT,"ERROR: could not go into daemon mode. Shutting down.");
Exit(EXIT_STATUS_FORK);
}
}
if ((stats->BoundPortCount == 0) && (found_ports > 0))
{
printf("\nERROR: I couldn't bind any ports! Are you sure you didn't start InspIRCd twice?\n");
+ Log(DEFAULT,"ERROR: I couldn't bind any ports! Are you sure you didn't start InspIRCd twice?");
Exit(EXIT_STATUS_BIND);
}
-
+
if (stats->BoundPortCount != (unsigned int)found_ports)
{
printf("\nWARNING: Not all your client ports could be bound --\nstarting anyway with %ld of %d client ports bound.\n\n", stats->BoundPortCount, found_ports);
if (!SE->AddFd(Config->openSockfd[count]))
{
printf("\nEH? Could not add listener to socketengine. You screwed up, aborting.\n");
+ Log(DEFAULT,"EH? Could not add listener to socketengine. You screwed up, aborting.");
Exit(EXIT_STATUS_INTERNAL);
}
}
- if (!Config->nofork)
+ if (!Config->nofork && !do_restart)
{
+ int closed = 0;
+
if (kill(getppid(), SIGTERM) == -1)
+ {
printf("Error killing parent process: %s\n",strerror(errno));
- fclose(stdin);
- fclose(stderr);
- fclose(stdout);
+ Log(DEFAULT,"Error killing parent process: %s",strerror(errno));
+ }
+
+ /*Log(DEBUG,"Fileno(stdin, stdout, stderr): %d %d %d", fileno(stdin), fileno(stdout), fileno(stderr));*/
+
+ if (stdin)
+ {
+ fclose(stdin);
+ closed++;
+ }
+
+ if (stdout)
+ {
+ fclose(stdout);
+ closed++;
+ }
+
+ if (stderr)
+ {
+ fclose(stderr);
+ closed++;
+ }
+
+ Log(DEBUG,"%d system descriptors closed.", closed);
}
printf("\nInspIRCd is now running!\n");
+ Log(DEFAULT,"Startup complete, Initial TS=%d.", time(NULL));
this->WritePID(Config->PID);
}
}
else
{
- snprintf(versiondata,MAXBUF,"%s %s :%s [FLAGS=%lu,%s,%s]",VERSION,Config->ServerName,SYSTEM,(unsigned long)OPTIMISATION,SE->GetName().c_str(),dnsengine);
+ snprintf(versiondata,MAXBUF,"%s %s :%s [FLAGS=%s,%s,%s]",VERSION,Config->ServerName,SYSTEM,REVISION,SE->GetName().c_str(),dnsengine);
}
return versiondata;
}
{
// the neatest way to construct the initial 005 numeric, considering the number of configure constants to go in it...
std::stringstream v;
- v << "WALLCHOPS WALLVOICES MODES=" << MAXMODES << " CHANTYPES=# PREFIX=" << this->Modes->BuildPrefixes() << " MAP MAXCHANNELS=" << MAXCHANS << " MAXBANS=60 VBANLIST NICKLEN=" << NICKMAX-1;
+ v << "WALLCHOPS WALLVOICES MODES=" << MAXMODES << " CHANTYPES=# PREFIX=" << this->Modes->BuildPrefixes() << " MAP MAXCHANNELS=" << Config->MaxChans << " MAXBANS=60 VBANLIST NICKLEN=" << NICKMAX-1;
v << " CASEMAPPING=rfc1459 STATUSMSG=@%+ CHARSET=ascii TOPICLEN=" << MAXTOPIC << " KICKLEN=" << MAXKICK << " MAXTARGETS=" << Config->MaxTargets << " AWAYLEN=";
v << MAXAWAY << " CHANMODES=" << this->Modes->ChanModes() << " FNC NETWORK=" << Config->Network << " MAXPARA=32";
Config->data005 = v.str();
* file descriptors. The socket engine has everything's
* descriptors in its list... dns, modules, users,
* servers... so its nice and easy, just one call.
- * This will cause any read or write events to be
+ * This will cause any read or write events to be
* dispatched to their handlers.
*/
SE->DispatchEvents();
+
+ /* if any users was quit, take them out */
+ GlobalCulls.Apply();
+
}
bool InspIRCd::IsIdent(const char* n)
int InspIRCd::SetTimeDelta(int delta)
{
int old = time_delta;
- time_delta += delta;
+ time_delta = delta;
this->Log(DEBUG, "Time delta set to %d (was %d)", time_delta, old);
return old;
}
/* Wrote the whole buffer, and no need for write callback */
buffer = "";
}
- }
- if (writeops++ % 20)
- {
- fflush(log);
+
+ if (writeops++ % 20)
+ {
+ fflush(log);
+ }
}
}