diff options
-rw-r--r-- | src/modules/extra/m_regex.h | 4 | ||||
-rw-r--r-- | src/modules/extra/m_regex_posix.cpp | 113 |
2 files changed, 115 insertions, 2 deletions
diff --git a/src/modules/extra/m_regex.h b/src/modules/extra/m_regex.h index 441d1c0df..7670582c3 100644 --- a/src/modules/extra/m_regex.h +++ b/src/modules/extra/m_regex.h @@ -11,8 +11,8 @@ * --------------------------------------------------- */ -#ifndef _REGEX_H -#define _REGEX_H +#ifndef _M_REGEX_H +#define _M_REGEX_H #include "inspircd.h" diff --git a/src/modules/extra/m_regex_posix.cpp b/src/modules/extra/m_regex_posix.cpp new file mode 100644 index 000000000..1a1d8e305 --- /dev/null +++ b/src/modules/extra/m_regex_posix.cpp @@ -0,0 +1,113 @@ +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * InspIRCd: (C) 2002-2008 InspIRCd Development Team + * See: http://www.inspircd.org/wiki/index.php/Credits + * + * This program is free but copyrighted software; see + * the file COPYING for details. + * + * --------------------------------------------------- + */ + +#include "inspircd.h" +#include "m_regex.h" +#include <sys/types.h> +#include <regex.h> + +/* $ModDesc: Regex Provider Module for POSIX Regular Expressions */ +/* $ModDep: m_regex.h */ + +class POSIXRegexException : public ModuleException +{ +public: + POSIXRegexException(const std::string& rx, const std::string& error) + : ModuleException(std::string("Error in regex ") + rx + ": " + error) + { + } +}; + +class POSIXRegex : public Regex +{ +private: + regex_t regbuf; + +public: + POSIXRegex(const std::string& rx, InspIRCd* Me, bool extended) : Regex(rx, Me) + { + int flags = (extended ? REG_EXTENDED : 0) | REG_NOSUB; + int errcode; + errcode = regcomp(®buf, rx.c_str(), flags); + if (errcode) + { + // Get the error string into a std::string. YUCK this involves at least 2 string copies. + std::string error; + char* errbuf; + size_t sz = regerror(errcode, ®buf, NULL, 0); + errbuf = new char[sz + 1]; + memset(errbuf, 0, sz + 1); + regerror(errcode, ®buf, errbuf, sz + 1); + error = errbuf; + delete[] errbuf; + regfree(®buf); + throw POSIXRegexException(rx, error); + } + } + + virtual ~POSIXRegex() + { + regfree(®buf); + } + + virtual bool Matches(const std::string& text) + { + if (regexec(®buf, text.c_str(), 0, NULL, 0) == 0) + { + // Bang. :D + return true; + } + return false; + } +}; + +class ModuleRegexPOSIX : public Module +{ +private: + bool extended; +public: + ModuleRegexPOSIX(InspIRCd* Me) : Module(Me) + { + Me->Modules->PublishInterface("RegularExpression", this); + Implementation eventlist[] = { I_OnRequest, I_OnRehash }; + Me->Modules->Attach(eventlist, this, 1); + OnRehash(NULL, ""); + } + + virtual ~ModuleRegexPOSIX() + { + ServerInstance->Modules->UnpublishInterface("RegularExpression", this); + } + + virtual void OnRehash(User* u, const std::string& parameter) + { + ConfigReader Conf(ServerInstance); + extended = Conf.ReadFlag("posix", "extended", 0); + } + + virtual const char* OnRequest(Request* request) + { + if (strcmp("REGEX-NAME", request->GetId()) == 0) + { + return "posix"; + } + else if (strcmp("REGEX", request->GetId()) == 0) + { + RegexFactoryRequest* rfr = (RegexFactoryRequest*)request; + std::string rx = rfr->GetRegex(); + rfr->result = new POSIXRegex(rx, ServerInstance, extended); + return "OK"; + } + return NULL; + } +}; |