The InspIRCd Project
Home | Developers | Wiki | Forums | Bug Tracker | SVN | Download | Blog | Stats
Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

InspIRCd Class Reference

The main class of the irc server. More...

#include <inspircd.h>

Inheritance diagram for InspIRCd:

Inheritance graph
[legend]
Collaboration diagram for InspIRCd:

Collaboration graph
[legend]
List of all members.

Public Member Functions

void BuildISupport ()
 Build the ISUPPORT string by triggering all modules On005Numeric events.
time_t Time (bool delta=false)
 Get the current time Because this only calls time() once every time around the mainloop, it is much faster than calling time() directly.
int SetTimeDelta (int delta)
 Set the time offset in seconds This offset is added to Time() to offset the system time by the specified number of seconds.
void AddLocalClone (userrec *user)
 Add a user to the local clone map.
void AddGlobalClone (userrec *user)
 Add a user to the global clone map.
int ModeCount (const char mode)
 Number of users with a certain mode set on them.
int GetTimeDelta ()
 Get the time offset in seconds.
void ProcessUser (userrec *cu)
 Process a user whos socket has been flagged as active.
int GetModuleCount ()
 Get the total number of currently loaded modules.
ModuleFindModule (const std::string &name)
 Find a module by name, and return a Module* to it.
int BindPorts (bool bail, int &found_ports, FailedPortList &failed_ports)
 Bind all ports specified in the configuration file.
bool BindSocket (int sockfd, int port, char *addr, bool dolisten=true)
 Binds a socket on an already open file descriptor.
void AddServerName (const std::string &servername)
 Adds a server name to the list of servers we've seen.
const char * FindServerNamePtr (const std::string &servername)
 Finds a cached char* pointer of a server name, This is used to optimize userrec by storing only the pointer to the name.
bool FindServerName (const std::string &servername)
 Returns true if we've seen the given server name before.
std::string GetServerDescription (const char *servername)
 Gets the GECOS (description) field of the given server.
void WriteOpers (const char *text,...)
 Write text to all opers connected to this server.
void WriteOpers (const std::string &text)
 Write text to all opers connected to this server.
userrecFindNick (const std::string &nick)
 Find a nickname in the nick hash.
userrecFindNick (const char *nick)
 Find a nickname in the nick hash.
chanrecFindChan (const std::string &chan)
 Find a channel in the channels hash.
chanrecFindChan (const char *chan)
 Find a channel in the channels hash.
void LoadAllModules ()
 Called by the constructor to load all modules from the config file.
void CheckDie ()
 Check for a 'die' tag in the config file, and abort if found.
void CheckRoot ()
 Check we aren't running as root, and exit if we are.
bool OpenLog (char **argv, int argc)
 Determine the right path for, and open, the logfile.
void CloseLog ()
 Close the currently open log file.
void ServerNoticeAll (char *text,...)
 Send a server notice to all local users.
void ServerPrivmsgAll (char *text,...)
 Send a server message (PRIVMSG) to all local users.
void WriteMode (const char *modes, int flags, const char *text,...)
 Send text to all users with a specific set of modes.
bool IsChannel (const char *chname)
 Return true if a channel name is valid.
int UserCount ()
 Return a count of users, unknown and known connections.
int RegisteredUserCount ()
 Return a count of fully registered connections only.
int InvisibleUserCount ()
 Return a count of invisible (umode +i) users only.
int OperCount ()
 Return a count of opered (umode +o) users only.
int UnregisteredUserCount ()
 Return a count of unregistered (before NICK/USER) users only.
long ChannelCount ()
 Return a count of channels on the network.
long LocalUserCount ()
 Return a count of local users on this server only.
void SendError (const std::string &s)
 Send an error notice to all local users, opered and unopered.
long PriorityBefore (const std::string &modulename)
 For use with Module::Prioritize().
long PriorityAfter (const std::string &modulename)
 For use with Module::Prioritize().
bool PublishFeature (const std::string &FeatureName, Module *Mod)
 Publish a 'feature'.
bool PublishInterface (const std::string &InterfaceName, Module *Mod)
 Publish a module to an 'interface'.
std::pair< int, std::stringGetInterfaceInstanceCount (Module *m)
 Return a pair saying how many other modules are currently using the interfaces provided by module m.
void UseInterface (const std::string &InterfaceName)
 Mark your module as using an interface.
void DoneWithInterface (const std::string &InterfaceName)
 Mark your module as finished with an interface.
bool UnpublishFeature (const std::string &FeatureName)
 Unpublish a 'feature'.
bool UnpublishInterface (const std::string &InterfaceName, Module *Mod)
 Unpublish your module from an interface When your module exits, it must call this method for every interface it is part of so that the interfaces table is cleaned up.
ModuleFindFeature (const std::string &FeatureName)
 Find a 'feature'.
modulelistFindInterface (const std::string &InterfaceName)
 Find an 'interface'.
const std::stringGetModuleName (Module *m)
 Given a pointer to a Module, return its filename.
bool IsNick (const char *n)
 Return true if a nickname is valid.
bool IsIdent (const char *n)
 Return true if an ident is valid.
userrecFindDescriptor (int socket)
 Find a username by their file descriptor.
bool AddMode (ModeHandler *mh, const unsigned char modechar)
 Add a new mode to this server's mode parser.
bool AddModeWatcher (ModeWatcher *mw)
 Add a new mode watcher to this server's mode parser.
bool DelModeWatcher (ModeWatcher *mw)
 Delete a mode watcher from this server's mode parser.
bool AddResolver (Resolver *r, bool cached)
 Add a dns Resolver class to this server's active set.
void AddCommand (command_t *f)
 Add a command to this server's command parser.
void SendMode (const char **parameters, int pcnt, userrec *user)
 Send a modechange.
bool MatchText (const std::string &sliteral, const std::string &spattern)
 Match two strings using pattern matching.
CmdResult CallCommandHandler (const std::string &commandname, const char **parameters, int pcnt, userrec *user)
 Call the handler for a given command.
bool IsValidModuleCommand (const std::string &commandname, int pcnt, userrec *user)
 Return true if the command is a module-implemented command and the given parameters are valid for it.
void AddGLine (long duration, const std::string &source, const std::string &reason, const std::string &hostmask)
 Add a gline and apply it.
void AddQLine (long duration, const std::string &source, const std::string &reason, const std::string &nickname)
 Add a qline and apply it.
void AddZLine (long duration, const std::string &source, const std::string &reason, const std::string &ipaddr)
 Add a zline and apply it.
void AddKLine (long duration, const std::string &source, const std::string &reason, const std::string &hostmask)
 Add a kline and apply it.
void AddELine (long duration, const std::string &source, const std::string &reason, const std::string &hostmask)
 Add an eline.
bool DelGLine (const std::string &hostmask)
 Delete a gline.
bool DelQLine (const std::string &nickname)
 Delete a qline.
bool DelZLine (const std::string &ipaddr)
 Delete a zline.
bool DelKLine (const std::string &hostmask)
 Delete a kline.
bool DelELine (const std::string &hostmask)
 Delete an eline.
bool IsValidMask (const std::string &mask)
 Return true if the given parameter is a valid nick!user@host mask.
void RehashServer ()
 Rehash the local server.
chanrecGetChannelIndex (long index)
 Return the channel whos index number matches that provided.
void DumpText (userrec *User, const std::string &LinePrefix, stringstream &TextStream)
 Dump text to a user target, splitting it appropriately to fit.
bool NickMatchesEveryone (const std::string &nick, userrec *user)
 Check if the given nickmask matches too many users, send errors to the given user.
bool IPMatchesEveryone (const std::string &ip, userrec *user)
 Check if the given IP mask matches too many users, send errors to the given user.
bool HostMatchesEveryone (const std::string &mask, userrec *user)
 Check if the given hostmask matches too many users, send errors to the given user.
long Duration (const std::string &str)
 Calculate a duration in seconds from a string in the form 1y2w3d4h6m5s.
int OperPassCompare (const char *data, const char *input, int tagnum)
 Attempt to compare an oper password to a string from the config file.
bool ULine (const char *server)
 Check if a given server is a uline.
bool SilentULine (const char *server)
 Returns true if the uline is 'silent' (doesnt generate remote connect notices etc).
std::string GetRevision ()
 Returns the subversion revision ID of this ircd.
std::string GetVersionString ()
 Returns the full version string of this ircd.
void WritePID (const std::string &filename)
 Attempt to write the process id to a given file.
char * ModuleError ()
 Returns text describing the last module error.
bool LoadModule (const char *filename)
 Load a given module file.
bool UnloadModule (const char *filename)
 Unload a given module file.
 InspIRCd (int argc, char **argv)
 This constructor initialises all the subsystems and reads the config file.
void DoOneIteration (bool process_module_sockets=true)
 Do one iteration of the mainloop.
void Log (int level, const char *text,...)
 Output a log message to the ircd.log file The text will only be output if the current loglevel is less than or equal to the level you provide.
void Log (int level, const std::string &text)
 Output a log message to the ircd.log file The text will only be output if the current loglevel is less than or equal to the level you provide.
void SendWhoisLine (userrec *user, userrec *dest, int numeric, const std::string &text)
 Send a line of WHOIS data to a user.
void SendWhoisLine (userrec *user, userrec *dest, int numeric, const char *format,...)
 Send a line of WHOIS data to a user.
void FloodQuitUser (userrec *current)
 Quit a user for excess flood, and if they are not fully registered yet, temporarily zline their IP.
void Restart (const std::string &reason)
 Restart the server.
void Cleanup ()
 Prepare the ircd for restart or shutdown.
void RehashUsersAndChans ()
 This copies the user and channel hash_maps into new hash maps.
void ResetMaxBans ()
 Resets the cached max bans value on all channels.
std::string TimeString (time_t curtime)
 Return a time_t as a human-readable string.
int Run ()
 Begin execution of the server.
void InspSocketCull ()
 Force all InspSockets to be removed which are due to be culled.

Static Public Member Functions

static void Rehash (int status)
 Rehash the local server.
static void Exit (int status)
 Causes the server to exit after unloading modules and closing all open file descriptors.
static void QuickExit (int status)
 Causes the server to exit immediately with exit code 0.

Public Attributes

int s_signal
 Signal which last occured.
std::map< InspSocket *, InspSocket * > SocketCull
 InspSocket classes pending deletion after being closed.
int unregistered_count
 Number of unregistered users online right now.
servernamelist servernames
 List of server names we've seen.
time_t startup_time
 Time this ircd was booted.
char ConfigFileName [MAXBUF]
 Config file pathname specified on the commandline or via .
ModeParserModes
 Mode handler, handles mode setting and removal.
CommandParserParser
 Command parser, handles client to server commands.
SocketEngineSE
 Socket engine, handles socket activity events.
serverstatsstats
 Stats class, holds miscellaneous stats counters.
ServerConfigConfig
 Server Config class, holds configuration file data.
SnomaskManagerSNO
 Snomask manager - handles routing of snomask messages to opers.
user_hashclientlist
 Client list, a hash_map containing all clients, local and remote.
chan_hashchanlist
 Channel list, a hash_map containing all channels.
std::vector< userrec * > local_users
 Local client list, a vector containing only local clients.
std::list< userrec * > all_opers
 Oper list, a vector containing all local and remote opered users.
clonemap local_clones
 Map of local ip addresses for clone counting.
clonemap global_clones
 Map of global ip addresses for clone counting.
DNSRes
 DNS class, provides resolver facilities to the core and modules.
TimerManagerTimers
 Timer manager class, triggers InspTimer timer events.
XLineManagerXLines
 X-Line manager.
ModuleList modules
 A list of Module* module classes Note that this list is always exactly 255 in size.
FactoryList factory
 A list of ModuleFactory* module factories Note that this list is always exactly 255 in size.
time_t next_call
 The time we next call our ping timeout and reg timeout checks.
CullList GlobalCulls
 Global cull list, will be processed on next iteration.

Private Member Functions

void EraseFactory (int j)
 Remove a ModuleFactory pointer.
void EraseModule (int j)
 Remove a Module pointer.
void MoveTo (std::string modulename, int slot)
 Move a given module to a specific slot in the list.
void Start ()
 Display the startup banner.
void SetSignals ()
 Set up the signal handlers.
bool DaemonSeed ()
 Daemonize the ircd and close standard input/output streams.
void MoveToLast (std::string modulename)
 Moves the given module to the last slot in the list.
void MoveToFirst (std::string modulename)
 Moves the given module to the first slot in the list.
void MoveAfter (std::string modulename, std::string after)
 Moves one module to be placed after another in the list.
void MoveBefore (std::string modulename, std::string before)
 Moves one module to be placed before another in the list.
void DoSocketTimeouts (time_t TIME)
 Iterate the list of InspSocket objects, removing ones which have timed out.
void DoBackgroundUserStuff (time_t TIME)
 Perform background user events such as PING checks.
bool AllModulesReportReady (userrec *user)
 Returns true when all modules have done pre-registration checks on a user.
void SignalHandler (int signal)

Static Private Member Functions

static void SetSignal (int signal)

Private Attributes

char MODERR [MAXBUF]
 Holds a string describing the last module error to occur.
int ModCount
 Total number of modules loaded into the ircd, minus one.
char LogFileName [MAXBUF]
 Logfile pathname specified on the commandline, or empty string.
featurelist Features
 The feature names published by various modules.
interfacelist Interfaces
 The interface names published by various modules.
time_t TIME
 The current time, updated in the mainloop.
time_t OLDTIME
 The time that was recorded last time around the mainloop.
char ReadBuffer [65535]
 A 64k buffer used to read client lines into.
insp_sockaddr client
 Used when connecting clients.
insp_sockaddr server
socklen_t length
 Used when connecting clients.
FileLoggerLogger
 Nonblocking file writer.
int time_delta
 Time offset in seconds This offset is added to all calls to Time().

Detailed Description

The main class of the irc server.

This class contains instances of all the other classes in this software, with the exception of the base class, classbase. Amongst other things, it contains a ModeParser, a DNS object, a CommandParser object, and a list of active Module objects, and facilities for Module objects to interact with the core system it implements. You should NEVER attempt to instantiate a class of type InspIRCd yourself. If you do, this is equivalent to spawning a second IRC server, and could have catastrophic consequences for the program in terms of ram usage (basically, you could create an obese forkbomb built from recursively spawning irc servers!)

Definition at line 334 of file inspircd.h.


Constructor & Destructor Documentation

InspIRCd::InspIRCd int  argc,
char **  argv
 

This constructor initialises all the subsystems and reads the config file.

Parameters:
argc The argument count passed to main()
argv The argument list passed to main()
Exceptions:
<anything> If anything is thrown from here and makes it to you, you should probably just give up and go home. Yes, really. It's that bad. Higher level classes should catch any non-fatal exceptions.

Definition at line 467 of file inspircd.cpp.

References AddServerName(), ServerConfig::argc, ServerConfig::argv, BindPorts(), BuildISupport(), chanlist, CheckDie(), CheckRoot(), ServerConfig::ClearStack(), client, clientlist, Config, CONFIG_FILE, ConfigFileName, SocketEngineFactory::Create(), DEFAULT, ServerConfig::DisabledCommands, Exit(), EXIT_STATUS_ARGV, EXIT_STATUS_BIND, EXIT_STATUS_CONFIG, EXIT_STATUS_FORK, EXIT_STATUS_LOG, EXIT_STATUS_NOERROR, factory, ServerConfig::FileExists(), ServerConfig::forcedebug, ServerConfig::GetFullProgDir(), ServerConfig::global_implementation, ServerConfig::implement_lists, InitializeDisabledCommands(), LoadAllModules(), Log(), LogFileName, ServerConfig::logpath, MAXBUF, Modes, modules, ServerConfig::MyExecutable, next_call, ServerConfig::nofork, OLDTIME, ServerConfig::operclass, ServerConfig::opertypes, Parser, ServerConfig::PID, ServerConfig::ports, ServerConfig::Read(), Res, REVISION, s_signal, SE, server, ServerConfig::ServerName, SetSignals(), CommandParser::SetupCommandTable(), SNO, Start(), startup_time, stats, strlcpy(), TIME, time_delta, Timers, unregistered_count, VERSION, ServerConfig::writelog, WritePID(), and XLines.

00468         : ModCount(-1), GlobalCulls(this)
00469 {
00470         int found_ports = 0;
00471         FailedPortList pl;
00472         int do_version = 0, do_nofork = 0, do_debug = 0, do_nolog = 0, do_root = 0;    /* flag variables */
00473         int c = 0;
00474 
00475         s_signal = 0;
00476 
00477         modules.resize(255);
00478         factory.resize(255);
00479         memset(&server, 0, sizeof(server));
00480         memset(&client, 0, sizeof(client));
00481 
00482         this->unregistered_count = 0;
00483 
00484         this->clientlist = new user_hash();
00485         this->chanlist = new chan_hash();
00486 
00487         this->Config = new ServerConfig(this);
00488 
00489         this->Config->argv = argv;
00490         this->Config->argc = argc;
00491 
00492         if (chdir(Config->GetFullProgDir().c_str()))
00493         {
00494                 printf("Unable to change to my directory: %s\nAborted.", strerror(errno));
00495                 exit(0);
00496         }
00497 
00498         this->Config->opertypes.clear();
00499         this->Config->operclass.clear();
00500         this->SNO = new SnomaskManager(this);
00501         this->TIME = this->OLDTIME = this->startup_time = time(NULL);
00502         this->time_delta = 0;
00503         this->next_call = this->TIME + 3;
00504         srand(this->TIME);
00505 
00506         *this->LogFileName = 0;
00507         strlcpy(this->ConfigFileName, CONFIG_FILE, MAXBUF);
00508 
00509         struct option longopts[] =
00510         {
00511                 { "nofork",     no_argument,            &do_nofork,     1       },
00512                 { "logfile",    required_argument,      NULL,           'f'     },
00513                 { "config",     required_argument,      NULL,           'c'     },
00514                 { "debug",      no_argument,            &do_debug,      1       },
00515                 { "nolog",      no_argument,            &do_nolog,      1       },
00516                 { "runasroot",  no_argument,            &do_root,       1       },
00517                 { "version",    no_argument,            &do_version,    1       },
00518                 { 0, 0, 0, 0 }
00519         };
00520 
00521         while ((c = getopt_long_only(argc, argv, ":f:", longopts, NULL)) != -1)
00522         {
00523                 switch (c)
00524                 {
00525                         case 'f':
00526                                 /* Log filename was set */
00527                                 strlcpy(LogFileName, optarg, MAXBUF);
00528                         break;
00529                         case 'c':
00530                                 /* Config filename was set */
00531                                 strlcpy(ConfigFileName, optarg, MAXBUF);
00532                         break;
00533                         case 0:
00534                                 /* getopt_long_only() set an int variable, just keep going */
00535                         break;
00536                         default:
00537                                 /* Unknown parameter! DANGER, INTRUDER.... err.... yeah. */
00538                                 printf("Usage: %s [--nofork] [--nolog] [--debug] [--logfile <filename>] [--runasroot] [--version] [--config <config>]\n", argv[0]);
00539                                 Exit(EXIT_STATUS_ARGV);
00540                         break;
00541                 }
00542         }
00543 
00544         if (do_version)
00545         {
00546                 printf("\n%s r%s\n", VERSION, REVISION);
00547                 Exit(EXIT_STATUS_NOERROR);
00548         }
00549 
00550 #ifdef WIN32
00551 
00552         // Handle forking
00553         if(!do_nofork && !owner_processid)
00554         {
00555                 DWORD ExitCode = WindowsForkStart(this);
00556                 if(ExitCode)
00557                         Exit(ExitCode);
00558         }
00559 
00560         // Set up winsock
00561         WSADATA wsadata;
00562         WSAStartup(MAKEWORD(2,0), &wsadata);
00563 
00564 #endif
00565         strlcpy(Config->MyExecutable,argv[0],MAXBUF);
00566 
00567         if (!this->OpenLog(argv, argc))
00568         {
00569                 printf("ERROR: Could not open logfile %s: %s\n\n", Config->logpath.c_str(), strerror(errno));
00570                 Exit(EXIT_STATUS_LOG);
00571         }
00572 
00573         if (!ServerConfig::FileExists(this->ConfigFileName))
00574         {
00575                 printf("ERROR: Cannot open config file: %s\nExiting...\n", this->ConfigFileName);
00576                 this->Log(DEFAULT,"Unable to open config file %s", this->ConfigFileName);
00577                 Exit(EXIT_STATUS_CONFIG);
00578         }
00579 
00580         this->Start();
00581 
00582         /* Set the finished argument values */
00583         Config->nofork = do_nofork;
00584         Config->forcedebug = do_debug;
00585         Config->writelog = !do_nolog;
00586 
00587         this->stats = new serverstats();
00588         this->Timers = new TimerManager(this);
00589         this->Parser = new CommandParser(this);
00590         this->XLines = new XLineManager(this);
00591         Config->ClearStack();
00592         Config->Read(true, NULL);
00593 
00594         this->Parser->SetupCommandTable(NULL);
00595 
00596         if (!do_root)
00597                 this->CheckRoot();
00598         else
00599         {
00600                 printf("* WARNING * WARNING * WARNING * WARNING * WARNING * \n\n");
00601                 printf("YOU ARE RUNNING INSPIRCD AS ROOT. THIS IS UNSUPPORTED\n");
00602                 printf("AND IF YOU ARE HACKED, CRACKED, SPINDLED OR MUTILATED\n");
00603                 printf("OR ANYTHING ELSE UNEXPECTED HAPPENS TO YOU OR YOUR\n");
00604                 printf("SERVER, THEN IT IS YOUR OWN FAULT. IF YOU DID NOT MEAN\n");
00605                 printf("TO START INSPIRCD AS ROOT, HIT CTRL+C NOW AND RESTART\n");
00606                 printf("THE PROGRAM AS A NORMAL USER. YOU HAVE BEEN WARNED!\n");
00607                 printf("\nInspIRCd starting in 20 seconds, ctrl+c to abort...\n");
00608                 sleep(20);
00609         }
00610 
00611         this->SetSignals();
00612 
00613         if (!Config->nofork)
00614         {
00615                 if (!this->DaemonSeed())
00616                 {
00617                         printf("ERROR: could not go into daemon mode. Shutting down.\n");
00618                         Log(DEFAULT,"ERROR: could not go into daemon mode. Shutting down.");
00619                         Exit(EXIT_STATUS_FORK);
00620                 }
00621         }
00622 
00623 
00624         /* Because of limitations in kqueue on freebsd, we must fork BEFORE we
00625          * initialize the socket engine.
00626          */
00627         SocketEngineFactory* SEF = new SocketEngineFactory();
00628         SE = SEF->Create(this);
00629         delete SEF;
00630 
00631         this->Modes = new ModeParser(this);
00632         this->AddServerName(Config->ServerName);
00633         CheckDie();
00634         int bounditems = BindPorts(true, found_ports, pl);
00635 
00636         for(int t = 0; t < 255; t++)
00637                 Config->global_implementation[t] = 0;
00638 
00639         memset(&Config->implement_lists,0,sizeof(Config->implement_lists));
00640 
00641         printf("\n");
00642 
00643         this->Res = new DNS(this);
00644 
00645         this->LoadAllModules();
00646         /* Just in case no modules were loaded - fix for bug #101 */
00647         this->BuildISupport();
00648         InitializeDisabledCommands(Config->DisabledCommands, this);
00649 
00650         if (Config->ports.size() != (unsigned int)found_ports)
00651         {
00652                 printf("\nWARNING: Not all your client ports could be bound --\nstarting anyway with %d of %d client ports bound.\n\n", bounditems, found_ports);
00653                 printf("The following port(s) failed to bind:\n");
00654                 int j = 1;
00655                 for (FailedPortList::iterator i = pl.begin(); i != pl.end(); i++, j++)
00656                 {
00657                         printf("%d.\tAddress: %s\tReason: %s\n", j, i->first.empty() ? "<all>" : i->first.c_str(), i->second.c_str());
00658                 }
00659         }
00660 
00661         if ((Config->ports.size() == 0) && (found_ports > 0))
00662         {
00663                 printf("\nERROR: I couldn't bind any ports! Are you sure you didn't start InspIRCd twice?\n");
00664                 Log(DEFAULT,"ERROR: I couldn't bind any ports! Are you sure you didn't start InspIRCd twice?");
00665                 Exit(EXIT_STATUS_BIND);
00666         }
00667 
00668 #ifndef WINDOWS
00669         if (!Config->nofork)
00670         {
00671                 if (kill(getppid(), SIGTERM) == -1)
00672                 {
00673                         printf("Error killing parent process: %s\n",strerror(errno));
00674                         Log(DEFAULT,"Error killing parent process: %s",strerror(errno));
00675                 }
00676         }
00677 
00678         if (isatty(0) && isatty(1) && isatty(2))
00679         {
00680                 /* We didn't start from a TTY, we must have started from a background process -
00681                  * e.g. we are restarting, or being launched by cron. Dont kill parent, and dont
00682                  * close stdin/stdout
00683                  */
00684                 if (!do_nofork)
00685                 {
00686                         fclose(stdin);
00687                         fclose(stderr);
00688                         fclose(stdout);
00689                 }
00690                 else
00691                 {
00692                         Log(DEFAULT,"Keeping pseudo-tty open as we are running in the foreground.");
00693                 }
00694         }
00695 #else
00696         InitIPC();
00697         if(!Config->nofork)
00698         {
00699                 WindowsForkKillOwner(this);
00700                 FreeConsole();
00701         }
00702 #endif
00703         printf("\nInspIRCd is now running!\n");
00704         Log(DEFAULT,"Startup complete.");
00705 
00706         this->WritePID(Config->PID);
00707 }


Member Function Documentation

void InspIRCd::AddCommand command_t f  ) 
 

Add a command to this server's command parser.

Parameters:
f A command_t command handler object to add
Exceptions:
ModuleException Will throw ModuleExcption if the command already exists

Definition at line 389 of file modules.cpp.

References command_t::command.

Referenced by FilterBase::FilterBase(), Modulealltime::Modulealltime(), ModuleCBan::ModuleCBan(), ModuleCgiIRC::ModuleCgiIRC(), ModuleCheck::ModuleCheck(), ModuleChgHost::ModuleChgHost(), ModuleChgIdent::ModuleChgIdent(), ModuleChgName::ModuleChgName(), ModuleClones::ModuleClones(), ModuleClose::ModuleClose(), ModuleCustomTitle::ModuleCustomTitle(), ModuleCycle::ModuleCycle(), ModuleDCCAllow::ModuleDCCAllow(), ModuleDeVoice::ModuleDeVoice(), ModuleGlobalLoad::ModuleGlobalLoad(), ModuleGlobops::ModuleGlobops(), ModuleHelpop::ModuleHelpop(), ModuleJumpServer::ModuleJumpServer(), ModuleKnock::ModuleKnock(), ModuleLockserv::ModuleLockserv(), ModuleNickLock::ModuleNickLock(), ModuleOperHash::ModuleOperHash(), ModuleOpermotd::ModuleOpermotd(), ModuleOperSSLCert::ModuleOperSSLCert(), ModuleRandQuote::ModuleRandQuote(), ModuleRemove::ModuleRemove(), ModuleSajoin::ModuleSajoin(), ModuleSaMode::ModuleSaMode(), ModuleSanick::ModuleSanick(), ModuleSapart::ModuleSapart(), ModuleSaquit::ModuleSaquit(), ModuleSetHost::ModuleSetHost(), ModuleSetIdent::ModuleSetIdent(), ModuleSetIdle::ModuleSetIdle(), ModuleSetName::ModuleSetName(), ModuleSilence::ModuleSilence(), ModuleSpanningTree::ModuleSpanningTree(), ModuleSpy::ModuleSpy(), ModuleSSLInfo::ModuleSSLInfo(), ModuleSVSHold::ModuleSVSHold(), ModuleSWhois::ModuleSWhois(), ModuleTaxonomy::ModuleTaxonomy(), ModuleTestCommand::ModuleTestCommand(), ModuleTimedBans::ModuleTimedBans(), ModuleTLine::ModuleTLine(), ModuleUninvite::ModuleUninvite(), ModuleUserIP::ModuleUserIP(), ModuleVHost::ModuleVHost(), and Modulewatch::Modulewatch().

00390 {
00391         if (!this->Parser->CreateCommand(f))
00392         {
00393                 ModuleException err("Command "+std::string(f->command)+" already exists.");
00394                 throw (err);
00395         }
00396 }

void InspIRCd::AddELine long  duration,
const std::string source,
const std::string reason,
const std::string hostmask
 

Add an eline.

Parameters:
duration How long the line should last
source Who set the line
reason The reason for the line
hostmask The hostmask to set the line against

Definition at line 475 of file modules.cpp.

References XLineManager::add_eline(), and XLines.

00476 {
00477         XLines->add_eline(duration, source.c_str(), reason.c_str(), hostmask.c_str());
00478 }

void InspIRCd::AddGLine long  duration,
const std::string source,
const std::string reason,
const std::string hostmask
 

Add a gline and apply it.

Parameters:
duration How long the line should last
source Who set the line
reason The reason for the line
hostmask The hostmask to set the line against

Definition at line 451 of file modules.cpp.

References XLineManager::add_gline(), APPLY_GLINES, XLineManager::apply_lines(), and XLines.

00452 {
00453         XLines->add_gline(duration, source.c_str(), reason.c_str(), hostmask.c_str());
00454         XLines->apply_lines(APPLY_GLINES);
00455 }

void InspIRCd::AddGlobalClone userrec user  ) 
 

Add a user to the global clone map.

Parameters:
user The user to add

Definition at line 1261 of file inspircd.cpp.

References userrec::GetIPString(), and global_clones.

Referenced by userrec::AddClient(), ModuleCgiIRC::CheckIdent(), ModuleCgiIRC::CheckPass(), TreeSocket::IntroduceClient(), and ModuleCgiIRC::OnUserConnect().

01262 {
01263         clonemap::iterator y = global_clones.find(user->GetIPString());
01264         if (y != global_clones.end())
01265                 y->second++;
01266         else
01267                 global_clones[user->GetIPString()] = 1;
01268 }

void InspIRCd::AddKLine long  duration,
const std::string source,
const std::string reason,
const std::string hostmask
 

Add a kline and apply it.

Parameters:
duration How long the line should last
source Who set the line
reason The reason for the line
hostmask The hostmask to set the line against

Definition at line 469 of file modules.cpp.

References XLineManager::add_kline(), APPLY_KLINES, XLineManager::apply_lines(), and XLines.

00470 {
00471         XLines->add_kline(duration, source.c_str(), reason.c_str(), hostmask.c_str());
00472         XLines->apply_lines(APPLY_KLINES);
00473 }

void InspIRCd::AddLocalClone userrec user  ) 
 

Add a user to the local clone map.

Parameters:
user The user to add

Definition at line 1252 of file inspircd.cpp.

References userrec::GetIPString(), and local_clones.

Referenced by userrec::AddClient(), ModuleCgiIRC::CheckIdent(), ModuleCgiIRC::CheckPass(), and ModuleCgiIRC::OnUserConnect().

01253 {
01254         clonemap::iterator x = local_clones.find(user->GetIPString());
01255         if (x != local_clones.end())
01256                 x->second++;
01257         else
01258                 local_clones[user->GetIPString()] = 1;
01259 }

bool InspIRCd::AddMode ModeHandler mh,
const unsigned char  modechar
 

Add a new mode to this server's mode parser.

Parameters:
mh The modehandler to add
modechar The mode character this modehandler handles
Returns:
True if the mode handler was added

Definition at line 424 of file modules.cpp.

References ModeParser::AddMode(), and Modes.

Referenced by ModuleAuditorium::ModuleAuditorium(), ModuleBanException::ModuleBanException(), ModuleBlockCAPS::ModuleBlockCAPS(), ModuleBlockColour::ModuleBlockColour(), ModuleBotMode::ModuleBotMode(), ModuleCensor::ModuleCensor(), ModuleChanFilter::ModuleChanFilter(), ModuleChanProtect::ModuleChanProtect(), ModuleCloaking::ModuleCloaking(), ModuleDeaf::ModuleDeaf(), ModuleHelpop::ModuleHelpop(), ModuleHideChans::ModuleHideChans(), ModuleHideOper::ModuleHideOper(), ModuleInvisible::ModuleInvisible(), ModuleInviteException::ModuleInviteException(), ModuleJoinFlood::ModuleJoinFlood(), ModuleKickNoRejoin::ModuleKickNoRejoin(), ModuleKnock::ModuleKnock(), ModuleMsgFlood::ModuleMsgFlood(), ModuleNickFlood::ModuleNickFlood(), ModuleNoCTCP::ModuleNoCTCP(), ModuleNoInvite::ModuleNoInvite(), ModuleNoKicks::ModuleNoKicks(), ModuleNoNickChange::ModuleNoNickChange(), ModuleNoNotice::ModuleNoNotice(), ModuleOperChans::ModuleOperChans(), ModulePrivacyMode::ModulePrivacyMode(), ModuleRedirect::ModuleRedirect(), ModuleServices::ModuleServices(), ModuleServicesAccount::ModuleServicesAccount(), ModuleShowwhois::ModuleShowwhois(), ModuleSSLModes::ModuleSSLModes(), ModuleStripColor::ModuleStripColor(), and ModuleChanProtect::OnRehash().

00425 {
00426         return this->Modes->AddMode(mh,mode);
00427 }

bool InspIRCd::AddModeWatcher ModeWatcher mw  ) 
 

Add a new mode watcher to this server's mode parser.

Parameters:
mw The modewatcher to add
Returns:
True if the modewatcher was added

Definition at line 429 of file modules.cpp.

References ModeParser::AddModeWatcher(), and Modes.

Referenced by ModuleBanRedirect::ModuleBanRedirect(), and ModuleInvisible::ModuleInvisible().

00430 {
00431         return this->Modes->AddModeWatcher(mw);
00432 }

void InspIRCd::AddQLine long  duration,
const std::string source,
const std::string reason,
const std::string nickname
 

Add a qline and apply it.

Parameters:
duration How long the line should last
source Who set the line
reason The reason for the line
nickname The nickmask to set the line against

Definition at line 457 of file modules.cpp.

References XLineManager::add_qline(), XLineManager::apply_lines(), APPLY_QLINES, and XLines.

00458 {
00459         XLines->add_qline(duration, source.c_str(), reason.c_str(), nickname.c_str());
00460         XLines->apply_lines(APPLY_QLINES);
00461 }

bool InspIRCd::AddResolver Resolver r,
bool  cached
 

Add a dns Resolver class to this server's active set.

Parameters:
r The resolver to add
cached If this value is true, then the cache will be searched for the DNS result, immediately. If the value is false, then a request will be sent to the nameserver, and the result will not be immediately available. You should usually use the boolean value which you passed to the Resolver constructor, which Resolver will set appropriately depending on if cached results are available and haven't expired. It is however safe to force this value to false, forcing a remote DNS lookup, but not an update of the cache.
Returns:
True if the operation completed successfully. Note that if this method returns true, you should not attempt to access the resolver class you pass it after this call, as depending upon the request given, the object may be deleted!

Definition at line 439 of file modules.cpp.

References DNS::AddResolverClass(), and Res.

Referenced by ModuleCgiIRC::CheckIdent(), ModuleCgiIRC::CheckPass(), ModuleSpanningTree::ConnectServer(), SecurityIPResolver::OnError(), ServernameResolver::OnError(), UserResolver::OnLookupComplete(), ModuleDNSBL::OnUserRegister(), ModulePgSQL::ReadConf(), SpanningTreeUtilities::ReadConfiguration(), SpanningTreeUtilities::RefreshIPCache(), and userrec::StartDNSLookup().

00440 {
00441         if (!cached)
00442                 return this->Res->AddResolverClass(r);
00443         else
00444         {
00445                 r->TriggerCachedResult();
00446                 delete r;
00447                 return true;
00448         }
00449 }

void InspIRCd::AddServerName const std::string servername  ) 
 

Adds a server name to the list of servers we've seen.

Parameters:
The servername to add

Definition at line 180 of file inspircd.cpp.

References servernames.

Referenced by InspIRCd().

00181 {
00182         servernamelist::iterator itr = servernames.begin();
00183         for(; itr != servernames.end(); ++itr)
00184                 if(**itr == servername)
00185                         return;
00186 
00187         string * ns = new string(servername);
00188         servernames.push_back(ns);
00189 }

void InspIRCd::AddZLine long  duration,
const std::string source,
const std::string reason,
const std::string ipaddr
 

Add a zline and apply it.

Parameters:
duration How long the line should last
source Who set the line
reason The reason for the line
ipaddr The ip-mask to set the line against

Definition at line 463 of file modules.cpp.

References XLineManager::add_zline(), XLineManager::apply_lines(), APPLY_ZLINES, and XLines.

00464 {
00465         XLines->add_zline(duration, source.c_str(), reason.c_str(), ipaddr.c_str());
00466         XLines->apply_lines(APPLY_ZLINES);
00467 }

bool InspIRCd::AllModulesReportReady userrec user  )  [private]
 

Returns true when all modules have done pre-registration checks on a user.

Parameters:
user The user to verify
Returns:
True if all modules have finished checking this user

Definition at line 1216 of file inspircd.cpp.

References Config, GetModuleCount(), ServerConfig::global_implementation, I_OnCheckReady, ServerConfig::implement_lists, and modules.

Referenced by DoBackgroundUserStuff().

01217 {
01218         if (!Config->global_implementation[I_OnCheckReady])
01219                 return true;
01220 
01221         for (int i = 0; i <= this->GetModuleCount(); i++)
01222         {
01223                 if (Config->implement_lists[i][I_OnCheckReady])
01224                 {
01225                         if (!modules[i]->OnCheckReady(user))
01226                                 return false;
01227                 }
01228         }
01229         return true;
01230 }

int InspIRCd::BindPorts bool  bail,
int &  found_ports,
FailedPortList failed_ports
 

Bind all ports specified in the configuration file.

Parameters:
bail True if the function should bail back to the shell on failure
found_ports The actual number of ports found in the config, as opposed to the number actually bound
Returns:
The number of ports actually bound without error

Definition at line 474 of file socket.cpp.

References Config, ServerConfig::config_data, ServerConfig::ConfValue(), ConvToStr(), DEFAULT, EventHandler::GetFd(), irc::portparser::GetToken(), Log(), MAXBUF, and ServerConfig::ports.

Referenced by InspIRCd(), and ServerConfig::Read().

00475 {
00476         char configToken[MAXBUF], Addr[MAXBUF], Type[MAXBUF];
00477         int bound = 0;
00478         bool started_with_nothing = (Config->ports.size() == 0);
00479         std::vector<std::pair<std::string, int> > old_ports;
00480 
00481         /* XXX: Make a copy of the old ip/port pairs here */
00482         for (std::vector<ListenSocket*>::iterator o = Config->ports.begin(); o != Config->ports.end(); ++o)
00483                 old_ports.push_back(make_pair((*o)->GetIP(), (*o)->GetPort()));
00484 
00485         for (int count = 0; count < Config->ConfValueEnum(Config->config_data, "bind"); count++)
00486         {
00487                 Config->ConfValue(Config->config_data, "bind", "port", count, configToken, MAXBUF);
00488                 Config->ConfValue(Config->config_data, "bind", "address", count, Addr, MAXBUF);
00489                 Config->ConfValue(Config->config_data, "bind", "type", count, Type, MAXBUF);
00490 
00491                 if ((!*Type) || (!strcmp(Type,"clients")))
00492                 {
00493                         irc::portparser portrange(configToken, false);
00494                         int portno = -1;
00495                         while ((portno = portrange.GetToken()))
00496                         {
00497                                 if (*Addr == '*')
00498                                         *Addr = 0;
00499 
00500                                 bool skip = false;
00501                                 for (std::vector<ListenSocket*>::iterator n = Config->ports.begin(); n != Config->ports.end(); ++n)
00502                                 {
00503                                         if (((*n)->GetIP() == Addr) && ((*n)->GetPort() == portno))
00504                                         {
00505                                                 skip = true;
00506                                                 /* XXX: Here, erase from our copy of the list */
00507                                                 for (std::vector<std::pair<std::string, int> >::iterator k = old_ports.begin(); k != old_ports.end(); ++k)
00508                                                 {
00509                                                         if ((k->first == Addr) && (k->second == portno))
00510                                                         {
00511                                                                 old_ports.erase(k);
00512                                                                 break;
00513                                                         }
00514                                                 }
00515                                         }
00516                                 }
00517                                 if (!skip)
00518                                 {
00519                                         ListenSocket* ll = new ListenSocket(this, portno, Addr);
00520                                         if (ll->GetFd() > -1)
00521                                         {
00522                                                 bound++;
00523                                                 Config->ports.push_back(ll);
00524                                         }
00525                                         else
00526                                         {
00527                                                 failed_ports.push_back(std::make_pair((*Addr ? Addr : "*") + std::string(":") + ConvToStr(portno), strerror(errno)));
00528                                         }
00529                                         ports_found++;
00530                                 }
00531                         }
00532                 }
00533         }
00534 
00535         /* XXX: Here, anything left in our copy list, close as removed */
00536         if (!started_with_nothing)
00537         {
00538                 for (size_t k = 0; k < old_ports.size(); ++k)
00539                 {
00540                         for (std::vector<ListenSocket*>::iterator n = Config->ports.begin(); n != Config->ports.end(); ++n)
00541                         {
00542                                 if (((*n)->GetIP() == old_ports[k].first) && ((*n)->GetPort() == old_ports[k].second))
00543                                 {
00544                                         this->Log(DEFAULT,"Port binding %s:%d was removed from the config file, closing.", old_ports[k].first.c_str(), old_ports[k].second);
00545                                         delete *n;
00546                                         Config->ports.erase(n);
00547                                         break;
00548                                 }
00549                         }
00550                 }
00551         }
00552 
00553         return bound;
00554 }

bool InspIRCd::BindSocket int  sockfd,
int  port,
char *  addr,
bool  dolisten = true
 

Binds a socket on an already open file descriptor.

Parameters:
sockfd A valid file descriptor of an open socket
port The port number to bind to
addr The address to bind to (IP only)
Returns:
True if the port was bound successfully

Definition at line 324 of file socket.cpp.

References Config, DEBUG, DEFAULT, Log(), ServerConfig::MaxConn, irc::sockets::NonBlocking(), and server.

Referenced by InspSocket::InspSocket(), ListenSocket::ListenSocket(), and DNS::Rehash().

00325 {
00326         /* We allocate 2 of these, because sockaddr_in6 is larger than sockaddr (ugh, hax) */
00327         sockaddr* server = new sockaddr[2];
00328         memset(server,0,sizeof(sockaddr)*2);
00329 
00330         int ret, size;
00331 
00332         if (*addr == '*')
00333                 *addr = 0;
00334 
00335 #ifdef IPV6
00336         if (*addr)
00337         {
00338                 /* There is an address here. Is it ipv6? */
00339                 if (strchr(addr,':'))
00340                 {
00341                         /* Yes it is */
00342                         in6_addr addy;
00343                         if (inet_pton(AF_INET6, addr, &addy) < 1)
00344                         {
00345                                 delete[] server;
00346                                 return false;
00347                         }
00348 
00349                         ((sockaddr_in6*)server)->sin6_family = AF_INET6;
00350                         memcpy(&(((sockaddr_in6*)server)->sin6_addr), &addy, sizeof(in6_addr));
00351                         ((sockaddr_in6*)server)->sin6_port = htons(port);
00352                         size = sizeof(sockaddr_in6);
00353                 }
00354                 else
00355                 {
00356                         /* No, its not */
00357                         in_addr addy;
00358                         if (inet_pton(AF_INET, addr, &addy) < 1)
00359                         {
00360                                 delete[] server;
00361                                 return false;
00362                         }
00363 
00364                         ((sockaddr_in*)server)->sin_family = AF_INET;
00365                         ((sockaddr_in*)server)->sin_addr = addy;
00366                         ((sockaddr_in*)server)->sin_port = htons(port);
00367                         size = sizeof(sockaddr_in);
00368                 }
00369         }
00370         else
00371         {
00372                 if (port == -1)
00373                 {
00374                         /* Port -1: Means UDP IPV4 port binding - Special case
00375                          * used by DNS engine.
00376                          */
00377                         ((sockaddr_in*)server)->sin_family = AF_INET;
00378                         ((sockaddr_in*)server)->sin_addr.s_addr = htonl(INADDR_ANY);
00379                         ((sockaddr_in*)server)->sin_port = 0;
00380                         size = sizeof(sockaddr_in);
00381                 }
00382                 else
00383                 {
00384                         /* Theres no address here, default to ipv6 bind to all */
00385                         ((sockaddr_in6*)server)->sin6_family = AF_INET6;
00386                         memset(&(((sockaddr_in6*)server)->sin6_addr), 0, sizeof(in6_addr));
00387                         ((sockaddr_in6*)server)->sin6_port = htons(port);
00388                         size = sizeof(sockaddr_in6);
00389                 }
00390         }
00391 #else
00392         /* If we aren't built with ipv6, the choice becomes simple */
00393         ((sockaddr_in*)server)->sin_family = AF_INET;
00394         if (*addr)
00395         {
00396                 /* There is an address here. */
00397                 in_addr addy;
00398                 if (inet_pton(AF_INET, addr, &addy) < 1)
00399                 {
00400                         delete[] server;
00401                         return false;
00402                 }
00403                 ((sockaddr_in*)server)->sin_addr = addy;
00404         }
00405         else
00406         {
00407                 /* Bind ipv4 to all */
00408                 ((sockaddr_in*)server)->sin_addr.s_addr = htonl(INADDR_ANY);
00409         }
00410         /* Bind ipv4 port number */
00411         ((sockaddr_in*)server)->sin_port = htons(port);
00412         size = sizeof(sockaddr_in);
00413 #endif
00414         ret = bind(sockfd, server, size);
00415         delete[] server;
00416 
00417         if (ret < 0)
00418         {
00419                 return false;
00420         }
00421         else
00422         {
00423                 if (dolisten)
00424                 {
00425                         if (listen(sockfd, Config->MaxConn) == -1)
00426                         {
00427                                 this->Log(DEFAULT,"ERROR in listen(): %s",strerror(errno));
00428                                 return false;
00429                         }
00430                         else
00431                         {
00432                                 this->Log(DEBUG,"New socket binding for %d with listen: %s:%d", sockfd, addr, port);
00433                                 NonBlocking(sockfd);
00434                                 return true;
00435                         }
00436                 }
00437                 else
00438                 {
00439                         this->Log(DEBUG,"New socket binding for %d without listen: %s:%d", sockfd, addr, port);
00440                         return true;
00441                 }
00442         }
00443 }

void InspIRCd::BuildISupport  ) 
 

Build the ISUPPORT string by triggering all modules On005Numeric events.

Definition at line 850 of file inspircd.cpp.

References ServerConfig::AllowHalfop, ModeParser::BuildPrefixes(), ModeParser::ChanModes(), Config, ServerConfig::data005, FOREACH_MOD_I, I_On005Numeric, MAXAWAY, ServerConfig::MaxChans, MAXKICK, MAXMODES, ServerConfig::MaxTargets, MAXTOPIC, Modes, ServerConfig::Network, NICKMAX, and ServerConfig::Update005().

Referenced by cmd_rehash::Handle(), InspIRCd(), LoadModule(), Rehash(), and UnloadModule().

00851 {
00852         // the neatest way to construct the initial 005 numeric, considering the number of configure constants to go in it...
00853         std::stringstream v;
00854         v << "WALLCHOPS WALLVOICES MODES=" << MAXMODES-1 << " CHANTYPES=# PREFIX=" << this->Modes->BuildPrefixes() << " MAP MAXCHANNELS=" << Config->MaxChans << " MAXBANS=60 VBANLIST NICKLEN=" << NICKMAX;
00855         v << " CASEMAPPING=rfc1459 STATUSMSG=@" << (this->Config->AllowHalfop ? "%" : "") << "+ CHARSET=ascii TOPICLEN=" << MAXTOPIC << " KICKLEN=" << MAXKICK << " MAXTARGETS=" << Config->MaxTargets;
00856         v << " AWAYLEN=" << MAXAWAY << " CHANMODES=" << this->Modes->ChanModes() << " FNC NETWORK=" << Config->Network << " MAXPARA=32 ELIST=MU";
00857         Config->data005 = v.str();
00858         FOREACH_MOD_I(this,I_On005Numeric,On005Numeric(Config->data005));
00859         Config->Update005();
00860 }

CmdResult InspIRCd::CallCommandHandler const std::string commandname,
const char **  parameters,
int  pcnt,
userrec user
 

Call the handler for a given command.

Parameters:
commandname The command whos handler you wish to call
parameters The mode parameters
pcnt The number of items you have given in the first parameter
user The user to execute the command as
Returns:
True if the command handler was called successfully

Definition at line 379 of file modules.cpp.

References CommandParser::CallHandler(), and Parser.

Referenced by TreeSocket::ForceMode(), userrec::FullConnect(), and cmd_tban::Handle().

00380 {
00381         return this->Parser->CallHandler(commandname,parameters,pcnt,user);
00382 }

long InspIRCd::ChannelCount  ) 
 

Return a count of channels on the network.

Returns:
The number of channels

Definition at line 345 of file helperfuncs.cpp.

References chanlist.

Referenced by cmd_lusers::Handle(), and ModuleSpanningTree::HandleLusers().

00346 {
00347         return chanlist->size();
00348 }

void InspIRCd::CheckDie  ) 
 

Check for a 'die' tag in the config file, and abort if found.

Returns:
Depending on the configuration, this function may never return

Definition at line 483 of file helperfuncs.cpp.

References Config, DEFAULT, ServerConfig::DieValue, Exit(), EXIT_STATUS_DIETAG, and Log().

Referenced by InspIRCd().

00484 {
00485         if (*Config->DieValue)
00486         {
00487                 printf("WARNING: %s\n\n",Config->DieValue);
00488                 this->Log(DEFAULT,"Died because of <die> tag: %s",Config->DieValue);
00489                 Exit(EXIT_STATUS_DIETAG);
00490         }
00491 }

void InspIRCd::CheckRoot  ) 
 

Check we aren't running as root, and exit if we are.

Returns:
Depending on the configuration, this function may never return

Definition at line 473 of file helperfuncs.cpp.

References DEFAULT, Exit(), EXIT_STATUS_ROOT, and Log().

Referenced by InspIRCd().

00474 {
00475         if (geteuid() == 0)
00476         {
00477                 printf("WARNING!!! You are running an irc server as ROOT!!! DO NOT DO THIS!!!\n\n");
00478                 this->Log(DEFAULT,"Cant start as root");
00479                 Exit(EXIT_STATUS_ROOT);
00480         }
00481 }

void InspIRCd::Cleanup  ) 
 

Prepare the ircd for restart or shutdown.

This function unloads all modules which can be unloaded, closes all open sockets, and closes the logfile.

Definition at line 225 of file inspircd.cpp.

References FileLogger::Close(), Config, GetModuleCount(), local_users, Logger, ServerConfig::module_names, ServerConfig::ports, servernames, and UnloadModule().

Referenced by Exit(), and Restart().

00226 {
00227         std::vector<std::string> mymodnames;
00228         int MyModCount = this->GetModuleCount();
00229 
00230         if (Config)
00231         {
00232                 for (unsigned int i = 0; i < Config->ports.size(); i++)
00233                 {
00234                         /* This calls the constructor and closes the listening socket */
00235                         delete Config->ports[i];
00236                 }
00237 
00238                 Config->ports.clear();
00239         }
00240 
00241         /* Close all client sockets, or the new process inherits them */
00242         for (std::vector<userrec*>::const_iterator i = this->local_users.begin(); i != this->local_users.end(); i++)
00243         {
00244                 (*i)->SetWriteError("Server shutdown");
00245                 (*i)->CloseSocket();
00246         }
00247 
00248         /* We do this more than once, so that any service providers get a
00249          * chance to be unhooked by the modules using them, but then get
00250          * a chance to be removed themsleves.
00251          */
00252         for (int tries = 0; tries < 3; tries++)
00253         {
00254                 MyModCount = this->GetModuleCount();
00255                 mymodnames.clear();
00256 
00257                 if (MyModCount)
00258                 {
00259                         /* Unload all modules, so they get a chance to clean up their listeners */
00260                         for (int j = 0; j <= MyModCount; j++)
00261                                 mymodnames.push_back(Config->module_names[j]);
00262 
00263                         for (int k = 0; k <= MyModCount; k++)
00264                                 this->UnloadModule(mymodnames[k].c_str());
00265                 }
00266         }
00267 
00268         /* Close logging */
00269         if (this->Logger)
00270                 this->Logger->Close();
00271 
00272         /* Cleanup Server Names */
00273         for(servernamelist::iterator itr = servernames.begin(); itr != servernames.end(); ++itr)
00274                 delete (*itr);
00275 
00276 #ifdef WINDOWS
00277         /* WSACleanup */
00278         WSACleanup();
00279 #endif
00280 }

void InspIRCd::CloseLog  ) 
 

Close the currently open log file.

Definition at line 365 of file inspircd.cpp.

References FileLogger::Close(), and Logger.

Referenced by cmd_rehash::Handle(), and Rehash().

00366 {
00367         if (this->Logger)
00368                 this->Logger->Close();
00369 }

bool InspIRCd::DaemonSeed  )  [private]
 

Daemonize the ircd and close standard input/output streams.

Returns:
True if the program daemonized succesfully

Definition at line 388 of file inspircd.cpp.

References DEFAULT, Exit(), Log(), printf_c, and QuickExit().

00389 {
00390 #ifdef WINDOWS
00391         printf_c("InspIRCd Process ID: \033[1;32m%lu\033[0m\n", GetCurrentProcessId());
00392         return true;
00393 #else
00394         signal(SIGTERM, InspIRCd::QuickExit);
00395 
00396         int childpid;
00397         if ((childpid = fork ()) < 0)
00398                 return false;
00399         else if (childpid > 0)
00400         {
00401                 /* We wait here for the child process to kill us,
00402                  * so that the shell prompt doesnt come back over
00403                  * the output.
00404                  * Sending a kill with a signal of 0 just checks
00405                  * if the child pid is still around. If theyre not,
00406                  * they threw an error and we should give up.
00407                  */
00408                 while (kill(childpid, 0) != -1)
00409                         sleep(1);
00410                 exit(0);
00411         }
00412         setsid ();
00413         umask (007);
00414         printf("InspIRCd Process ID: \033[1;32m%lu\033[0m\n",(unsigned long)getpid());
00415 
00416         signal(SIGTERM, InspIRCd::Exit);
00417 
00418         rlimit rl;
00419         if (getrlimit(RLIMIT_CORE, &rl) == -1)
00420         {
00421                 this->Log(DEFAULT,"Failed to getrlimit()!");
00422                 return false;
00423         }
00424         else
00425         {
00426                 rl.rlim_cur = rl.rlim_max;
00427                 if (setrlimit(RLIMIT_CORE, &rl) == -1)
00428                         this->Log(DEFAULT,"setrlimit() failed, cannot increase coredump size.");
00429         }
00430 
00431         return true;
00432 #endif
00433 }

bool InspIRCd::DelELine const std::string hostmask  ) 
 

Delete an eline.

Parameters:
hostmask The kline to delete
Returns:
True if the item was removed

Definition at line 500 of file modules.cpp.

References XLineManager::del_eline(), and XLines.

00501 {
00502         return XLines->del_eline(hostmask.c_str());
00503 }

bool InspIRCd::DelGLine const std::string hostmask  ) 
 

Delete a gline.

Parameters:
hostmask The gline to delete
Returns:
True if the item was removed

Definition at line 480 of file modules.cpp.

References XLineManager::del_gline(), and XLines.

00481 {
00482         return XLines->del_gline(hostmask.c_str());
00483 }

bool InspIRCd::DelKLine const std::string hostmask  ) 
 

Delete a kline.

Parameters:
hostmask The kline to delete
Returns:
True if the item was removed

Definition at line 495 of file modules.cpp.

References XLineManager::del_kline(), and XLines.

00496 {
00497         return XLines->del_kline(hostmask.c_str());
00498 }

bool InspIRCd::DelModeWatcher ModeWatcher mw  ) 
 

Delete a mode watcher from this server's mode parser.

Parameters:
mw The modewatcher to delete
Returns:
True if the modewatcher was deleted

Definition at line 434 of file modules.cpp.

References ModeParser::DelModeWatcher(), and Modes.

00435 {
00436         return this->Modes->DelModeWatcher(mw);
00437 }

bool InspIRCd::DelQLine const std::string nickname  ) 
 

Delete a qline.

Parameters:
nickname The qline to delete
Returns:
True if the item was removed

Definition at line 485 of file modules.cpp.

References XLineManager::del_qline(), and XLines.

00486 {
00487         return XLines->del_qline(nickname.c_str());
00488 }

bool InspIRCd::DelZLine const std::string ipaddr  ) 
 

Delete a zline.

Parameters:
ipaddr The zline to delete
Returns:
True if the item was removed

Definition at line 490 of file modules.cpp.

References XLineManager::del_zline(), and XLines.

00491 {
00492         return XLines->del_zline(ipaddr.c_str());
00493 }

void InspIRCd::DoBackgroundUserStuff time_t  TIME  )  [private]
 

Perform background user events such as PING checks.

Parameters:
TIME the current time

Definition at line 199 of file userprocess.cpp.

References AllModulesReportReady(), Config, userrec::dns_done, ServerConfig::dns_timeout, userrec::FullConnect(), userrec::GetIPString(), connection::lastping, local_users, MAXBUF, next_call, connection::nping, userrec::pingmax, userrec::QuitUser(), REG_ALL, REG_NICKUSER, connection::registered, connection::signon, stats, serverstats::statsDnsBad, Time(), userrec::timeout, userrec::Write(), and userrec::WriteServ().

Referenced by DoOneIteration().

00200 {
00201         /* Is it time yet? */
00202         if (TIME < next_call)
00203                 return;
00204         else
00205         {
00206                 /* Time we actually need to call this again */
00207                 const time_t DUMMY_VALUE = 32768;
00208                 next_call = TIME + DUMMY_VALUE;
00209 
00210                 /* XXX: IT IS NOT SAFE TO USE AN ITERATOR HERE. DON'T EVEN THINK ABOUT IT. */
00211                 for (unsigned long count2 = 0; count2 != this->local_users.size(); count2++)
00212                 {
00213                         if (count2 >= this->local_users.size())
00214                                 break;
00215 
00216                         userrec* curr = this->local_users[count2];
00217 
00218                         if (curr)
00219                         {
00220                                 /*
00221                                  * registration timeout -- didnt send USER/NICK/HOST
00222                                  * in the time specified in their connection class.
00223                                  */
00224                                 if ((TIME > curr->timeout) && (curr->registered != REG_ALL))
00225                                 {
00226                                         userrec::QuitUser(this, curr, "Registration timeout");
00227                                         continue;
00228                                 }
00229                                 else
00230                                 {
00231                                         if ((curr->registered != REG_ALL) && (next_call > (time_t)curr->timeout))
00232                                                 next_call = curr->timeout;
00233                                 }
00234 
00235                                 /*
00236                                  * user has signed on with USER/NICK/PASS, and dns has completed, all the modules
00237                                  * say this user is ok to proceed, fully connect them.
00238                                  */
00239                                 bool ready = curr->registered == REG_NICKUSER && AllModulesReportReady(curr);
00240                                 if ((TIME > curr->signon) && (ready))
00241                                 {
00242                                         if (!curr->dns_done)
00243                                         {
00244                                                 curr->WriteServ("NOTICE Auth :*** Could not resolve your hostname: Request timed out; using your IP address (%s) instead.", curr->GetIPString());
00245                                                 curr->dns_done = true;
00246                                         }
00247                                         this->stats->statsDnsBad++;
00248                                         curr->FullConnect();
00249                                         continue;
00250                                 }
00251                                 else
00252                                 {
00253                                         if ((curr->registered == REG_NICKUSER) && (ready) && (next_call > curr->signon))
00254                                                 next_call = curr->signon;
00255                                 }
00256 
00257                                 if ((curr->dns_done) && (curr->registered == REG_NICKUSER) && (ready))
00258                                 {
00259                                         curr->FullConnect();
00260                                         continue;
00261                                 }
00262                                 else
00263                                 {
00264                                         if ((curr->registered == REG_NICKUSER) && (ready) && (next_call > curr->signon + this->Config->dns_timeout))
00265                                                 next_call = curr->signon + this->Config->dns_timeout;
00266                                 }
00267 
00268                                 // It's time to PING this user. Send them a ping.
00269                                 if ((TIME > curr->nping) && (curr->registered == REG_ALL))
00270                                 {
00271                                         // This user didn't answer the last ping, remove them
00272                                         if (!curr->lastping)
00273                                         {
00274                                                 /* Everybody loves boobies. */
00275                                                 time_t time = this->Time(false) - (curr->nping - curr->pingmax);
00276                                                 char message[MAXBUF];
00277                                                 snprintf(message, MAXBUF, "Ping timeout: %ld second%s", (long)time, time > 1 ? "s" : "");
00278                                                 curr->lastping = 1;
00279                                                 curr->nping = TIME+curr->pingmax;
00280                                                 userrec::QuitUser(this, curr, message);
00281                                                 continue;
00282                                         }
00283                                         curr->Write("PING :%s",this->Config->ServerName);
00284                                         curr->lastping = 0;
00285                                         curr->nping = TIME+curr->pingmax;
00286                                 }
00287                                 else
00288                                 {
00289                                         if ((curr->registered == REG_ALL) && (next_call > curr->nping))
00290                                                 next_call = curr->nping;
00291                                 }
00292                         }
00293                 }
00294 
00295                 /* If theres nothing to do, trigger in the next second, something might come up */
00296                 time_t delta = next_call - TIME;
00297                 if (delta == DUMMY_VALUE)
00298                 {
00299                         next_call = TIME + 1;
00300                         delta = 1;
00301                 }
00302         }
00303 }

void InspIRCd::DoneWithInterface const std::string InterfaceName  ) 
 

Mark your module as finished with an interface.

If you used UseInterface() above, you should use this method when your module is finished with the interface (usually in its destructor) to allow the modules which implement the given interface to be unloaded.

Parameters:
InterfaceName The interface you are finished with using.

Definition at line 308 of file modules.cpp.

References Interfaces.

Referenced by ModuleCloaking::~ModuleCloaking(), ModuleOperHash::~ModuleOperHash(), ModulePgSQL::~ModulePgSQL(), ModuleSpanningTree::~ModuleSpanningTree(), ModuleSQL::~ModuleSQL(), ModuleSQLAuth::~ModuleSQLAuth(), ModuleSQLite3::~ModuleSQLite3(), ModuleSQLLog::~ModuleSQLLog(), and ModuleSQLOper::~ModuleSQLOper().

00309 {
00310         interfacelist::iterator iter = Interfaces.find(InterfaceName);
00311         if (iter != Interfaces.end())
00312                 iter->second.first--;
00313 }

void InspIRCd::DoOneIteration bool  process_module_sockets = true  ) 
 

Do one iteration of the mainloop.

Parameters:
process_module_sockets True if module sockets are to be processed this time around the event loop. The is the default.

Definition at line 1079 of file inspircd.cpp.

References CullList::Apply(), Config, SocketEngine::DispatchEvents(), DoBackgroundUserStuff(), XLineManager::expire_lines(), FOREACH_MOD_I, GlobalCulls, I_OnBackgroundTimer, I_OnGarbageCollect, InspSocketCull(), serverstats::LastCPU, LocalUserCount(), ServerConfig::nofork, OLDTIME, RehashUsersAndChans(), RUSAGE_SELF, s_signal, SE, SignalHandler(), startup_time, stats, serverstats::statsAccept, TimerManager::TickMissedTimers(), TimerManager::TickTimers(), Time(), TIME, Timers, WriteOpers(), and XLines.

Referenced by Run().

01080 {
01081 #ifndef WIN32
01082         static rusage ru;
01083 #else
01084         static time_t uptime;
01085         static struct tm * stime;
01086         static char window_title[100];
01087 #endif
01088 
01089         /* time() seems to be a pretty expensive syscall, so avoid calling it too much.
01090          * Once per loop iteration is pleanty.
01091          */
01092         OLDTIME = TIME;
01093         TIME = time(NULL);
01094 
01095         /* Run background module timers every few seconds
01096          * (the docs say modules shouldnt rely on accurate
01097          * timing using this event, so we dont have to
01098          * time this exactly).
01099          */
01100         if (TIME != OLDTIME)
01101         {
01102                 if (TIME < OLDTIME)
01103                         WriteOpers("*** \002EH?!\002 -- Time is flowing BACKWARDS in this dimension! Clock drifted backwards %d secs.",abs(OLDTIME-TIME));
01104                 if ((TIME % 3600) == 0)
01105                 {
01106                         this->RehashUsersAndChans();
01107                         FOREACH_MOD_I(this, I_OnGarbageCollect, OnGarbageCollect());
01108                 }
01109                 Timers->TickTimers(TIME);
01110                 this->DoBackgroundUserStuff(TIME);
01111 
01112                 if ((TIME % 5) == 0)
01113                 {
01114                         XLines->expire_lines();
01115                         FOREACH_MOD_I(this,I_OnBackgroundTimer,OnBackgroundTimer(TIME));
01116                         Timers->TickMissedTimers(TIME);
01117                 }
01118 #ifndef WIN32
01119                 /* Same change as in cmd_stats.cpp, use RUSAGE_SELF rather than '0' -- Om */
01120                 if (!getrusage(RUSAGE_SELF, &ru))
01121                 {
01122                         gettimeofday(&this->stats->LastSampled, NULL);
01123                         this->stats->LastCPU = ru.ru_utime;
01124                 }
01125 #else
01126                 CheckIPC(this);
01127 
01128                 if(Config->nofork)
01129                 {
01130                         uptime = Time() - startup_time;
01131                         stime = gmtime(&uptime);
01132                         snprintf(window_title, 100, "InspIRCd - %u clients, %u accepted connections - Up %u days, %.2u:%.2u:%.2u",
01133                                 LocalUserCount(), stats->statsAccept, stime->tm_yday, stime->tm_hour, stime->tm_min, stime->tm_sec);
01134                         SetConsoleTitle(window_title);
01135                 }
01136 #endif
01137         }
01138 
01139         /* Call the socket engine to wait on the active
01140          * file descriptors. The socket engine has everything's
01141          * descriptors in its list... dns, modules, users,
01142          * servers... so its nice and easy, just one call.
01143          * This will cause any read or write events to be
01144          * dispatched to their handlers.
01145          */
01146         SE->DispatchEvents();
01147 
01148         /* if any users was quit, take them out */
01149         GlobalCulls.Apply();
01150 
01151         /* If any inspsockets closed, remove them */
01152         this->InspSocketCull();
01153 
01154         if (this->s_signal)
01155         {
01156                 this->SignalHandler(s_signal);
01157                 this->s_signal = 0;
01158         }
01159 
01160 }

void InspIRCd::DoSocketTimeouts time_t  TIME  )  [private]
 

Iterate the list of InspSocket objects, removing ones which have timed out.

Parameters:
TIME the current time

void InspIRCd::DumpText userrec User,
const std::string LinePrefix,
stringstream &  TextStream
 

Dump text to a user target, splitting it appropriately to fit.

Parameters:
User the user to dump the text to
LinePrefix text to prefix each complete line with
TextStream the text to send to the user

Definition at line 403 of file modules.cpp.

References userrec::WriteServ().

Referenced by cmd_check::Handle().

00404 {
00405         std::string CompleteLine = LinePrefix;
00406         std::string Word;
00407         while (TextStream >> Word)
00408         {
00409                 if (CompleteLine.length() + Word.length() + 3 > 500)
00410                 {
00411                         User->WriteServ(CompleteLine);
00412                         CompleteLine = LinePrefix;
00413                 }
00414                 CompleteLine = CompleteLine + Word + " ";
00415         }
00416         User->WriteServ(CompleteLine);
00417 }

long InspIRCd::Duration const std::string str  ) 
 

Calculate a duration in seconds from a string in the form 1y2w3d4h6m5s.

Parameters:
str A string containing a time in the form 1y2w3d4h6m5s (one year, two weeks, three days, four hours, six minutes and five seconds)
Returns:
The total number of seconds

Definition at line 69 of file command_parse.cpp.

References duration_multi.

Referenced by cmd_tban::Handle(), cmd_svshold::Handle(), cmd_setidle::Handle(), cmd_filter::Handle(), cmd_dccallow::Handle(), cmd_cban::Handle(), cmd_zline::Handle(), cmd_qline::Handle(), cmd_kline::Handle(), cmd_gline::Handle(), cmd_eline::Handle(), ModuleFilterPCRE::OnRehash(), ModuleFilter::OnRehash(), ModuleDNSBL::ReadConf(), and ValidateWhoWas().

00070 {
00071         unsigned char multiplier = 0;
00072         long total = 0;
00073         long times = 1;
00074         long subtotal = 0;
00075 
00076         /* Iterate each item in the string, looking for number or multiplier */
00077         for (std::string::const_reverse_iterator i = str.rbegin(); i != str.rend(); ++i)
00078         {
00079                 /* Found a number, queue it onto the current number */
00080                 if ((*i >= '0') && (*i <= '9'))
00081                 {
00082                         subtotal = subtotal + ((*i - '0') * times);
00083                         times = times * 10;
00084                 }
00085                 else
00086                 {
00087                         /* Found something thats not a number, find out how much
00088                          * it multiplies the built up number by, multiply the total
00089                          * and reset the built up number.
00090                          */
00091                         if (subtotal)
00092                                 total += subtotal * duration_multi[multiplier];
00093 
00094                         /* Next subtotal please */
00095                         subtotal = 0;
00096                         multiplier = *i;
00097                         times = 1;
00098                 }
00099         }
00100         if (multiplier)
00101         {
00102                 total += subtotal * duration_multi[multiplier];
00103                 subtotal = 0;
00104         }
00105         /* Any trailing values built up are treated as raw seconds */
00106         return total + subtotal;
00107 }

void InspIRCd::EraseFactory int  j  )  [private]
 

Remove a ModuleFactory pointer.

Parameters:
j Index number of the ModuleFactory to remove

Definition at line 730 of file inspircd.cpp.

References factory.

Referenced by UnloadModule().

00731 {
00732         int v = 0;
00733         for (std::vector<ircd_module*>::iterator t = factory.begin(); t != factory.end(); t++)
00734         {
00735                 if (v == j)
00736                 {
00737                         delete *t;
00738                         factory.erase(t);
00739                         factory.push_back(NULL);
00740                         return;
00741                 }
00742                 v++;
00743         }
00744 }

void InspIRCd::EraseModule int  j  )  [private]
 

Remove a Module pointer.

Parameters:
j Index number of the Module to remove

Definition at line 746 of file inspircd.cpp.

References Config, DELETE(), ServerConfig::module_names, and modules.

Referenced by UnloadModule().

00747 {
00748         int v1 = 0;
00749         for (ModuleList::iterator m = modules.begin(); m!= modules.end(); m++)
00750         {
00751                 if (v1 == j)
00752                 {
00753                         DELETE(*m);
00754                         modules.erase(m);
00755                         modules.push_back(NULL);
00756                         break;
00757                 }
00758                 v1++;
00759         }
00760         int v2 = 0;
00761         for (std::vector<std::string>::iterator v = Config->module_names.begin(); v != Config->module_names.end(); v++)
00762         {
00763                 if (v2 == j)
00764                 {
00765                         Config->module_names.erase(v);
00766                         break;
00767                 }
00768                 v2++;
00769         }
00770 
00771 }

void InspIRCd::Exit int  status  )  [static]
 

Causes the server to exit after unloading modules and closing all open file descriptors.

Parameters:
The exit code to give to the operating system (See the ExitStatus enum for valid values)

Definition at line 212 of file inspircd.cpp.

References Cleanup(), ConvToStr(), and SendError().

Referenced by CheckDie(), CheckRoot(), DaemonSeed(), EPollEngine::EPollEngine(), cmd_die::Handle(), InspIRCd(), IOCPEngine::IOCPEngine(), KQueueEngine::KQueueEngine(), LoadAllModules(), PortsEngine::PortsEngine(), ServerConfig::ReportConfigError(), SignalHandler(), and WritePID().

00213 {
00214 #ifdef WINDOWS
00215         CloseIPC();
00216 #endif
00217         if (SI)
00218         {
00219                 SI->SendError("Exiting with status " + ConvToStr(status) + " (" + std::string(ExitCodes[status]) + ")");
00220                 SI->Cleanup();
00221         }
00222         exit (status);
00223 }

chanrec * InspIRCd::FindChan const char *  chan  ) 
 

Find a channel in the channels hash.

Parameters:
chan The channel to find
Returns:
A pointer to the channel, or NULL if the channel does not exist

Definition at line 259 of file helperfuncs.cpp.

References chanlist.

00260 {
00261         chan_hash::iterator iter = chanlist->find(chan);
00262 
00263         if (iter == chanlist->end())
00264                 /* Couldn't find it */
00265                 return NULL;
00266 
00267         return iter->second;
00268 }

chanrec * InspIRCd::FindChan const std::string chan  ) 
 

Find a channel in the channels hash.

Parameters:
chan The channel to find
Returns:
A pointer to the channel, or NULL if the channel does not exist

Definition at line 270 of file helperfuncs.cpp.

References chanlist.

Referenced by SpanningTreeUtilities::DoOneToAllButSenderRaw(), TreeSocket::ForceJoin(), TreeSocket::ForceMode(), TreeSocket::ForceTopic(), cmd_uninvite::Handle(), cmd_tban::Handle(), cmd_spynames::Handle(), cmd_sapart::Handle(), RemoveBase::Handle(), cmd_knock::Handle(), cmd_devoice::Handle(), cmd_cycle::Handle(), cmd_check::Handle(), cmd_who::Handle(), cmd_topic::Handle(), cmd_privmsg::Handle(), cmd_part::Handle(), cmd_notice::Handle(), cmd_names::Handle(), cmd_kick::Handle(), cmd_invite::Handle(), chanrec::JoinUser(), TreeSocket::MetaData(), ModuleTimedBans::OnBackgroundTimer(), ModuleSpanningTree::OnEvent(), ModuleHttpStats::OnEvent(), Redirect::OnModeChange(), ModuleRedirect::OnUserPreJoin(), ModuleBanRedirect::OnUserPreJoin(), ModeParser::Process(), TreeSocket::ProcessLine(), TreeSocket::RemoveStatus(), cmd_who::SendWhoLine(), and TreeSocket::ServicePart().

00271 {
00272         chan_hash::iterator iter = chanlist->find(chan);
00273 
00274         if (iter == chanlist->end())
00275                 /* Couldn't find it */
00276                 return NULL;
00277 
00278         return iter->second;
00279 }

userrec * InspIRCd::FindDescriptor int  socket  ) 
 

Find a username by their file descriptor.

It is preferred to use this over directly accessing the fd_ref_table array.

Parameters:
socket The file descriptor of a user
Returns:
A pointer to the user if the user exists locally on this descriptor

Definition at line 419 of file modules.cpp.

References SocketEngine::GetRef(), and SE.

Referenced by ModuleSSLOpenSSL::Handshake(), ModuleSSLGnuTLS::Handshake(), ModuleSSLOpenSSL::MakePollWrite(), ModuleSSLGnuTLS::MakePollWrite(), ModuleXMLSocket::OnRawSocketRead(), ModuleXMLSocket::OnRawSocketWrite(), and ModuleSSLGnuTLS::OnRequest().

00420 {
00421         return reinterpret_cast<userrec*>(this->SE->GetRef(socket));
00422 }

Module * InspIRCd::FindFeature const std::string FeatureName  ) 
 

Find a 'feature'.

There are two ways for a module to find another module it depends on. Either by name, using InspIRCd::FindModule, or by feature, using the InspIRCd::PublishFeature method. A feature is an arbitary string which identifies something this module can do. For example, if your module provides SSL support, but other modules provide SSL support too, all the modules supporting SSL should publish an identical 'SSL' feature. To find a module capable of providing the feature you want, simply call this method with the feature name you are looking for.

Parameters:
FeatureName The feature name you wish to obtain the module for
Returns:
A pointer to a valid module class on success, NULL on failure.

Definition at line 242 of file modules.cpp.

References Features.

Referenced by ModuleSQLOper::LookupOper(), ModuleSQLAuth::ModuleSQLAuth(), ModuleSQLLog::ModuleSQLLog(), and ModuleTestClient::OnBackgroundTimer().

00243 {
00244         featurelist::iterator iter = Features.find(FeatureName);
00245 
00246         if (iter == Features.end())
00247                 return NULL;
00248 
00249         return iter->second;
00250 }

modulelist * InspIRCd::FindInterface const std::string InterfaceName  ) 
 

Find an 'interface'.

An interface is a list of modules which all implement the same API.

Parameters:
InterfaceName The Interface you wish to obtain the module list of.
Returns:
A pointer to a deque of Module*, or NULL if the interface does not exist.

Definition at line 291 of file modules.cpp.

References Interfaces.

Referenced by ModuleOperHash::ModuleOperHash(), and SpanningTreeUtilities::SpanningTreeUtilities().

00292 {
00293         interfacelist::iterator iter = Interfaces.find(InterfaceName);
00294         if (iter == Interfaces.end())
00295                 return NULL;
00296         else
00297                 return &(iter->second.second);
00298 }

Module * InspIRCd::FindModule const std::string name  ) 
 

Find a module by name, and return a Module* to it.

This is preferred over iterating the module lists yourself.

Parameters:
name The module name to look up
Returns:
A pointer to the module, or NULL if the module cannot be found

Definition at line 538 of file modules.cpp.

References GetModuleCount(), and modules.

Referenced by TreeSocket::Capab(), TreeSocket::ComparePass(), RemoveBase::Handle(), TreeSocket::MakePass(), ModuleCloaking::ModuleCloaking(), ModuleSQLAuth::ModuleSQLAuth(), ModuleSQLLog::ModuleSQLLog(), ModuleSQLOper::ModuleSQLOper(), InvisibleMode::OnModeChange(), ModuleBanRedirect::OnRehash(), ModuleUHNames::OnUserList(), ModuleNamesX::OnUserList(), ModuleBanRedirect::OnUserPreJoin(), ModuleUHNames::Prioritize(), and TreeSocket::SendCapabilities().

00539 {
00540         for (int i = 0; i <= this->GetModuleCount(); i++)
00541         {
00542                 if (this->Config->module_names[i] == name)
00543                 {
00544                         return this->modules[i];
00545                 }
00546         }
00547         return NULL;
00548 }

userrec * InspIRCd::FindNick const char *  nick  ) 
 

Find a nickname in the nick hash.

Parameters:
nick The nickname to find
Returns:
A pointer to the user, or NULL if the user does not exist

Definition at line 248 of file helperfuncs.cpp.

References clientlist.

00249 {
00250         user_hash::iterator iter = clientlist->find(nick);
00251         
00252         if (iter == clientlist->end())
00253                 return NULL;
00254 
00255         return iter->second;
00256 }

userrec * InspIRCd::FindNick const std::string nick  ) 
 

Find a nickname in the nick hash.

Parameters:
nick The nickname to find
Returns:
A pointer to the user, or NULL if the user does not exist

Definition at line 237 of file helperfuncs.cpp.

References clientlist.

Referenced by cmd_watch::add_watch(), TreeSocket::Admin(), TreeSocket::ChangeHost(), TreeSocket::ChangeName(), SpanningTreeUtilities::DoOneToAllButSenderRaw(), FounderProtectBase::FindAndVerify(), TreeSocket::ForceJoin(), TreeSocket::ForceMode(), TreeSocket::ForceNick(), TreeSocket::ForceTopic(), cmd_userip::Handle(), cmd_uninvite::Handle(), cmd_taxonomy::Handle(), cmd_swhois::Handle(), cmd_sslinfo::Handle(), cmd_fingerprint::Handle(), cmd_saquit::Handle(), cmd_sapart::Handle(), cmd_sanick::Handle(), cmd_sajoin::Handle(), RemoveBase::Handle(), cmd_nickunlock::Handle(), cmd_nicklock::Handle(), cmd_dccallow::Handle(), cmd_chgname::Handle(), cmd_chgident::Handle(), cmd_chghost::Handle(), cmd_check::Handle(), cmd_zline::Handle(), cmd_whois::Handle(), cmd_userhost::Handle(), cmd_privmsg::Handle(), cmd_notice::Handle(), cmd_nick::Handle(), cmd_kline::Handle(), cmd_kill::Handle(), cmd_kick::Handle(), cmd_ison::Handle(), cmd_invite::Handle(), cmd_gline::Handle(), cmd_eline::Handle(), ModuleSpanningTree::HandleRemoteWhois(), TreeSocket::LocalPong(), TreeSocket::MetaData(), FounderProtectBase::ModeSet(), TreeSocket::Modules(), TreeSocket::Motd(), ModuleSpanningTree::OnEvent(), ModuleAlias::OnPreCommand(), TreeSocket::OperQuit(), TreeSocket::OperType(), ModeParser::Process(), TreeSocket::ProcessLine(), TreeSocket::Push(), TreeSocket::RemoteKill(), ModeParser::SanityChecks(), TreeSocket::ServiceJoin(), TreeSocket::ServicePart(), TreeSocket::Stats(), TreeSocket::Time(), and TreeSocket::Whois().

00238 {
00239         user_hash::iterator iter = clientlist->find(nick);
00240 
00241         if (iter == clientlist->end())
00242                 /* Couldn't find it */
00243                 return NULL;
00244 
00245         return iter->second;
00246 }

bool InspIRCd::FindServerName const std::string servername  ) 
 

Returns true if we've seen the given server name before.

Parameters:
The servername to find
Returns:
True if we've seen this server name before

Definition at line 203 of file inspircd.cpp.

References servernames.

Referenced by cmd_who::Handle().

00204 {
00205         servernamelist::iterator itr = servernames.begin();
00206         for(; itr != servernames.end(); ++itr)
00207                 if(**itr == servername)
00208                         return true;
00209         return false;
00210 }

const char * InspIRCd::FindServerNamePtr const std::string servername  ) 
 

Finds a cached char* pointer of a server name, This is used to optimize userrec by storing only the pointer to the name.

Parameters:
The servername to find
Returns:
A pointer to this name, gauranteed to never become invalid

Definition at line 191 of file inspircd.cpp.

References servernames.

Referenced by userrec::AddClient(), TreeSocket::IntroduceClient(), and userrec::userrec().

00192 {
00193         servernamelist::iterator itr = servernames.begin();
00194         for(; itr != servernames.end(); ++itr)
00195                 if(**itr == servername)
00196                         return (*itr)->c_str();
00197 
00198         servernames.push_back(new string(servername));
00199         itr = --servernames.end();
00200         return (*itr)->c_str();
00201 }

void InspIRCd::FloodQuitUser userrec current  ) 
 

Quit a user for excess flood, and if they are not fully registered yet, temporarily zline their IP.

Parameters:
current user to quit

Definition at line 23 of file userprocess.cpp.

References XLineManager::add_zline(), XLineManager::apply_lines(), APPLY_ZLINES, DEFAULT, userrec::GetIPString(), connection::host, userrec::ident, Log(), userrec::nick, REG_ALL, connection::registered, userrec::SetWriteError(), SNO, SnomaskManager::WriteToSnoMask(), and XLines.

Referenced by ProcessUser().

00024 {
00025         this->Log(DEFAULT,"Excess flood from: %s@%s", current->ident, current->host);
00026         this->SNO->WriteToSnoMask('f',"Excess flood from: %s%s%s@%s",
00027                         current->registered == REG_ALL ? current->nick : "",
00028                         current->registered == REG_ALL ? "!" : "", current->ident, current->host);
00029         current->SetWriteError("Excess flood");
00030         if (current->registered != REG_ALL)
00031         {
00032                 XLines->add_zline(120,this->Config->ServerName,"Flood from unregistered connection",current->GetIPString());
00033                 XLines->apply_lines(APPLY_ZLINES);
00034         }
00035 }

chanrec * InspIRCd::GetChannelIndex long  index  ) 
 

Return the channel whos index number matches that provided.

Parameters:
The index number of the channel to fetch
Returns:
A channel record, or NUll if index < 0 or index >= InspIRCd::ChannelCount()

Definition at line 363 of file modules.cpp.

References chanlist.

Referenced by ModuleSafeList::OnBufferFlushed().

00364 {
00365         int target = 0;
00366         for (chan_hash::iterator n = this->chanlist->begin(); n != this->chanlist->end(); n++, target++)
00367         {
00368                 if (index == target)
00369                         return n->second;
00370         }
00371         return NULL;
00372 }

std::pair< int, std::string > InspIRCd::GetInterfaceInstanceCount Module m  ) 
 

Return a pair saying how many other modules are currently using the interfaces provided by module m.

Parameters:
m The module to count usage for
Returns:
A pair, where the first value is the number of uses of the interface, and the second value is the interface name being used.

Definition at line 315 of file modules.cpp.

References Interfaces.

Referenced by UnloadModule().

00316 {
00317         for (interfacelist::iterator iter = Interfaces.begin(); iter != Interfaces.end(); iter++)
00318         {
00319                 for (modulelist::iterator x = iter->second.second.begin(); x != iter->second.second.end(); x++)
00320                 {
00321                         if (*x == m)
00322                         {
00323                                 return std::make_pair(iter->second.first, iter->first);
00324                         }
00325                 }
00326         }
00327         return std::make_pair(0, "");
00328 }

int InspIRCd::GetModuleCount  ) 
 

Get the total number of currently loaded modules.

Returns:
The number of loaded modules

Definition at line 1232 of file inspircd.cpp.

References ModCount.

Referenced by AllModulesReportReady(), Cleanup(), FindModule(), GetModuleName(), and TreeSocket::MyCapabilities().

01233 {
01234         return this->ModCount;
01235 }

const std::string & InspIRCd::GetModuleName Module m  ) 
 

Given a pointer to a Module, return its filename.

Parameters:
m The module pointer to identify
Returns:
The module name or an empty string

Definition at line 330 of file modules.cpp.

References Config, GetModuleCount(), and ServerConfig::module_names.

00331 {
00332         static std::string nothing; /* Prevent compiler warning */
00333 
00334         if (!this->GetModuleCount())
00335                 return nothing;
00336 
00337         for (int i = 0; i <= this->GetModuleCount(); i++)
00338         {
00339                 if (this->modules[i] == m)
00340                 {
00341                         return this->Config->module_names[i];
00342                 }
00343         }
00344         return nothing; /* As above */
00345 }

std::string InspIRCd::GetRevision  ) 
 

Returns the subversion revision ID of this ircd.

Returns:
The revision ID or an empty string

Definition at line 462 of file inspircd.cpp.

References REVISION.

00463 {
00464         return REVISION;
00465 }

std::string InspIRCd::GetServerDescription const char *  servername  ) 
 

Gets the GECOS (description) field of the given server.

If the servername is not that of the local server, the name is passed to handling modules which will attempt to determine the GECOS that bleongs to the given servername.

Parameters:
servername The servername to find the description of
Returns:
The description of this server, or of the local server

Definition at line 83 of file helperfuncs.cpp.

References Config, FOREACH_MOD_I, I_OnGetServerDescription, and ServerConfig::ServerDesc.

Referenced by do_whois().

00084 {
00085         std::string description;
00086 
00087         FOREACH_MOD_I(this,I_OnGetServerDescription,OnGetServerDescription(servername,description));
00088 
00089         if (!description.empty())
00090         {
00091                 return description;
00092         }
00093         else
00094         {
00095                 // not a remote server that can be found, it must be me.
00096                 return Config->ServerDesc;
00097         }
00098 }

int InspIRCd::GetTimeDelta  ) 
 

Get the time offset in seconds.

Returns:
The current time delta (in seconds)

Definition at line 1270 of file inspircd.cpp.

References time_delta.

Referenced by cmd_alltime::Handle().

01271 {
01272         return time_delta;
01273 }

std::string InspIRCd::GetVersionString  ) 
 

Returns the full version string of this ircd.

Returns:
The version string

Definition at line 709 of file inspircd.cpp.

References Config, ServerConfig::CustomVersion, SocketEngine::GetName(), MAXBUF, REVISION, SE, ServerConfig::ServerName, SYSTEM, and VERSION.

Referenced by cmd_version::Handle(), and TreeServer::TreeServer().

00710 {
00711         char versiondata[MAXBUF];
00712         char dnsengine[] = "singlethread-object";
00713 
00714         if (*Config->CustomVersion)
00715         {
00716                 snprintf(versiondata,MAXBUF,"InspIRCd-1.1 %s :%s",Config->ServerName,Config->CustomVersion);
00717         }
00718         else
00719         {
00720                 snprintf(versiondata,MAXBUF,"InspIRCd-1.1 %s :%s (%s) [FLAGS=%s,%s,%s]",Config->ServerName,SYSTEM,VERSION,REVISION,SE->GetName().c_str(),dnsengine);
00721         }
00722         return versiondata;
00723 }

bool InspIRCd::HostMatchesEveryone const std::string mask,
userrec user
 

Check if the given hostmask matches too many users, send errors to the given user.

Parameters:
mask A hostmask to match against
user A user to send error text to
Returns:
True if the host matches too many users

Definition at line 24 of file commands.cpp.

References clientlist, Config, ServerConfig::config_data, ServerConfig::ConfValue(), ServerConfig::ConfValueBool(), match(), MAXBUF, userrec::nick, strlcpy(), and WriteOpers().

Referenced by cmd_kline::Handle(), cmd_gline::Handle(), and cmd_eline::Handle().

00025 {
00026         char itrigger[MAXBUF];
00027         long matches = 0;
00028         
00029         if (!Config->ConfValue(Config->config_data, "insane","trigger", 0, itrigger, MAXBUF))
00030                 strlcpy(itrigger,"95.5",MAXBUF);
00031         
00032         if (Config->ConfValueBool(Config->config_data, "insane","hostmasks", 0))
00033                 return false;
00034         
00035         for (user_hash::iterator u = clientlist->begin(); u != clientlist->end(); u++)
00036         {
00037                 if ((match(u->second->MakeHost(),mask.c_str(),true)) || (match(u->second->MakeHostIP(),mask.c_str(),true)))
00038                 {
00039                         matches++;
00040                 }
00041         }
00042 
00043         if (!matches)
00044                 return false;
00045 
00046         float percent = ((float)matches / (float)clientlist->size()) * 100;
00047         if (percent > (float)atof(itrigger))
00048         {
00049                 WriteOpers("*** \2WARNING\2: %s tried to set a G/K/E line mask of %s, which covers %.2f%% of the network!",user->nick,mask.c_str(),percent);
00050                 return true;
00051         }
00052         return false;
00053 }

void InspIRCd::InspSocketCull  ) 
 

Force all InspSockets to be removed which are due to be culled.

Definition at line 1176 of file inspircd.cpp.

References SocketEngine::DelFd(), SE, and SocketCull.

Referenced by DoOneIteration(), SpanningTreeUtilities::ReadConfiguration(), ModuleHttpServer::~ModuleHttpServer(), and SpanningTreeUtilities::~SpanningTreeUtilities().

01177 {
01178         for (std::map<InspSocket*,InspSocket*>::iterator x = SocketCull.begin(); x != SocketCull.end(); ++x)
01179         {
01180                 SE->DelFd(x->second);
01181                 x->second->Close();
01182                 delete x->second;
01183         }
01184         SocketCull.clear();
01185 }

int InspIRCd::InvisibleUserCount  ) 
 

Return a count of invisible (umode +i) users only.

Returns:
The number of invisible users

Definition at line 327 of file helperfuncs.cpp.

References ModeCount().

Referenced by cmd_lusers::Handle(), and ModuleSpanningTree::HandleLusers().

00328 {
00329         return ModeCount('i');
00330 }

bool InspIRCd::IPMatchesEveryone const std::string ip,
userrec user
 

Check if the given IP mask matches too many users, send errors to the given user.

Parameters:
ip An ipmask to match against
user A user to send error text to
Returns:
True if the ip matches too many users

Definition at line 55 of file commands.cpp.

References clientlist, Config, ServerConfig::config_data, ServerConfig::ConfValue(), ServerConfig::ConfValueBool(), match(), MAXBUF, userrec::nick, strlcpy(), and WriteOpers().

Referenced by cmd_zline::Handle().

00056 {
00057         char itrigger[MAXBUF];
00058         long matches = 0;
00059         
00060         if (!Config->ConfValue(Config->config_data, "insane","trigger",0,itrigger,MAXBUF))
00061                 strlcpy(itrigger,"95.5",MAXBUF);
00062         
00063         if (Config->ConfValueBool(Config->config_data, "insane","ipmasks",0))
00064                 return false;
00065         
00066         for (user_hash::iterator u = clientlist->begin(); u != clientlist->end(); u++)
00067         {
00068                 if (match(u->second->GetIPString(),ip.c_str(),true))
00069                         matches++;
00070         }
00071 
00072         if (!matches)
00073                 return false;
00074 
00075         float percent = ((float)matches / (float)clientlist->size()) * 100;
00076         if (percent > (float)atof(itrigger))
00077         {
00078                 WriteOpers("*** \2WARNING\2: %s tried to set a Z line mask of %s, which covers %.2f%% of the network!",user->nick,ip.c_str(),percent);
00079                 return true;
00080         }
00081         return false;
00082 }

bool InspIRCd::IsChannel const char *  chname  ) 
 

Return true if a channel name is valid.

Parameters:
chname A channel name to verify
Returns:
True if the name is valid

Definition at line 358 of file helperfuncs.cpp.

References CHANMAX.

Referenced by BanRedirect::BeforeMode(), cmd_sajoin::Handle(), cmd_cban::Handle(), cmd_join::Handle(), Redirect::OnModeChange(), ModuleConnJoin::OnPostConnect(), and ModuleOperjoin::OnPostOper().

00359 {
00360         char *c;
00361 
00362         /* check for no name - don't check for !*chname, as if it is empty, it won't be '#'! */
00363         if (!chname || *chname != '#')
00364         {
00365                 return false;
00366         }
00367 
00368         c = (char *)chname + 1;
00369         while (*c)
00370         {
00371                 switch (*c)
00372                 {
00373                         case ' ':
00374                         case ',':
00375                         case 7:
00376                                 return false;
00377                 }
00378 
00379                 c++;
00380         }
00381                 
00382         /* too long a name - note funky pointer arithmetic here. */
00383         if ((c - chname) > CHANMAX)
00384         {
00385                         return false;
00386         }
00387 
00388         return true;
00389 }

bool InspIRCd::IsIdent const char *  n  ) 
 

Return true if an ident is valid.

Parameters:
An ident to verify
Returns:
True if the ident is valid

Definition at line 421 of file helperfuncs.cpp.

Referenced by cmd_setident::Handle(), cmd_chgident::Handle(), cmd_user::Handle(), and IdentRequestSocket::ReadResponse().

00422 {
00423         if (!n || !*n)
00424                 return false;
00425 
00426         for (char* i = (char*)n; *i; i++)
00427         {
00428                 if ((*i >= 'A') && (*i <= '}'))
00429                 {
00430                         continue;
00431                 }
00432 
00433                 if (((*i >= '0') && (*i <= '9')) || (*i == '-') || (*i == '.'))
00434                 {
00435                         continue;
00436                 }
00437 
00438                 return false;
00439         }
00440 
00441         return true;
00442 }

bool InspIRCd::IsNick const char *  n  ) 
 

Return true if a nickname is valid.

Parameters:
n A nickname to verify
Returns:
True if the nick is valid

Definition at line 392 of file helperfuncs.cpp.

References NICKMAX.

Referenced by cmd_watch::add_watch(), DoStats(), cmd_svshold::Handle(), cmd_sanick::Handle(), cmd_nicklock::Handle(), cmd_oper::Handle(), cmd_nick::Handle(), and cmd_watch::remove_watch().

00393 {
00394         if (!n || !*n)
00395                 return false;
00396  
00397         int p = 0;
00398         for (char* i = (char*)n; *i; i++, p++)
00399         {
00400                 if ((*i >= 'A') && (*i <= '}'))
00401                 {
00402                         /* "A"-"}" can occur anywhere in a nickname */
00403                         continue;
00404                 }
00405 
00406                 if ((((*i >= '0') && (*i <= '9')) || (*i == '-')) && (i > n))
00407                 {
00408                         /* "0"-"9", "-" can occur anywhere BUT the first char of a nickname */
00409                         continue;
00410                 }
00411 
00412                 /* invalid character! abort */
00413                 return false;
00414         }
00415 
00416         /* too long? or not -- pointer arithmetic rocks */
00417         return (p < NICKMAX - 1);
00418 }

bool InspIRCd::IsValidMask const std::string mask  ) 
 

Return true if the given parameter is a valid nick!user@host mask.

Parameters:
mask A nick!user@host masak to match against
Returns:
True i the mask is valid

Definition at line 509 of file modules.cpp.

Referenced by cmd_tban::Handle(), and cmd_dccallow::Handle().

00510 {
00511         char* dest = (char*)mask.c_str();
00512         if (strchr(dest,'!')==0)
00513                 return false;
00514         if (strchr(dest,'@')==0)
00515                 return false;
00516         for (char* i = dest; *i; i++)
00517                 if (*i < 32)
00518                         return false;
00519         for (char* i = dest; *i; i++)
00520                 if (*i > 126)
00521                         return false;
00522         unsigned int c = 0;
00523         for (char* i = dest; *i; i++)
00524                 if (*i == '!')
00525                         c++;
00526         if (c>1)
00527                 return false;
00528         c = 0;
00529         for (char* i = dest; *i; i++)
00530                 if (*i == '@')
00531                         c++;
00532         if (c>1)
00533                 return false;
00534 
00535         return true;
00536 }

bool InspIRCd::IsValidModuleCommand const std::string commandname,
int  pcnt,
userrec user
 

Return true if the command is a module-implemented command and the given parameters are valid for it.

Parameters:
parameters The mode parameters
pcnt The number of items you have given in the first parameter
user The user to test-execute the command as
Returns:
True if the command handler is a module command, and there are enough parameters and the user has permission to the command

Definition at line 384 of file modules.cpp.

References CommandParser::IsValidCommand(), and Parser.

Referenced by ModuleSpanningTree::OnPostCommand().

00385 {
00386         return this->Parser->IsValidCommand(commandname, pcnt, user);
00387 }

void InspIRCd::LoadAllModules  ) 
 

Called by the constructor to load all modules from the config file.

Definition at line 494 of file helperfuncs.cpp.

References Config, ServerConfig::config_data, ServerConfig::ConfValue(), DEFAULT, Exit(), EXIT_STATUS_MODULE, Log(), MAXBUF, ModCount, ServerConfig::module_names, and printf_c.

Referenced by InspIRCd().

00495 {
00496         char configToken[MAXBUF];
00497         Config->module_names.clear();
00498         this->ModCount = -1;
00499 
00500         for (int count = 0; count < Config->ConfValueEnum(Config->config_data, "module"); count++)
00501         {
00502                 Config->ConfValue(Config->config_data, "module", "name", count, configToken, MAXBUF);
00503                 printf_c("[\033[1;32m*\033[0m] Loading module:\t\033[1;32m%s\033[0m\n",configToken);
00504                 
00505                 if (!this->LoadModule(configToken))             
00506                 {
00507                         this->Log(DEFAULT,"There was an error loading the module '%s': %s", configToken, this->ModuleError());
00508                         printf_c("\n[\033[1;31m*\033[0m] There was an error loading the module '%s': %s\n\n", configToken, this->ModuleError());
00509                         Exit(EXIT_STATUS_MODULE);
00510                 }
00511         }
00512         printf_c("\nA total of \033[1;32m%d\033[0m module%s been loaded.\n", this->ModCount+1, this->ModCount+1 == 1 ? " has" : "s have");
00513         this->Log(DEFAULT,"Total loaded modules: %d", this->ModCount+1);
00514 }

bool InspIRCd::LoadModule const char *  filename  ) 
 

Load a given module file.

Parameters:
filename The file to load
Returns:
True if the module was found and loaded

Definition at line 931 of file inspircd.cpp.

References Version::API, API_VERSION, Version::Build, BuildISupport(), Config, DEFAULT, ServerConfig::DirValid(), factory, ServerConfig::FileExists(), Version::Flags, FOREACH_MOD_I, CoreException::GetReason(), CoreException::GetSource(), Module::GetVersion(), ServerConfig::global_implementation, I_OnLoadModule, ServerConfig::implement_lists, Log(), Version::Major, MAXBUF, Version::Minor, ModCount, MODERR, ServerConfig::ModPath, ServerConfig::module_names, modules, MoveAfter(), MoveBefore(), MoveToFirst(), MoveToLast(), PRIORITY_AFTER, PRIORITY_BEFORE, PRIORITY_FIRST, PRIORITY_LAST, Version::Revision, and VF_VENDOR.

Referenced by cmd_greloadmodule::Handle(), cmd_gloadmodule::Handle(), cmd_reloadmodule::Handle(), cmd_loadmodule::Handle(), and ServerConfig::Read().

00932 {
00933         /* Do we have a glob pattern in the filename?
00934          * The user wants to load multiple modules which
00935          * match the pattern.
00936          */
00937         if (strchr(filename,'*') || (strchr(filename,'?')))
00938         {
00939                 int n_match = 0;
00940                 DIR* library = opendir(Config->ModPath);
00941                 if (library)
00942                 {
00943                         /* Try and locate and load all modules matching the pattern */
00944                         dirent* entry = NULL;
00945                         while ((entry = readdir(library)))
00946                         {
00947                                 if (this->MatchText(entry->d_name, filename))
00948                                 {
00949                                         if (!this->LoadModule(entry->d_name))
00950                                                 n_match++;
00951                                 }
00952                         }
00953                         closedir(library);
00954                 }
00955                 /* Loadmodule will now return false if any one of the modules failed
00956                  * to load (but wont abort when it encounters a bad one) and when 1 or
00957                  * more modules were actually loaded.
00958                  */
00959                 return (n_match > 0);
00960         }
00961 
00962         char modfile[MAXBUF];
00963         snprintf(modfile,MAXBUF,"%s/%s",Config->ModPath,filename);
00964         std::string filename_str = filename;
00965 
00966         if (!ServerConfig::DirValid(modfile))
00967         {
00968                 this->Log(DEFAULT,"Module %s is not within the modules directory.",modfile);
00969                 snprintf(MODERR,MAXBUF,"Module %s is not within the modules directory.",modfile);
00970                 return false;
00971         }
00972         if (ServerConfig::FileExists(modfile))
00973         {
00974 
00975                 for (unsigned int j = 0; j < Config->module_names.size(); j++)
00976                 {
00977                         if (Config->module_names[j] == filename_str)
00978                         {
00979                                 this->Log(DEFAULT,"Module %s is already loaded, cannot load a module twice!",modfile);
00980                                 snprintf(MODERR,MAXBUF,"Module already loaded");
00981                                 return false;
00982                         }
00983                 }
00984                 Module* m = NULL;
00985                 ircd_module* a = NULL;
00986                 try
00987                 {
00988                         a = new ircd_module(this, modfile);
00989                         factory[this->ModCount+1] = a;
00990                         if (factory[this->ModCount+1]->LastError())
00991                         {
00992                                 this->Log(DEFAULT,"Unable to load %s: %s",modfile,factory[this->ModCount+1]->LastError());
00993                                 snprintf(MODERR,MAXBUF,"Loader/Linker error: %s",factory[this->ModCount+1]->LastError());
00994                                 return false;
00995                         }
00996                         if ((long)factory[this->ModCount+1]->factory != -1)
00997                         {
00998                                 m = factory[this->ModCount+1]->factory->CreateModule(this);
00999 
01000                                 Version v = m->GetVersion();
01001 
01002                                 if (v.API != API_VERSION)
01003                                 {
01004                                         delete m;
01005                                         this->Log(DEFAULT,"Unable to load %s: Incorrect module API version: %d (our version: %d)",modfile,v.API,API_VERSION);
01006                                         snprintf(MODERR,MAXBUF,"Loader/Linker error: Incorrect module API version: %d (our version: %d)",v.API,API_VERSION);
01007                                         return false;
01008                                 }
01009                                 else
01010                                 {
01011                                         this->Log(DEFAULT,"New module introduced: %s (API version %d, Module version %d.%d.%d.%d)%s", filename, v.API, v.Major, v.Minor, v.Revision, v.Build, (!(v.Flags & VF_VENDOR) ? " [3rd Party]" : " [Vendor]"));
01012                                 }
01013 
01014                                 modules[this->ModCount+1] = m;
01015                                 /* save the module and the module's classfactory, if
01016                                  * this isnt done, random crashes can occur :/ */
01017                                 Config->module_names.push_back(filename);
01018 
01019                                 char* x = &Config->implement_lists[this->ModCount+1][0];
01020                                 for(int t = 0; t < 255; t++)
01021                                         x[t] = 0;
01022 
01023                                 modules[this->ModCount+1]->Implements(x);
01024 
01025                                 for(int t = 0; t < 255; t++)
01026                                         Config->global_implementation[t] += Config->implement_lists[this->ModCount+1][t];
01027                         }
01028                         else
01029                         {
01030                                 this->Log(DEFAULT,"Unable to load %s",modfile);
01031                                 snprintf(MODERR,MAXBUF,"Factory function failed: Probably missing init_module() entrypoint.");
01032                                 return false;
01033                         }
01034                 }
01035                 catch (CoreException& modexcept)
01036                 {
01037                         this->Log(DEFAULT,"Unable to load %s: %s",modfile,modexcept.GetReason());
01038                         snprintf(MODERR,MAXBUF,"Factory function of %s threw an exception: %s", modexcept.GetSource(), modexcept.GetReason());
01039                         return false;
01040                 }
01041         }
01042         else
01043         {
01044                 this->Log(DEFAULT,"InspIRCd: startup: Module Not Found %s",modfile);
01045                 snprintf(MODERR,MAXBUF,"Module file could not be found");
01046                 return false;
01047         }
01048         this->ModCount++;
01049         FOREACH_MOD_I(this,I_OnLoadModule,OnLoadModule(modules[this->ModCount],filename_str));
01050         // now work out which modules, if any, want to move to the back of the queue,
01051         // and if they do, move them there.
01052         std::vector<std::string> put_to_back;
01053         std::vector<std::string> put_to_front;
01054         std::map<std::string,std::string> put_before;
01055         std::map<std::string,std::string> put_after;
01056         for (unsigned int j = 0; j < Config->module_names.size(); j++)
01057         {
01058                 if (modules[j]->Prioritize() == PRIORITY_LAST)
01059                         put_to_back.push_back(Config->module_names[j]);
01060                 else if (modules[j]->Prioritize() == PRIORITY_FIRST)
01061                         put_to_front.push_back(Config->module_names[j]);
01062                 else if ((modules[j]->Prioritize() & 0xFF) == PRIORITY_BEFORE)
01063                         put_before[Config->module_names[j]] = Config->module_names[modules[j]->Prioritize() >> 8];
01064                 else if ((modules[j]->Prioritize() & 0xFF) == PRIORITY_AFTER)
01065                         put_after[Config->module_names[j]] = Config->module_names[modules[j]->Prioritize() >> 8];
01066         }
01067         for (unsigned int j = 0; j < put_to_back.size(); j++)
01068                 MoveToLast(put_to_back[j]);
01069         for (unsigned int j = 0; j < put_to_front.size(); j++)
01070                 MoveToFirst(put_to_front[j]);
01071         for (std::map<std::string,std::string>::iterator j = put_before.begin(); j != put_before.end(); j++)
01072                 MoveBefore(j->first,j->second);
01073         for (std::map<std::string,std::string>::iterator j = put_after.begin(); j != put_after.end(); j++)
01074                 MoveAfter(j->first,j->second);
01075         BuildISupport();
01076         return true;
01077 }

long InspIRCd::LocalUserCount  ) 
 

Return a count of local users on this server only.

Returns:
The number of local users

Definition at line 351 of file helperfuncs.cpp.

References local_users, and UnregisteredUserCount().

Referenced by DoOneIteration(), cmd_lusers::Handle(), and ModuleSpanningTree::HandleLusers().

00352 {
00353         /* Doesnt count unregistered clients */
00354         return (local_users.size() - this->UnregisteredUserCount());
00355 }

void InspIRCd::Log int  level,
const std::string text
 

Output a log message to the ircd.log file The text will only be output if the current loglevel is less than or equal to the level you provide.

Parameters:
level A log level from the DebugLevel enum
text Text to write to the log

Definition at line 51 of file helperfuncs.cpp.

References Config, ServerConfig::forcedebug, LAST, ServerConfig::log_file, Logger, ServerConfig::nofork, strlcpy(), Time(), TIMESTR, ServerConfig::writelog, and FileLogger::WriteLogLine().

00052 {
00053         /* sanity check, just in case */
00054         if (!this->Config || !this->Logger)
00055                 return;
00056 
00057         /* If we were given -debug we output all messages, regardless of configured loglevel */
00058         if ((level < Config->LogLevel) && !Config->forcedebug)
00059                 return;
00060 
00061         if (Time() != LAST)
00062         {
00063                 time_t local = Time();
00064                 struct tm *timeinfo = localtime(&local);
00065 
00066                 strlcpy(TIMESTR,asctime(timeinfo),26);
00067                 TIMESTR[24] = ':';
00068                 LAST = Time();
00069         }
00070 
00071         if (Config->log_file && Config->writelog)
00072         {
00073                 std::string out = std::string(TIMESTR) + " " + text.c_str() + "\n";
00074                 this->Logger->WriteLogLine(out);
00075         }
00076 
00077         if (Config->nofork)
00078         {
00079                 printf("%s %s\n", TIMESTR, text.c_str());
00080         }
00081 }

void InspIRCd::Log int  level,
const char *  text,
  ...
 

Output a log message to the ircd.log file The text will only be output if the current loglevel is less than or equal to the level you provide.

Parameters:
level A log level from the DebugLevel enum
text Format string of to write to the log
... Format arguments of text to write to the log

Definition at line 31 of file helperfuncs.cpp.

References Config, and ServerConfig::forcedebug.

Referenced by userrec::AddBuffer(), ModuleSQLite3::AddConn(), ModulePgSQL::AddConn(), SelectEngine::AddFd(), PortsEngine::AddFd(), PollEngine::AddFd(), KQueueEngine::AddFd(), IOCPEngine::AddFd(), EPollEngine::AddFd(), ModuleFilterPCRE::AddFilter(), CullList::Apply(), BindPorts(), BindSocket(), ModeHandler::ChangeCount(), userrec::ChannelList(), CheckDie(), CheckRoot(), SQLConn::Close(), IdentRequestSocket::Close(), InspSocket::Close(), ServerConfig::ConfValue(), ConnectDatabases(), CommandParser::CreateCommand(), DaemonSeed(), SelectEngine::DelFd(), PortsEngine::DelFd(), PollEngine::DelFd(), KQueueEngine::DelFd(), IOCPEngine::DelFd(), EPollEngine::DelFd(), SQLConn::DoConnect(), SpanningTreeUtilities::DoFailOver(), SQLConn::DoQuery(), EPollEngine::EPollEngine(), error_callback(), ModuleSVSHold::ExpireBans(), CommandParser::FindSym(), FloodQuitUser(), userrec::FlushWriteBuf(), InspSocket::FlushWriteBuffer(), TreeSocket::ForceJoin(), TreeSocket::ForceMode(), userrec::ForceNickChange(), ModuleSSLGnuTLS::GenerateDHParams(), userrec::GetBuffer(), cmd_restart::Handle(), cmd_oper::Handle(), cmd_kill::Handle(), cmd_die::Handle(), userrec::HandleEvent(), ListenSocket::HandleEvent(), IdentRequestSocket::HandleEvent(), ModuleSafeList::HandleList(), TreeSocket::HandleSetTime(), ModuleSSLOpenSSL::Handshake(), InitConnect(), InspIRCd(), InspSocket::InspSocket(), TreeSocket::IntroduceClient(), IOCPEngine::IOCPEngine(), chanrec::JoinUser(), KQueueEngine::KQueueEngine(), LoadAllModules(), CommandParser::LoadCommand(), LoadModule(), ModuleSQLOper::LoginFail(), ModuleSQLOper::LookupOper(), TreeSocket::MakePass(), ModuleSQL::ModuleSQL(), ModuleTestClient::OnBackgroundTimer(), ModuleSQLutils::OnChannelDelete(), ModuleIdent::OnCheckReady(), IdentRequestSocket::OnConnected(), SecurityIPResolver::OnError(), SQLresolver::OnError(), UserResolver::OnLookupComplete(), ModuleUHNames::OnPreCommand(), ModuleOperSSLCert::OnPreCommand(), ModuleOperLog::OnPreCommand(), ModuleSSLOpenSSL::OnRawSocketAccept(), ModuleSSLOpenSSL::OnRawSocketConnect(), ModuleXMLSocket::OnRehash(), ModuleSSLOpenSSL::OnRehash(), ModuleSSLGnuTLS::OnRehash(), ModuleFilterPCRE::OnRehash(), ModuleCgiIRC::OnRehash(), ModuleTestClient::OnRequest(), ModuleFoobar::OnUserConnect(), ModuleSQLutils::OnUserDisconnect(), ModuleIdent::OnUserDisconnect(), ModuleFoobar::OnUserJoin(), ModuleUHNames::OnUserList(), ModuleNamesX::OnUserList(), ModuleAuditorium::OnUserList(), ModuleFoobar::OnUserPart(), FilterBase::OnUserPreNotice(), ModuleFoobar::OnUserQuit(), ModuleIdent::OnUserRegister(), userrec::Oper(), InspSocket::Poll(), PortsEngine::PortsEngine(), CommandParser::ProcessBuffer(), TreeSocket::ProcessLine(), ProcessUser(), cmd_whowas::PruneWhoWas(), userrec::PurgeEmptyChannels(), InspSocket::Read(), ServerConfig::Read(), ModulePgSQL::ReadConf(), ModuleBlockCAPS::ReadConf(), SpanningTreeUtilities::ReadConfiguration(), ServerConfig::ReadFile(), IdentRequestSocket::ReadResponse(), DNS::Rehash(), ServerConfig::ReportConfigError(), TreeSocket::SendChannelModes(), SpanningTreeUtilities::SetRemoteBursting(), userrec::SetSockAddr(), SetTimeDelta(), userrec::SetWriteError(), userrec::SplitChanList(), SQLConn::SQLConn(), TreeSocket::Squit(), userrec::StartDNSLookup(), UnloadModule(), userrec::UnOper(), userrec::UpdateNickHash(), ValidateDnsServer(), ValidateMaxConn(), ValidateMaxTargets(), ValidateMaxWho(), ValidateNetBufferSize(), ValidateServerName(), ValidateSoftLimit(), ValidateWhoWas(), PollEngine::WantWrite(), KQueueEngine::WantWrite(), userrec::Write(), userrec::WriteCommon(), TreeSocket::WriteLine(), WriteMode(), WritePID(), cmd_whowas::~cmd_whowas(), ListenSocket::~ListenSocket(), and ModuleSQL::~ModuleSQL().

00032 {
00033         /* sanity check, just in case */
00034         if (!this->Config || !this->Logger)
00035                 return;
00036 
00037         /* Do this check again here so that we save pointless vsnprintf calls */
00038         if ((level < Config->LogLevel) && !Config->forcedebug)
00039                 return;
00040 
00041         va_list argsPtr;
00042         char textbuffer[65536];
00043 
00044         va_start(argsPtr, text);
00045         vsnprintf(textbuffer, 65536, text, argsPtr);
00046         va_end(argsPtr);
00047 
00048         this->Log(level, std::string(textbuffer));
00049 }

bool InspIRCd::MatchText const std::string sliteral,
const std::string spattern
 

Match two strings using pattern matching.

This operates identically to the global function match(), except for that it takes std::string arguments rather than const char* ones.

Parameters:
sliteral The literal string to match against
spattern The pattern to match against. CIDR and globs are supported.

Definition at line 374 of file modules.cpp.

References match().

Referenced by ModuleFilter::FilterMatch(), SpanningTreeUtilities::FindLink(), cmd_rsquit::Handle(), cmd_rconnect::Handle(), cmd_greloadmodule::Handle(), cmd_gunloadmodule::Handle(), cmd_gloadmodule::Handle(), cmd_webirc::Handle(), ModuleSpanningTree::HandleConnect(), ModuleSilence::MatchPattern(), ModuleSecureList::OnPreCommand(), ModuleSpanningTree::OnRehash(), ModuleBanRedirect::OnUserPreJoin(), ModuleDCCAllow::OnUserPreNotice(), ModuleSQLAuth::OnUserRegister(), ModuleLDAPAuth::OnUserRegister(), and ModuleCgiIRC::OnUserRegister().

00375 {
00376         return match(sliteral.c_str(),spattern.c_str());
00377 }

int InspIRCd::ModeCount const char  mode  ) 
 

Number of users with a certain mode set on them.

Definition at line 316 of file helperfuncs.cpp.

References ModeParser::FindMode(), ModeHandler::GetCount(), Modes, and MODETYPE_USER.

Referenced by InvisibleUserCount().

00317 {
00318         ModeHandler* mh = this->Modes->FindMode(mode, MODETYPE_USER);
00319 
00320         if (mh)
00321                 return mh->GetCount();
00322         else
00323                 return 0;
00324 }

char * InspIRCd::ModuleError  ) 
 

Returns text describing the last module error.

Returns:
The last error message to occur

Definition at line 725 of file inspircd.cpp.

References MODERR.

Referenced by cmd_greloadmodule::Handle(), cmd_gunloadmodule::Handle(), cmd_gloadmodule::Handle(), cmd_unloadmodule::Handle(), cmd_loadmodule::Handle(), and ServerConfig::Read().

00726 {
00727         return MODERR;
00728 }

void InspIRCd::MoveAfter std::string  modulename,
std::string  after
[private]
 

Moves one module to be placed after another in the list.

Parameters:
modulename The module name to relocate
after The module name to place the module after

Definition at line 809 of file inspircd.cpp.

References Config, ServerConfig::module_names, and MoveTo().

Referenced by LoadModule().

00810 {
00811         for (unsigned int v = 0; v < Config->module_names.size(); v++)
00812         {
00813                 if (Config->module_names[v] == after)
00814                 {
00815                         MoveTo(modulename, v);
00816                         return;
00817                 }
00818         }
00819 }

void InspIRCd::MoveBefore std::string  modulename,
std::string  before
[private]
 

Moves one module to be placed before another in the list.

Parameters:
modulename The module name to relocate
after The module name to place the module before

Definition at line 821 of file inspircd.cpp.

References Config, ServerConfig::module_names, and MoveTo().

Referenced by LoadModule().

00822 {
00823         for (unsigned int v = 0; v < Config->module_names.size(); v++)
00824         {
00825                 if (Config->module_names[v] == before)
00826                 {
00827                         if (v > 0)
00828                         {
00829                                 MoveTo(modulename, v-1);
00830                         }
00831                         else
00832                         {
00833                                 MoveTo(modulename, v);
00834                         }
00835                         return;
00836                 }
00837         }
00838 }

void InspIRCd::MoveTo std::string  modulename,
int  slot
[private]
 

Move a given module to a specific slot in the list.

Parameters:
modulename The module name to relocate
slot The slot to move the module into

Definition at line 773 of file inspircd.cpp.

References Config, factory, ServerConfig::implement_lists, ServerConfig::module_names, and modules.

Referenced by MoveAfter(), MoveBefore(), MoveToFirst(), and MoveToLast().

00774 {
00775         unsigned int v2 = 256;
00776         for (unsigned int v = 0; v < Config->module_names.size(); v++)
00777         {
00778                 if (Config->module_names[v] == modulename)
00779                 {
00780                         // found an instance, swap it with the item at the end
00781                         v2 = v;
00782                         break;
00783                 }
00784         }
00785         if ((v2 != (unsigned int)slot) && (v2 < 256))
00786         {
00787                 // Swap the module names over
00788                 Config->module_names[v2] = Config->module_names[slot];
00789                 Config->module_names[slot] = modulename;
00790                 // now swap the module factories
00791                 ircd_module* temp = factory[v2];
00792                 factory[v2] = factory[slot];
00793                 factory[slot] = temp;
00794                 // now swap the module objects
00795                 Module* temp_module = modules[v2];
00796                 modules[v2] = modules[slot];
00797                 modules[slot] = temp_module;
00798                 // now swap the implement lists (we dont
00799                 // need to swap the global or recount it)
00800                 for (int n = 0; n < 255; n++)
00801                 {
00802                         char x = Config->implement_lists[v2][n];
00803                         Config->implement_lists[v2][n] = Config->implement_lists[slot][n];
00804                         Config->implement_lists[slot][n] = x;
00805                 }
00806         }
00807 }

void InspIRCd::MoveToFirst std::string  modulename  )  [private]
 

Moves the given module to the first slot in the list.

Parameters:
modulename The module name to relocate

Definition at line 840 of file inspircd.cpp.

References MoveTo().

Referenced by LoadModule().

00841 {
00842         MoveTo(modulename,0);
00843 }

void InspIRCd::MoveToLast std::string  modulename  )  [private]
 

Moves the given module to the last slot in the list.

Parameters:
modulename The module name to relocate

Definition at line 845 of file inspircd.cpp.

References MoveTo().

Referenced by LoadModule().

00846 {
00847         MoveTo(modulename,this->GetModuleCount());
00848 }

bool InspIRCd::NickMatchesEveryone const std::string nick,
userrec user
 

Check if the given nickmask matches too many users, send errors to the given user.

Parameters:
nick A nickmask to match against
user A user to send error text to
Returns:
True if the nick matches too many users

Definition at line 84 of file commands.cpp.

References clientlist, Config, ServerConfig::config_data, ServerConfig::ConfValue(), ServerConfig::ConfValueBool(), match(), MAXBUF, userrec::nick, strlcpy(), and WriteOpers().

Referenced by cmd_qline::Handle().

00085 {
00086         char itrigger[MAXBUF];
00087         long matches = 0;
00088         
00089         if (!Config->ConfValue(Config->config_data, "insane","trigger",0,itrigger,MAXBUF))
00090                 strlcpy(itrigger,"95.5",MAXBUF);
00091         
00092         if (Config->ConfValueBool(Config->config_data, "insane","nickmasks",0))
00093                 return false;
00094 
00095         for (user_hash::iterator u = clientlist->begin(); u != clientlist->end(); u++)
00096         {
00097                 if (match(u->second->nick,nick.c_str()))
00098                         matches++;
00099         }
00100 
00101         if (!matches)
00102                 return false;
00103 
00104         float percent = ((float)matches / (float)clientlist->size()) * 100;
00105         if (percent > (float)atof(itrigger))
00106         {
00107                 WriteOpers("*** \2WARNING\2: %s tried to set a Q line mask of %s, which covers %.2f%% of the network!",user->nick,nick.c_str(),percent);
00108                 return true;
00109         }
00110         return false;
00111 }

bool InspIRCd::OpenLog char **  argv,
int  argc
 

Determine the right path for, and open, the logfile.

Parameters:
argv The argv passed to main() initially, used to calculate program path
argc The argc passed to main() initially, used to calculate program path
Returns:
True if the log could be opened, false if otherwise

Definition at line 445 of file helperfuncs.cpp.

References Config, ServerConfig::GetFullProgDir(), ServerConfig::log_file, Logger, ServerConfig::logpath, and ServerConfig::MyDir.

Referenced by cmd_rehash::Handle(), and Rehash().

00446 {
00447         Config->MyDir = Config->GetFullProgDir();
00448 
00449         if (!*this->LogFileName)
00450         {
00451                 if (Config->logpath.empty())
00452                 {
00453                         Config->logpath = Config->MyDir + "/ircd.log";
00454                 }
00455 
00456                 Config->log_file = fopen(Config->logpath.c_str(),"a+");
00457         }
00458         else
00459         {
00460                 Config->log_file = fopen(this->LogFileName,"a+");
00461         }
00462 
00463         if (!Config->log_file)
00464         {
00465                 this->Logger = NULL;
00466                 return false;
00467         }
00468 
00469         this->Logger = new FileLogger(this, Config->log_file);
00470         return true;
00471 }

int InspIRCd::OperCount  ) 
 

Return a count of opered (umode +o) users only.

Returns:
The number of opers

Definition at line 333 of file helperfuncs.cpp.

References all_opers.

Referenced by cmd_lusers::Handle(), ModuleSpanningTree::HandleLusers(), and TreeServer::TreeServer().

00334 {
00335         return this->all_opers.size();
00336 }

int InspIRCd::OperPassCompare const char *  data,
const char *  input,
int  tagnum
 

Attempt to compare an oper password to a string from the config file.

This will be passed to handling modules which will compare the data against possible hashed equivalents in the input string.

Parameters:
data The data from the config file
input The data input by the oper
tagnum the tag number of the oper's tag in the config file
Returns:
0 if the strings match, 1 or -1 if they do not

Definition at line 50 of file command_parse.cpp.

References FOREACH_RESULT_I, and I_OnOperCompare.

Referenced by cmd_oper::Handle(), and ModuleOperSSLCert::OnPreCommand().

00051 {
00052         int MOD_RESULT = 0;
00053         FOREACH_RESULT_I(this,I_OnOperCompare,OnOperCompare(data, input, tagnumber))
00054         if (MOD_RESULT == 1)
00055                 return 0;
00056         if (MOD_RESULT == -1)
00057                 return 1;
00058         return strcmp(data,input);
00059 }

long InspIRCd::PriorityAfter const std::string modulename  ) 
 

For use with Module::Prioritize().

When the return value of this function is returned from Module::Prioritize(), this specifies that the module wishes to be ordered exactly AFTER 'modulename'. For more information please see Module::Prioritize().

Parameters:
modulename The module your module wants to be after in the call list
Returns:
a priority ID which the core uses to relocate the module in the list

Definition at line 197 of file modules.cpp.

References Config, ServerConfig::module_names, PRIORITY_AFTER, and PRIORITY_DONTCARE.

Referenced by ModuleUHNames::Prioritize(), and ModuleHostChange::Prioritize().

00198 {
00199         for (unsigned int j = 0; j < this->Config->module_names.size(); j++)
00200         {
00201                 if (this->Config->module_names[j] == modulename)
00202                 {
00203                         return ((j << 8) | PRIORITY_AFTER);
00204                 }
00205         }
00206         return PRIORITY_DONTCARE;
00207 }

long InspIRCd::PriorityBefore const std::string modulename  ) 
 

For use with Module::Prioritize().

When the return value of this function is returned from Module::Prioritize(), this specifies that the module wishes to be ordered exactly BEFORE 'modulename'. For more information please see Module::Prioritize().

Parameters:
modulename The module your module wants to be before in the call list
Returns:
a priority ID which the core uses to relocate the module in the list

Definition at line 209 of file modules.cpp.

References Config, ServerConfig::module_names, PRIORITY_BEFORE, and PRIORITY_DONTCARE.

Referenced by ModuleUHNames::Prioritize(), ModuleSecureList::Prioritize(), and ModuleBanRedirect::Prioritize().

00210 {
00211         for (unsigned int j = 0; j < this->Config->module_names.size(); j++)
00212         {
00213                 if (this->Config->module_names[j] == modulename)
00214                 {
00215                         return ((j << 8) | PRIORITY_BEFORE);
00216                 }
00217         }
00218         return PRIORITY_DONTCARE;
00219 }

void InspIRCd::ProcessUser userrec cu  ) 
 

Process a user whos socket has been flagged as active.

Parameters:
cu The user to process
Returns:
There is no actual return value, however upon exit, the user 'cu' may have been marked for deletion in the global CullList.

Definition at line 37 of file userprocess.cpp.

References userrec::AddBuffer(), userrec::BufferIsReady(), connection::bytes_in, connection::cmds_in, Config, DEBUG, FD_MAGIC_NUMBER, userrec::flood, FloodQuitUser(), userrec::GetBuffer(), EventHandler::GetFd(), ServerConfig::GetIOHook(), userrec::GetPort(), CoreException::GetReason(), SocketEngine::GetRef(), CoreException::GetSource(), userrec::lines_in, Log(), MAXBUF, userrec::nick, Module::OnRawSocketRead(), Parser, CommandParser::ProcessBuffer(), ReadBuffer, userrec::ReadData(), userrec::recvq, REG_ALL, connection::registered, userrec::reset_due, SE, userrec::SetWriteError(), stats, serverstats::statsRecv, userrec::threshold, TIME, and userrec::WriteServ().

Referenced by userrec::HandleEvent().

00038 {
00039         int result = EAGAIN;
00040 
00041         if (cu->GetFd() == FD_MAGIC_NUMBER)
00042                 return;
00043 
00044         if (this->Config->GetIOHook(cu->GetPort()))
00045         {
00046                 int result2 = 0;
00047                 int MOD_RESULT = 0;
00048 
00049                 try
00050                 {
00051                         MOD_RESULT = this->Config->GetIOHook(cu->GetPort())->OnRawSocketRead(cu->GetFd(),ReadBuffer,sizeof(ReadBuffer),result2);
00052                 }
00053                 catch (CoreException& modexcept)
00054                 {
00055                         this->Log(DEBUG, "%s threw an exception: %s", modexcept.GetSource(), modexcept.GetReason());
00056                 }
00057 
00058                 if (MOD_RESULT < 0)
00059                 {
00060                         result = -EAGAIN;
00061                 }
00062                 else
00063                 {
00064                         result = result2;
00065                 }
00066         }
00067         else
00068         {
00069                 result = cu->ReadData(ReadBuffer, sizeof(ReadBuffer));
00070         }
00071 
00072         if ((result) && (result != -EAGAIN))
00073         {
00074                 userrec *current;
00075                 int currfd;
00076                 int floodlines = 0;
00077 
00078                 this->stats->statsRecv += result;
00079                 /*
00080                  * perform a check on the raw buffer as an array (not a string!) to remove
00081                  * character 0 which is illegal in the RFC - replace them with spaces.
00082