00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #ifndef USE_PCH
00017 #include "sys.h"
00018 #include "debug.h"
00019 #endif
00020
00021 #include "Matcher.h"
00022 #include "is_channel.h"
00023 #include "Identity.h"
00024 #include "match.h"
00025 #include "MessageIn.h"
00026
00027 bool Matcher_noarg::match_impl(ServerSession const& server_session, char const* start, size_t len)
00028 {
00029 switch(M_mt)
00030 {
00031 case anystring_mt:
00032 return true;
00033 case nonemptystring_mt:
00034 return len > 0;
00035 case anyserver_mt:
00036 {
00037 for (char const* p = start; p < start + len; ++p)
00038 if (*p == '.')
00039 return true;
00040 return false;
00041 }
00042 case localserver_mt:
00043 {
00044 Dout(dc::matcher|continued_cf, "localserver_mt: get_irc_name() = \"" <<
00045 server_session.server_connection().server()->get_irc_name() << "\"; input = \"" << buf2str(start, len) << "\", ");
00046 bool result = server_session.server_connection().server()->get_irc_name().compare(0, std::string::npos, start, len) == 0;
00047 Dout(dc::finish, "returning " << (result ? "true" : "false"));
00048 return result;
00049 }
00050 case anynick_mt:
00051 return len > 0 && !is_channel(start);
00052 case mynick_mt:
00053 {
00054 Dout(dc::matcher|continued_cf, "mynick_mt: server_in_nick() = \"" <<
00055 server_session.nicks().in_nick() << "\"; input = \"" << buf2str(start, len) << "\", ");
00056 bool result = server_session.nicks().in_nick().compare(0, std::string::npos, start, len) == 0;
00057 Dout(dc::finish, "returning " << (result ? "true" : "false"));
00058 return result;
00059 }
00060 case anychannel_mt:
00061 return len > 0 && is_channel(start);
00062 case anyglobalchannel_mt:
00063 return len > 0 && *start == '#';
00064 case anylocalchannel_mt:
00065 return len > 0 && *start == '&';
00066 }
00067
00068 return false;
00069 }
00070
00071 boost::shared_ptr<Matcher> Matcher::create(int param, match1_type mt, std::string const& arg, bool single_param)
00072 {
00073 boost::shared_ptr<Matcher> matcher;
00074 switch(mt)
00075 {
00076 case wildcard_mt:
00077 matcher.reset(NEW(Matcher_matchcomp(param, arg, single_param)));
00078 break;
00079 case regexp_mt:
00080 matcher.reset(NEW(Matcher_regexp(param, arg, single_param)));
00081 break;
00082 case exactmatch_mt:
00083 matcher.reset(NEW(Matcher_exactmatch(param, arg, single_param)));
00084 break;
00085 }
00086 return matcher;
00087 }
00088
00089 bool Matcher_regexp::match_impl(ServerSession const& LIBCW_UNUSED(server_session), char const* start, size_t len)
00090 {
00091 char c = start[len];
00092 const_cast<char*>(start)[len] = '\0';
00093 bool success = regexec(&M_regex, start, 0, NULL, 0) == 0;
00094 const_cast<char*>(start)[len] = c;
00095 return success;
00096 }
00097
00098 bool Matcher::match(ServerMessageIn const& msg)
00099 {
00100 MessageIn::Part const& part((M_param == prefix) ? msg.prefix_part() : msg.params()[M_param]);
00101 char const* start = part.start();
00102 size_t len = M_single_param ? part.len() : (msg.end() - start);
00103 Dout(dc::matcher|continued_cf, "Matching \"" << buf2str(start, len) << "\" against {" << cwprint(*this) << "} : ");
00104 bool result = match_impl(msg.server_session(), start, len);
00105 Dout(dc::finish, (result ? "(matched)" : "(did not match)"));
00106 return result;
00107 }
00108
00109 void MatcherEventRequestQueue::destroy_requests(void)
00110 {
00111 ASSERT(!M_event_requests_locked);
00112 while (!M_event_requests.empty())
00113 {
00114 M_event_requests.front()->release();
00115 M_event_requests.pop_front();
00116 }
00117 }
00118
00119 bool MatcherEventRequestQueue::trigger(MatcherEventRequestBase::event_type_ct const& event_type)
00120 {
00121 #if 0 // Too verbose.
00122 DoutEntering(dc::matcher, "MatcherEventRequestQueue::trigger(" <<
00123 libcwd::type_info_of<MatcherEventRequestBase::event_type_ct>().demangled_name() <<
00124 " const& " << event_type << ")");
00125 #endif
00126 bool sink = false;
00127 {
00128 ASSERT(M_event_requests_locked > 0 || M_event_requests_tmp.empty());
00129 Increment tmp(M_event_requests_locked);
00130 event_requests_ct::iterator iter = M_event_requests.begin();
00131 while (iter != M_event_requests.end())
00132 {
00133 if ((*iter)->canceled())
00134 {
00135 Dout(dc::matcher, "Removing canceled " << **iter);
00136 (*iter)->release();
00137 iter = M_event_requests.erase(iter);
00138 }
00139 else if ((*iter)->request_data().is_match(event_type.message()))
00140 {
00141 Dout(dc::matcher, "Calling handle() for " << **iter);
00142 (*iter)->handle(event_type);
00143 sink = (*iter)->request_data().sink();
00144 (*iter)->release();
00145 iter = M_event_requests.erase(iter);
00146 }
00147 else
00148 ++iter;
00149 }
00150 }
00151 if (M_event_requests_locked == 0)
00152 while (!M_event_requests_tmp.empty())
00153 {
00154 add_request(M_event_requests_tmp.front());
00155 M_event_requests_tmp.pop_front();
00156 }
00157 return sink;
00158 }
00159
00160 bool MatchRequestList::check_list(ServerMessageIn const& msg) const
00161 {
00162 for (std::multiset<boost::shared_ptr<Matcher> >::const_iterator iter = M_conditions.begin();
00163 iter != M_conditions.end(); ++iter)
00164 {
00165 if (!(*iter)->match(msg))
00166 return false;
00167 }
00168 return true;
00169 }