summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/inspircd.conf.example2
-rw-r--r--include/modules.h28
-rw-r--r--src/commands.cpp33
-rw-r--r--src/inspircd.cpp5
-rw-r--r--src/inspircd_io.cpp2
-rw-r--r--src/modules.cpp3
-rw-r--r--src/users.cpp1
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;