// Utils.C -*- C++ -*- // Copyright (c) 1997, 1998 Etienne BERNARD // Copyright (c) 2005,2008 Clinton Ebadi // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "Utils.H" #include #include #include #include #include "Bot.H" #include "ChannelList.H" #include "StringTokenizer.H" #include "User.H" #include "UserList.H" std::string Utils::get_nick (std::string nuh) { StringTokenizer st(nuh); return st.next_token('!'); } std::string Utils::get_userhost (std::string nuh) { StringTokenizer st(nuh); st.next_token('@'); return st.rest(); } std::string Utils::get_key() { return long2str (std::rand()); } bool Utils::IP_p (std::string host) { for (std::string::size_type i = 0; i < host.length(); i++) if (!std::isdigit (host[i]) && host[i] !='.') return false; return true; } std::string Utils::make_wildcard (std::string mask) { StringTokenizer st (mask); std::cerr << "make_wildcard: \"" << mask << "\"\n"; st.next_token('!', true); std::string nick = "*"; std::string user = st.next_token('@', true); if (user[0] == '~' || user[0] == '^' || user[0] == '+' || user[0] == '-' || user[0] == '*') user = user.substr (1); if (user.length() < 10) user = std::string("*") + user; std::string host = st.rest(); StringTokenizer st2(host); if (!wildcard_p (host)) { if (IP_p (host)) { host = st2.next_token('.') + "."; host = host + st2.next_token('.') + "."; host = host + st2.next_token('.') + ".*"; } else { st2.next_token('.', true); if (st2.count_tokens('.') > 1) host = std::string("*.") + st2.rest(); } } else { if (host == "") host = "*"; } return nick + "!" + user + "@" + host; } bool Utils::channel_p(std::string c) { return (c[0] == '#' || c[0] == '&'); } bool Utils::wildcard_p (std::string c) { return (c.find('*') != std::string::npos); } bool Utils::valid_channel_name_p (std::string c) { return channel_p (c) && c.find(',') == std::string::npos; } #define isvalid(c) (((c) >= 'A' && (c) <= '~') || std::isdigit(c) || (c) == '-') bool Utils::valid_nickname_p (const Bot *b, std::string n) { // FIXME: make max nick length configurable if (n[0] == '-' || std::isdigit(n[0]) || n.length() > b->MAX_NICKLENGTH) return false; for (std::string::size_type i = 0; i < n.length(); i++) if (!isvalid(n[i]) || std::isspace (n[i])) return false; return true; } int Utils::get_level (Bot * b, std::string nuh) { return b->userList->getMaxLevel(nuh); } int Utils::get_level (Bot * b, std::string nuh, std::string channel) { if (!channel_p (channel)) return get_level(b, nuh); Channel * c = b->channelList->getChannel(channel); if (c && c->hasNick (get_nick (nuh))) return c->getUser(get_nick (nuh)).getLevel (); else return -1; return b->userList->getLevel(nuh, channel); } std::string Utils::level2str(int l) { switch (l) { case User::USER: return "User"; case User::TRUSTED_USER: return "Trusted User"; case User::FRIEND: return "Friend"; case User::MASTER: return "Master"; } return "None"; } std::string Utils::prot2str(int p) { switch (p) { case User::NO_BAN: return "No ban"; case User::NO_KICK: return "No kick"; case User::NO_DEOP: return "No deop"; } return "None"; } std::string Utils::bool2str(bool b) { // FIXME: should these be lowercase? return b ? "True" : "False"; } std::string Utils::long2str (long l) { std::ostringstream temp; temp << l; return temp.str (); } time_t Utils::str2time(std::string str) { std::string num; time_t ans = 0; // Make sure that str is nominally valid before allocating a buffer if (to_lower (str) == "inf") return -1; if (!std::isdigit (str[0])) return 0; num.reserve (64); // reserve a buffer to speed things up for (std::string::size_type i = 0; i < str.length(); i++) { switch (str[i]) { case 'y': case 'Y': ans += (std::atoi (num.c_str ()) * 31557600); num.clear (); break; case 'M': ans += (std::atoi (num.c_str ()) * 2629800); num.clear (); break; case 'd': case 'D': ans += (std::atoi (num.c_str ()) * 86400); num.clear (); break; case 'h': case 'H': ans += (std::atoi (num.c_str ()) * 3600); num.clear (); break; case 'm': ans += (std::atoi (num.c_str ()) * 60); num.clear (); break; case 's': case 'S': ans += std::atoi (num.c_str ()); num.clear (); default: if (std::isdigit(str[i])) num += str[i]; else return 0; } } if (!num.empty ()) ans += std::atoi (num.c_str ()); return std::time (0) + ans; } std::string Utils::to_lower (std::string s) { std::string::iterator it; for (it = s.begin (); it != s.end (); ++it) *it = std::tolower (*it); return s; } std::string Utils::to_upper (std::string s) { std::string::iterator it; for (it = s.begin (); it != s.end (); it++) *it = std::toupper (*it); return s; } std::string Utils::trim_str (std::string s) { int i = 0, j = s.length () - 1; while (i < j && std::isspace (s[i])) i++; while (j > 0 && std::isspace (s[j])) j--; return s.substr (i, j - i + 1); } #ifdef USESCRIPTS // Returns a std::string from an SCM argument std::string Utils::scm2str (SCM s) { // FIXME: uses gh_, replace with scm_ char *tmp = scm_to_locale_string (s); std::string temp (tmp); free(tmp); return temp; } // Returns a SCM from an std::string argument SCM Utils::str2scm (std::string s) { return scm_from_locale_string (s.c_str ()); } #endif