00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include "inspircd.h"
00015
00016
00017
00020 class Alias : public classbase
00021 {
00022 public:
00024 irc::string text;
00026 std::string replace_with;
00028 std::string requires;
00030 bool uline;
00032 bool operonly;
00033
00034 bool case_sensitive;
00036 std::string format;
00037 };
00038
00039 class ModuleAlias : public Module
00040 {
00041 private:
00043 std::vector<Alias> Aliases;
00044 std::map<std::string, int> AliasMap;
00045 std::vector<std::string> pars;
00046
00047 virtual void ReadAliases()
00048 {
00049 ConfigReader MyConf(ServerInstance);
00050
00051 Aliases.clear();
00052 AliasMap.clear();
00053 for (int i = 0; i < MyConf.Enumerate("alias"); i++)
00054 {
00055 Alias a;
00056 std::string txt;
00057 txt = MyConf.ReadValue("alias", "text", i);
00058 a.text = txt.c_str();
00059 a.replace_with = MyConf.ReadValue("alias", "replace", i, true);
00060 a.requires = MyConf.ReadValue("alias", "requires", i);
00061 a.uline = MyConf.ReadFlag("alias", "uline", i);
00062 a.operonly = MyConf.ReadFlag("alias", "operonly", i);
00063 a.format = MyConf.ReadValue("alias", "format", i);
00064 a.case_sensitive = MyConf.ReadFlag("alias", "matchcase", i);
00065 Aliases.push_back(a);
00066 AliasMap[txt] = 1;
00067 }
00068 }
00069
00070 public:
00071
00072 ModuleAlias(InspIRCd* Me)
00073 : Module(Me)
00074 {
00075 ReadAliases();
00076 Me->Modules->Attach(I_OnPreCommand, this);
00077 Me->Modules->Attach(I_OnRehash, this);
00078
00079 }
00080
00081 virtual ~ModuleAlias()
00082 {
00083 }
00084
00085 virtual Version GetVersion()
00086 {
00087 return Version("$Id: m_alias.cpp 10338 2008-08-28 19:46:21Z w00t $", VF_VENDOR,API_VERSION);
00088 }
00089
00090 std::string GetVar(std::string varname, const std::string &original_line)
00091 {
00092 irc::spacesepstream ss(original_line);
00093 varname.erase(varname.begin());
00094 int index = *(varname.begin()) - 48;
00095 varname.erase(varname.begin());
00096 bool everything_after = (varname == "-");
00097 std::string word;
00098
00099 for (int j = 0; j < index; j++)
00100 ss.GetToken(word);
00101
00102 if (everything_after)
00103 {
00104 std::string more;
00105 while (ss.GetToken(more))
00106 {
00107 word.append(" ");
00108 word.append(more);
00109 }
00110 }
00111
00112 return word;
00113 }
00114
00115 void SearchAndReplace(std::string& newline, const std::string &find, const std::string &replace)
00116 {
00117 std::string::size_type x = newline.find(find);
00118 while (x != std::string::npos)
00119 {
00120 newline.erase(x, find.length());
00121 newline.insert(x, replace);
00122 x = newline.find(find);
00123 }
00124 }
00125
00126 virtual int OnPreCommand(std::string &command, std::vector<std::string> ¶meters, User *user, bool validated, const std::string &original_line)
00127 {
00128 User *u = NULL;
00129
00130
00131
00132
00133 if (user->registered != REG_ALL)
00134 return 0;
00135
00136
00137 if (AliasMap.find(command) == AliasMap.end())
00138 return 0;
00139
00140 irc::string c = command.c_str();
00141
00142 std::string compare = original_line.substr(command.length());
00143 while (*(compare.c_str()) == ' ')
00144 compare.erase(compare.begin());
00145
00146 std::string safe(original_line);
00147
00148
00149
00150 SearchAndReplace(safe, "$", "\r");
00151
00152 for (unsigned int i = 0; i < Aliases.size(); i++)
00153 {
00154 if (Aliases[i].text == c)
00155 {
00156
00157 if (!Aliases[i].format.empty())
00158 {
00159 if (Aliases[i].case_sensitive)
00160 {
00161 if (InspIRCd::Match(compare, Aliases[i].format, case_sensitive_map))
00162 continue;
00163 }
00164 else
00165 {
00166 if (InspIRCd::Match(compare, Aliases[i].format))
00167 continue;
00168 }
00169 }
00170
00171 if ((Aliases[i].operonly) && (!IS_OPER(user)))
00172 return 0;
00173
00174 if (!Aliases[i].requires.empty())
00175 {
00176 u = ServerInstance->FindNick(Aliases[i].requires);
00177 if (!u)
00178 {
00179 user->WriteNumeric(401, ""+std::string(user->nick)+" "+Aliases[i].requires+" :is currently unavailable. Please try again later.");
00180 return 1;
00181 }
00182 }
00183 if ((u != NULL) && (!Aliases[i].requires.empty()) && (Aliases[i].uline))
00184 {
00185 if (!ServerInstance->ULine(u->server))
00186 {
00187 ServerInstance->SNO->WriteToSnoMask('A', "NOTICE -- Service "+Aliases[i].requires+" required by alias "+std::string(Aliases[i].text.c_str())+" is not on a u-lined server, possibly underhanded antics detected!");
00188 user->WriteNumeric(401, ""+std::string(user->nick)+" "+Aliases[i].requires+" :is an imposter! Please inform an IRC operator as soon as possible.");
00189 return 1;
00190 }
00191 }
00192
00193
00194
00195 std::string::size_type crlf = Aliases[i].replace_with.find('\n');
00196
00197 if (crlf == std::string::npos)
00198 {
00199 DoCommand(Aliases[i].replace_with, user, safe);
00200 return 1;
00201 }
00202 else
00203 {
00204 irc::sepstream commands(Aliases[i].replace_with, '\n');
00205 std::string scommand;
00206 while (commands.GetToken(scommand))
00207 {
00208 DoCommand(scommand, user, safe);
00209 }
00210 return 1;
00211 }
00212 }
00213 }
00214 return 0;
00215 }
00216
00217 void DoCommand(std::string newline, User* user, const std::string &original_line)
00218 {
00219 for (int v = 1; v < 10; v++)
00220 {
00221 std::string var = "$";
00222 var.append(ConvToStr(v));
00223 var.append("-");
00224 std::string::size_type x = newline.find(var);
00225
00226 while (x != std::string::npos)
00227 {
00228 newline.erase(x, var.length());
00229 newline.insert(x, GetVar(var, original_line));
00230 x = newline.find(var);
00231 }
00232
00233 var = "$";
00234 var.append(ConvToStr(v));
00235 x = newline.find(var);
00236
00237 while (x != std::string::npos)
00238 {
00239 newline.erase(x, var.length());
00240 newline.insert(x, GetVar(var, original_line));
00241 x = newline.find(var);
00242 }
00243 }
00244
00245
00246 SearchAndReplace(newline, "$nick", user->nick);
00247 SearchAndReplace(newline, "$ident", user->ident);
00248 SearchAndReplace(newline, "$host", user->host);
00249 SearchAndReplace(newline, "$vhost", user->dhost);
00250
00251
00252 SearchAndReplace(newline, "\r", "$");
00253
00254 irc::tokenstream ss(newline);
00255 pars.clear();
00256 std::string command, token;
00257
00258 ss.GetToken(command);
00259 while (ss.GetToken(token) && (pars.size() <= MAXPARAMETERS))
00260 {
00261 pars.push_back(token);
00262 }
00263 ServerInstance->Parser->CallHandler(command, pars, user);
00264 }
00265
00266 virtual void OnRehash(User* user, const std::string ¶meter)
00267 {
00268 ReadAliases();
00269 }
00270 };
00271
00272 MODULE_INIT(ModuleAlias)