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