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 "WhoRequest.h"
00022 #include "is_channel.h"
00023 #include "ircd_chattr.h"
00024 #include "Channel.h"
00025 #include "Nick.h"
00026 #include "exceptions.h"
00027 #include "ClientSession.h"
00028
00029 WhoOptions::WhoOptions(std::string const& options) : M_fields(0)
00030 {
00031 std::string::size_type pos1 = options.find('%');
00032 M_flags = options.substr(0, pos1);
00033 std::string::size_type pos2 = options.find(',');
00034 if (pos1 == std::string::npos)
00035 pos2 = std::string::npos;
00036 else
00037 M_fields = field_percentage;
00038 if (pos2 != std::string::npos)
00039 M_querytype = options.substr(pos2 + 1);
00040 std::string fields_str;
00041 if (pos1 != std::string::npos)
00042 fields_str = options.substr(pos1 + 1, pos2 - pos1 - 1);
00043 for (std::string::iterator c = fields_str.begin(); c != fields_str.end(); ++c)
00044 {
00045 switch(*c)
00046 {
00047 case 'c':
00048 M_fields |= field_c;
00049 break;
00050 case 'd':
00051 M_fields |= field_d;
00052 break;
00053 case 'f':
00054 M_fields |= field_f;
00055 break;
00056 case 'h':
00057 M_fields |= field_h;
00058 break;
00059 case 'i':
00060 M_fields |= field_i;
00061 break;
00062 case 'l':
00063 M_fields |= field_l;
00064 break;
00065 case 'n':
00066 M_fields |= field_n;
00067 break;
00068 case 'r':
00069 M_fields |= field_r;
00070 break;
00071 case 's':
00072 M_fields |= field_s;
00073 break;
00074 case 't':
00075 M_fields |= field_t;
00076 break;
00077 case 'u':
00078 M_fields |= field_u;
00079 break;
00080 case 'a':
00081 M_fields |= field_a;
00082 break;
00083 case 'o':
00084 M_fields |= field_o;
00085 break;
00086 }
00087 }
00088 }
00089
00090 std::string WhoOptions::str(void) const
00091 {
00092 std::string result(M_flags);
00093 if (M_fields != 0)
00094 result += '%';
00095 for (unsigned int field = 1; field < field_percentage; field <<= 1)
00096 if ((M_fields & field))
00097 switch(field)
00098 {
00099 case field_c:
00100 result += 'c';
00101 break;
00102 case field_d:
00103 result += 'd';
00104 break;
00105 case field_f:
00106 result += 'f';
00107 break;
00108 case field_h:
00109 result += 'h';
00110 break;
00111 case field_i:
00112 result += 'i';
00113 break;
00114 case field_l:
00115 result += 'l';
00116 break;
00117 case field_n:
00118 result += 'n';
00119 break;
00120 case field_r:
00121 result += 'r';
00122 break;
00123 case field_s:
00124 result += 's';
00125 break;
00126 case field_t:
00127 result += 't';
00128 break;
00129 case field_u:
00130 result += 'u';
00131 break;
00132 case field_a:
00133 result += 'a';
00134 break;
00135 case field_o:
00136 result += 'o';
00137 break;
00138 }
00139 if (!M_querytype.empty())
00140 {
00141 if (M_fields == 0)
00142 result += '%';
00143 result += ',';
00144 result += M_querytype;
00145 }
00146 return result;
00147 }
00148
00149 bool WhoOptions::matches_against_channel(void) const
00150 {
00151 return (M_fields & ~field_percentage) == 0 || ((M_fields & field_c) == field_c);
00152 }
00153
00154 void WhoRequest::decode_mask(ClientSession& client_session)
00155 {
00156 DoutEntering(dc::debug, "WhoRequest::decode_mask(" << client_session << ")");
00157 M_mask_contains_space = false;
00158 bool mask_is_channel = is_channel(M_mask) && (M_mask[0] != '@');
00159 bool mask_is_nick = is_nick(M_mask);
00160 for (std::string::iterator iter = M_mask.begin(); iter != M_mask.end(); ++iter)
00161 {
00162 char c = *iter;
00163 if (c == ' ')
00164 {
00165 M_mask_contains_space = true;
00166 mask_is_channel = false;
00167 mask_is_nick = false;
00168 break;
00169 }
00170 if (!IsChannelChar(c))
00171 mask_is_channel = false;
00172 if (!IsNickChar(c))
00173 mask_is_nick = false;
00174 }
00175 if (mask_is_channel)
00176 {
00177 try
00178 {
00179
00180 M_mask_is_target = true;
00181 }
00182 catch(unknown_target& error)
00183 {
00184 Debug(edragon::caught(error));
00185 M_mask_is_target = false;
00186 }
00187 }
00188 else if (mask_is_nick)
00189 {
00190 try
00191 {
00192 M_target = boost::static_pointer_cast<Target>(client_session.get_nick(M_mask));
00193 M_mask_is_target = true;
00194 }
00195 catch(unknown_target& error)
00196 {
00197 Debug(edragon::caught(error));
00198 M_mask_is_target = false;
00199 }
00200 }
00201 else
00202 M_mask_is_target = false;
00203 #ifdef CWDEBUG
00204 if (M_mask_contains_space)
00205 Dout(dc::debug, "WHO mask contains a space");
00206 if (M_mask_is_target)
00207 Dout(dc::debug, "WHO matches the target: " << M_target);
00208 #endif
00209 }