diff options
-rw-r--r-- | docs/inspircd.conf.example | 2 | ||||
-rw-r--r-- | include/modules.h | 28 | ||||
-rw-r--r-- | src/commands.cpp | 33 | ||||
-rw-r--r-- | src/inspircd.cpp | 5 | ||||
-rw-r--r-- | src/inspircd_io.cpp | 2 | ||||
-rw-r--r-- | src/modules.cpp | 3 | ||||
-rw-r--r-- | src/users.cpp | 1 |
7 files changed, 58 insertions, 16 deletions
diff --git a/docs/inspircd.conf.example b/docs/inspircd.conf.example index cccae5ed0..c652c2cca 100644 --- a/docs/inspircd.conf.example +++ b/docs/inspircd.conf.example @@ -134,7 +134,7 @@ # Syntax is as follow: # # <class name="name" commands="oper commands"> # # # - + <class name="Shutdown" commands="DIE RESTART REHASH"> <class name="ServerLink" commands="CONNECT SQUIT"> <class name="BanControl" commands="KILL GLINE KLINE ZLINE QLINE SHUN"> diff --git a/include/modules.h b/include/modules.h index 81d76d55d..2146ec4a6 100644 --- a/include/modules.h +++ b/include/modules.h @@ -326,6 +326,34 @@ class Module : public classbase * multiple commands in the string_list. */ virtual string_list OnChannelSync(chanrec* chan); + + /** Called when a 005 numeric is about to be output. + * The module should modify the 005 numeric if needed to indicate its features. + */ + virtual void On005Numeric(std::string &output); + + /** Called when a client is disconnected by KILL. + * If a client is killed by a server, e.g. a nickname collision or protocol error, + * source is NULL. + * Return 1 from this function to prevent the kill, and 0 from this function to allow + * it as normal. If you prevent the kill no output will be sent to the client, it is + * down to your module to generate this information. + * NOTE: It is NOT advisable to stop kills which originate from servers. If you do + * so youre risking race conditions, desyncs and worse! + */ + virtual int OnKill(userrec* source, userrec* dest, std::string reason); + + /** Called whenever a module is loaded. + * mod will contain a pointer to the module, and string will contain its name, + * for example m_widgets.so. This function is primary for dependency checking, + * your module may decide to enable some extra features if it sees that you have + * for example loaded "m_killwidgets.so" with "m_makewidgets.so". It is highly + * recommended that modules do *NOT* bail if they cannot satisfy dependencies, + * but instead operate under reduced functionality, unless the dependency is + * absolutely neccessary (e.g. a module that extends the features of another + * module). + */ + virtual void OnLoadModule(Module* mod,std::string name); }; diff --git a/src/commands.cpp b/src/commands.cpp index dbb7a43a4..c47da8a61 100644 --- a/src/commands.cpp +++ b/src/commands.cpp @@ -762,7 +762,7 @@ void handle_whois(char **parameters, int pcnt, userrec *user) { WriteServ(user->fd,"301 %s %s :%s",user->nick, dest->nick, dest->awaymsg); } - if (strchr(dest->modes,'o')) + if ((strchr(dest->modes,'o')) && (strcmp(dest->oper,""))) { WriteServ(user->fd,"313 %s %s :is %s %s on %s",user->nick, dest->nick, (strchr("aeiou",dest->oper[0]) ? "an" : "a"),dest->oper, Network); @@ -1487,6 +1487,7 @@ void handle_oper(char **parameters, int pcnt, userrec *user) char TypeName[MAXBUF]; char Hostname[MAXBUF]; int i,j; + bool found = false; for (int i = 0; i < ConfValueEnum("oper",&config_f); i++) { @@ -1494,14 +1495,6 @@ void handle_oper(char **parameters, int pcnt, userrec *user) ConfValue("oper","password",i,Password,&config_f); if ((!strcmp(LoginName,parameters[0])) && (!strcmp(Password,parameters[1]))) { - /* correct oper credentials */ - ConfValue("oper","type",i,OperType,&config_f); - WriteOpers("*** %s (%s@%s) is now an IRC operator of type %s",user->nick,user->ident,user->host,OperType); - WriteServ(user->fd,"381 %s :You are now an IRC operator of type %s",user->nick,OperType); - WriteServ(user->fd,"MODE %s :+o",user->nick); - char global[MAXBUF]; - snprintf(global,MAXBUF,"M %s +o",user->nick); - NetSendToAll(global); for (j =0; j < ConfValueEnum("type",&config_f); j++) { ConfValue("type","name",j,TypeName,&config_f); @@ -1513,13 +1506,29 @@ void handle_oper(char **parameters, int pcnt, userrec *user) ConfValue("type","host",j,Hostname,&config_f); ChangeDisplayedHost(user,Hostname); strlcpy(user->oper,TypeName,NICKMAX); + found = true; } } - if (!strchr(user->modes,'o')) + if (found) + { + /* correct oper credentials */ + ConfValue("oper","type",i,OperType,&config_f); + WriteOpers("*** %s (%s@%s) is now an IRC operator of type %s",user->nick,user->ident,user->host,OperType); + WriteServ(user->fd,"381 %s :You are now an IRC operator of type %s",user->nick,OperType); + if (!strchr(user->modes,'o')) + { + strcat(user->modes,"o"); + WriteServ(user->fd,"MODE %s :+o",user->nick); + char global[MAXBUF]; + snprintf(global,MAXBUF,"M %s +o",user->nick); + NetSendToAll(global); + FOREACH_MOD OnOper(user); + } + } + else { - strcat(user->modes,"o"); + WriteOpers("*** BROKEN CONFIGURATION! *** Oper type %s for oper %s not found!",OperType,LoginName); } - FOREACH_MOD OnOper(user); return; } } diff --git a/src/inspircd.cpp b/src/inspircd.cpp index c39389f88..ed1c37c73 100644 --- a/src/inspircd.cpp +++ b/src/inspircd.cpp @@ -2399,8 +2399,9 @@ void ConnectUser(userrec *user) WriteServ(user->fd,"002 %s :Your host is %s, running version %s",user->nick,ServerName,VERSION); WriteServ(user->fd,"003 %s :This server was created %s %s",user->nick,__TIME__,__DATE__); WriteServ(user->fd,"004 %s %s %s iowghraAsORVSxNCWqBzvdHtGI lvhopsmntikrRcaqOALQbSeKVfHGCuzN",user->nick,ServerName,VERSION); - WriteServ(user->fd,"005 %s MAP KNOCK SAFELIST HCN MAXCHANNELS=20 MAXBANS=60 NICKLEN=30 TOPICLEN=307 KICKLEN=307 MAXTARGETS=20 AWAYLEN=307 :are supported by this server",user->nick); - WriteServ(user->fd,"005 %s WALLCHOPS WATCH=128 SILENCE=5 MODES=13 CHANTYPES=# PREFIX=(ohv)@%c+ CHANMODES=ohvbeqa,kfL,l,psmntirRcOAQKVHGCuzN NETWORK=%s :are supported by this server",user->nick,'%',Network); + std::string data005 = "WALLCHOPS MODES=13 CHANTYPES=# PREFIX=(ohv)@%+MAP SAFELIST MAXCHANNELS=20 MAXBANS=60 NICKLEN=30 TOPICLEN=307 KICKLEN=307 MAXTARGETS=20 AWAYLEN=307 CHANMODES=ohvbe,k,l,psmnti NETWORK=" + std::string(Network); + FOREACH_MOD On005Numeric(data005); + WriteServ(user->fd,"005 %s %s :are supported by this server",user->nick,data005.c_str()); ShowMOTD(user); FOREACH_MOD OnUserConnect(user); WriteOpers("*** Client connecting on port %d: %s!%s@%s [%s]",user->port,user->nick,user->ident,user->host,user->ip); diff --git a/src/inspircd_io.cpp b/src/inspircd_io.cpp index 7fd5c952d..7a2ad99f8 100644 --- a/src/inspircd_io.cpp +++ b/src/inspircd_io.cpp @@ -209,7 +209,7 @@ std::string ConfProcess(char* buffer, long linenumber, std::stringstream* errors } } // no quotes, and no equals. something freaky. - if ((!number_of_quotes) || (!number_of_equals) && (strlen(buffer)>2)) + if ((!number_of_quotes) || (!number_of_equals) && (strlen(buffer)>2) && (buffer[0]=='<')) { *errorstream << "Malformed tag at " << filename << ":" << linenumber << endl; error = true; diff --git a/src/modules.cpp b/src/modules.cpp index ac47544c0..fff5f1c7b 100644 --- a/src/modules.cpp +++ b/src/modules.cpp @@ -324,6 +324,9 @@ int Module::OnUserPreNick(userrec* user, std::string newnick) { return 0; }; int Module::OnAccessCheck(userrec* source,userrec* dest,chanrec* channel,int access_type) { return ACR_DEFAULT; }; string_list Module::OnUserSync(userrec* user) { string_list empty; return empty; } string_list Module::OnChannelSync(chanrec* chan) { string_list empty; return empty; } +void Module::On005Numeric(std::string &output) { }; +int Module::OnKill(userrec* source, userrec* dest, std::string reason) { return 0; }; +void Module::OnLoadModule(Module* mod,std::string name) { }; // server is a wrapper class that provides methods to all of the C-style diff --git a/src/users.cpp b/src/users.cpp index 46dfb35d7..9b97eff05 100644 --- a/src/users.cpp +++ b/src/users.cpp @@ -37,6 +37,7 @@ userrec::userrec() strcpy(inbuf,""); strcpy(server,""); strcpy(awaymsg,""); + strcpy(oper,""); fd = lastping = signon = idle_lastmsg = nping = registered = 0; flood = port = bytes_in = bytes_out = cmds_in = cmds_out = 0; haspassed = false; |