Improve include dependencies
[clinton/bobotpp.git] / source / Utils.C
1 // Utils.C -*- C++ -*-
2 // Copyright (c) 1997, 1998 Etienne BERNARD
3 // Copyright (c) 2005,2008 Clinton Ebadi
4
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 2 of the License, or
8 // any later version.
9
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
14
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18
19 #ifdef HAVE_CONFIG_H
20 #include "config.h"
21 #endif
22
23 #include "Utils.H"
24
25 #include <string>
26 #include <sstream>
27
28 #include <cctype>
29 #include <cstdlib>
30
31 #include "Bot.H"
32 #include "ChannelList.H"
33 #include "StringTokenizer.H"
34 #include "User.H"
35 #include "UserList.H"
36
37 std::string
38 Utils::get_nick (std::string nuh)
39 {
40 StringTokenizer st(nuh);
41 return st.next_token('!');
42 }
43
44 std::string
45 Utils::get_userhost (std::string nuh)
46 {
47 StringTokenizer st(nuh);
48 st.next_token('@');
49 return st.rest();
50 }
51
52 std::string
53 Utils::get_key()
54 {
55 return long2str (std::rand());
56 }
57
58 bool
59 Utils::IP_p (std::string host)
60 {
61 for (std::string::size_type i = 0; i < host.length(); i++)
62 if (!std::isdigit (host[i]) && host[i] !='.')
63 return false;
64 return true;
65 }
66
67 std::string
68 Utils::make_wildcard (std::string mask)
69 {
70 StringTokenizer st (mask);
71
72 st.next_token('!', true);
73 std::string nick = "*";
74
75 std::string user = st.next_token('@', true);
76 if (user[0] == '~' || user[0] == '^' ||
77 user[0] == '+' || user[0] == '-' ||
78 user[0] == '*')
79 user = user.substr (1);
80 if (user.length() < 10)
81 user = std::string("*") + user;
82
83 std::string host = st.rest();
84 StringTokenizer st2(host);
85
86 if (!wildcard_p (host))
87 {
88 if (IP_p (host))
89 {
90 host = st2.next_token('.') + ".";
91 host = host + st2.next_token('.') + ".";
92 host = host + st2.next_token('.') + ".*";
93 }
94 else
95 {
96 st2.next_token('.', true);
97 if (st2.count_tokens('.') > 1)
98 host = std::string("*.") + st2.rest();
99 }
100 }
101 else
102 {
103 if (host == "") host = "*";
104 }
105
106 std::cout << nick + "!" + user + "@" + host << std::endl;
107
108 return nick + "!" + user + "@" + host;
109 }
110
111 bool
112 Utils::channel_p(std::string c)
113 {
114 return (c[0] == '#' || c[0] == '&');
115 }
116
117 bool
118 Utils::wildcard_p (std::string c)
119 {
120 return (c.find('*') != std::string::npos);
121 }
122
123 bool
124 Utils::valid_channel_name_p (std::string c)
125 {
126 return channel_p (c) && c.find(',') == std::string::npos;
127 }
128
129 #define isvalid(c) (((c) >= 'A' && (c) <= '~') || std::isdigit(c) || (c) == '-')
130
131 bool
132 Utils::valid_nickname_p (const Bot *b, std::string n)
133 {
134 // FIXME: make max nick length configurable
135 if (n[0] == '-' || std::isdigit(n[0]) || n.length() > b->MAX_NICKLENGTH)
136 return false;
137
138 for (std::string::size_type i = 0; i < n.length(); i++)
139 if (!isvalid(n[i]) || std::isspace (n[i]))
140 return false;
141
142 return true;
143 }
144
145 int
146 Utils::get_level (Bot * b, std::string nuh)
147 {
148 return b->userList->getMaxLevel(nuh);
149 }
150
151 int
152 Utils::get_level (Bot * b, std::string nuh, std::string channel)
153 {
154 if (!channel_p (channel))
155 return get_level(b, nuh);
156
157 if (Channel * c = b->channelList->getChannel(channel))
158 {
159 User * u = c->getUser(get_nick (nuh));
160 if (u)
161 return u->getLevel();
162 }
163 else {
164 return -1;
165 }
166
167 return b->userList->getLevel(nuh, channel);
168 }
169
170 std::string
171 Utils::level2str(int l)
172 {
173 switch (l)
174 {
175 case User::USER: return "User";
176 case User::TRUSTED_USER: return "Trusted User";
177 case User::FRIEND: return "Friend";
178 case User::MASTER: return "Master";
179 }
180
181 return "None";
182 }
183
184 std::string
185 Utils::prot2str(int p)
186 {
187 switch (p)
188 {
189 case User::NO_BAN: return "No ban";
190 case User::NO_KICK: return "No kick";
191 case User::NO_DEOP: return "No deop";
192 }
193
194 return "None";
195 }
196
197 std::string
198 Utils::bool2str(bool b)
199 {
200 // FIXME: should these be lowercase?
201 return b ? "True" : "False";
202 }
203
204 std::string
205 Utils::long2str (long l)
206 {
207 std::ostringstream temp;
208 temp << l;
209
210 return temp.str ();
211 }
212
213 time_t
214 Utils::str2time(std::string str)
215 {
216 std::string num;
217 time_t ans = 0;
218
219 // Make sure that str is nominally valid before allocating a buffer
220 if (to_lower (str) == "inf")
221 return -1;
222
223 if (!std::isdigit (str[0]))
224 return 0;
225
226 num.reserve (64); // reserve a buffer to speed things up
227
228 for (std::string::size_type i = 0; i < str.length(); i++)
229 {
230 switch (str[i])
231 {
232 case 'y':
233 case 'Y':
234 ans += (std::atoi (num.c_str ()) * 31557600);
235 num.clear ();
236 break;
237 case 'M':
238 ans += (std::atoi (num.c_str ()) * 2629800);
239 num.clear ();
240 break;
241 case 'd':
242 case 'D':
243 ans += (std::atoi (num.c_str ()) * 86400);
244 num.clear ();
245 break;
246 case 'h':
247 case 'H':
248 ans += (std::atoi (num.c_str ()) * 3600);
249 num.clear ();
250 break;
251 case 'm':
252 ans += (std::atoi (num.c_str ()) * 60);
253 num.clear ();
254 break;
255 case 's':
256 case 'S':
257 ans += std::atoi (num.c_str ());
258 num.clear ();
259 default:
260 if (std::isdigit(str[i]))
261 num += str[i];
262 else
263 return 0;
264 }
265 }
266
267 if (!num.empty ())
268 ans += std::atoi (num.c_str ());
269
270 return std::time (0) + ans;
271 }
272
273 std::string
274 Utils::to_lower (std::string s)
275 {
276 std::string::iterator it;
277
278 for (it = s.begin (); it != s.end (); ++it)
279 *it = std::tolower (*it);
280
281 return s;
282 }
283
284 std::string
285 Utils::to_upper (std::string s)
286 {
287 std::string::iterator it;
288
289 for (it = s.begin (); it != s.end (); it++)
290 *it = std::toupper (*it);
291
292 return s;
293 }
294
295 std::string
296 Utils::trim_str (std::string s)
297 {
298 int i = 0, j = s.length () - 1;
299
300 while (i < j && std::isspace (s[i]))
301 i++;
302
303 while (j > 0 && std::isspace (s[j]))
304 j--;
305
306 return s.substr (i, j - i + 1);
307 }
308
309 #ifdef USESCRIPTS
310 // Returns a std::string from an SCM argument
311 std::string
312 Utils::scm2str (SCM s)
313 {
314 // FIXME: uses gh_, replace with scm_
315 char *tmp = scm_to_locale_string (s);
316 std::string temp (tmp);
317
318 free(tmp);
319
320 return temp;
321 }
322
323 // Returns a SCM from an std::string argument
324 SCM
325 Utils::str2scm (std::string s)
326 {
327 return scm_from_locale_string (s.c_str ());
328 }
329 #endif