Quiet annoying mutex debug logging messages
[clinton/bobotpp.git] / source / UserCommands.C
index 0ad6ba7..0e654e1 100644 (file)
@@ -24,6 +24,7 @@
 #include "UserCommands.H"
 
 #include <fstream>
+#include <functional>
 #include <map>
 #include <string>
 
@@ -66,7 +67,6 @@
 #include "ServerList.H"
 #include "ShitEntry.H"
 #include "StringTokenizer.H"
-#include "TodoList.H"
 #include "User.H"
 #include "UserList.H"
 #include "Utils.H"
@@ -129,17 +129,17 @@ UserCommands::AddUser(ServerConnection *cnx, Person *from,
   bool a;
   time_t e;
   
-  l = atoi((const char *)level);
+  l = atoi(level.c_str ());
   if (l < 0 || l > User::FRIEND)
     return;
   if (l > Utils::get_level(cnx->bot, from->getAddress())) {
     from->sendNotice("\002You can not give a level greater than yours.\002");
     return;
   }
-  p = atoi((const char *)prot);
+  p = atoi(prot.c_str ());
   if (p < 0 || p > User::NO_DEOP)
     return;
-  a = (bool)atoi((const char *)aop);
+  a = (bool)atoi(aop.c_str ());
   if (a != 0 && a != 1)
     return;
 
@@ -184,7 +184,7 @@ UserCommands::AddServer(ServerConnection *cnx, Person *from,
 
   if (st.more_tokens_p()) {
     String temp = st.next_token();
-    port = atoi((const char *)temp);
+    port = atoi(temp.c_str ());
   }
 
   Message m = Commands::AddServer(cnx->bot, serverName, port);
@@ -240,7 +240,7 @@ UserCommands::AddShit(ServerConnection *cnx, Person *from,
   int l;
   time_t e;
 
-  l = atoi((const char *)level);
+  l = atoi(level.c_str ());
   if (l < 0 || l > ShitEntry::SHIT_NODEBAN)
     return;
 
@@ -318,22 +318,31 @@ UserCommands::Ban(ServerConnection *cnx, Person *from,
     from->sendNotice(m.getMessage());
 }
 
+namespace
+{
+  void print_ban_list (Person * from, const BanEntry * b)
+  {
+    if (b->getExpirationDate() == -1)
+      from->sendNotice(b->getMask().getMask().pad(30) + " -1");
+    else
+      from->sendNotice(b->getMask().getMask().pad(30) + " " + 
+                      String((long)(b->getExpirationDate() - std::time (0))));
+  }
+}
+
 void
 UserCommands::BanList(ServerConnection *cnx, Person *from,
                       String channel, String rest)
 {
-  time_t current = time(0);
   Channel *c = cnx->bot->channelList->getChannel(channel);
+
   from->sendNotice(String("\002Banlist for channel\002 ") +
                    channel + "\002:\002");
   from->sendNotice("\002Mask                           Expires (seconds)\002");
-  for (std::vector<BanEntry *>::iterator it = c->channelBanlist.begin();
-       it != c->channelBanlist.end(); ++it)
-    if ((*it)->getExpirationDate() == -1)
-      from->sendNotice((*it)->getMask().getMask().pad(30) + " -1");
-    else
-      from->sendNotice((*it)->getMask().getMask().pad(30) + " " + 
-                       String((long)((*it)->getExpirationDate()-current)));
+
+  c->for_each_ban_entry (std::bind1st (std::ptr_fun (print_ban_list),
+                                      from));
+
   from->sendNotice("\002End of banlist.\002");
 }
 
@@ -408,7 +417,7 @@ UserCommands::Channels(ServerConnection *cnx, Person *from,
   if (result == "")
     from->sendNotice("\002I am not on any channel.\002");
   else
-    from->sendNotice(String("\002I am currently on channel(s):\002 ") +
+    from->sendNotice(String("\002I am currently on channel(s):\002 ")
                       + result);
 }
 
@@ -466,7 +475,7 @@ UserCommands::DelServer(ServerConnection *cnx, Person *from,
     return;
   }
 
-  int serverNumber = atoi(rest);
+  int serverNumber = atoi(rest.c_str ());
 
   Message m = Commands::DelServer(cnx->bot, serverNumber);
   if (m.getCode() != 0)
@@ -631,7 +640,7 @@ UserCommands::Help(ServerConnection *cnx, Person *from,
 
   StringTokenizer st(rest);
   String command = Utils::to_upper (st.next_token());
-  std::ifstream helpFile(cnx->bot->helpFileName);
+  std::ifstream helpFile(cnx->bot->helpFileName.c_str ());
 
   if (!helpFile) {
     from->sendNotice(String("\002Error: I can not find the "
@@ -672,36 +681,41 @@ UserCommands::Ident(ServerConnection *cnx, Person *from,
     return;
   }
 
-  User * u = c->getUser(from->getNick());
-  if (!u) {
-    from->sendNotice(String("\002You can identify yourself on"
-                     " channel\002 ") + channel +
-                     " \002only if you are on the channel.\002");
-    return;
-  }
-
-  if (u->userListItem && u->userListItem->identified) {
-    from->sendNotice(String("\002You are already identified on"
-                     " channel\002 ") + channel);
-    return;
-  }
-
-  if (!u->userListItem) {
-    from->sendNotice("\002You are not in my userlist.\002");
-    return;
-  }
-
-  if (u->userListItem->passwd ==
-      crypt((const char *)rest, (const char *)u->userListItem->passwd)) {
-    // For each channel, we increment identification counter
-    for (std::map<String, Channel *, std::less<String> >::iterator it =
-           cnx->bot->channelList->begin();
-         it != cnx->bot->channelList->end(); ++it)
-      u->userListItem->identified++;
-
-    from->sendNotice("\002You are now identified.\002");
-  } else
-    from->sendNotice("\002This is a wrong password.\002");
+  try
+    {
+      User u = c->getUser(from->getNick());
+      
+      if (u.userListItem && u.userListItem->identified) {
+       from->sendNotice(String("\002You are already identified on"
+                               " channel\002 ") + channel);
+       return;
+      }
+      
+      if (!u.userListItem) {
+       from->sendNotice("\002You are not in my userlist.\002");
+       return;
+      }
+      
+      if (u.userListItem->passwd ==
+         crypt(rest.c_str (), u.userListItem->passwd.c_str ())) {
+       // For each channel, we increment identification counter
+       // fixme: is this logic correct?
+       for (std::map<String, Channel *, std::less<String> >::iterator it =
+              cnx->bot->channelList->begin();
+            it != cnx->bot->channelList->end(); ++it)
+         u.userListItem->identified++;
+       
+       from->sendNotice("\002You are now identified.\002");
+      } else
+       from->sendNotice("\002This is a wrong password.\002");
+    }
+  catch (ChannelUserList::user_not_found &e)
+    {
+      from->sendNotice(String("\002You can identify yourself on"
+                             " channel\002 ") + channel +
+                      " \002only if you are on the channel.\002");
+      return;
+    }
 }
 
 void
@@ -758,13 +772,10 @@ UserCommands::Keep(ServerConnection *cnx, Person *from,
                     channel);
 }
 
-// FIXME: Convert
 void
 UserCommands::Kick(ServerConnection *cnx, Person *from,
                    String channel, String rest)
 {
-  String nick = from->getNick();
-
   Channel * c = cnx->bot->channelList->getChannel(channel);
 
   if (rest.length() == 0) {
@@ -776,46 +787,25 @@ UserCommands::Kick(ServerConnection *cnx, Person *from,
   String who = st.next_token();
 
   if (Utils::wildcard_p(who)) {
-    User * u = c->getUser(nick);
-    if (!u)
-      return;
-    if (u->getLevel() < User::TRUSTED_USER) {
-      from->sendNotice("\002You need an higher level to "
-                       "use wildcards.\002");
-      return;
-    }
-  }
-
-  if (!cnx->bot->iAmOp(channel)) {
-    from->sendNotice(String("\002I am not channel op on\002 ") +
-                     channel);
-    return;
-  }
+    try
+      {
+       User u = c->getUser(from->getNick ());
 
-  if (Utils::wildcard_p(who)) {
-    Mask m(who);
-    for (std::map<String, User *, std::less<String> >::iterator it =
-           c->channelMemory.begin();
-         it != c->channelMemory.end();
-         ++it)
-      if (m.matches((*it).second->nick + "!" +
-                    (*it).second->userhost) &&
-          (*it).second->getProt() < User::NO_KICK)
-        cnx->queue->sendKick(channel, (*it).second->nick, st.rest());
-  } else {
-    User * u = c->getUser(who);
-    if (!u) {
-      from->sendNotice(String("\002I can not find\002 ") +
-                       who + " \002on\002 " + channel);
-      return;
-    }
-    if (u->getProt() < User::NO_KICK)
-      cnx->queue->sendKick(channel, who, st.rest());
-    else
-      from->sendNotice(String("\002I can not kick\002 ") +
-                        who + " \002on\002 " + channel +
-                        " \002(protected).\002");
+       if (u.getLevel() < User::TRUSTED_USER) {
+         from->sendNotice("\002You need an higher level to "
+                          "use wildcards.\002");
+         return;
+       }
+      }
+    catch (const ChannelUserList::user_not_found &)
+      {
+       return;
+      }
   }
+  
+  Message ret = Commands::Kick (cnx->bot, channel, who, st.rest ());
+  if (ret.getCode () != 0)
+    from->sendNotice (ret.getMessage ());
 }
 
 // FIXME: Convert
@@ -894,31 +884,36 @@ UserCommands::Msg(ServerConnection *cnx, Person *from,
     from->sendNotice(m.getMessage());
 }
 
+UserCommands::map_names::map_names (Person *f, std::string &r)
+  : from (f), result (r), length (0)
+{ }
+
+void
+UserCommands::map_names::operator() (const User &user)
+{
+  result += (user.mode & User::OP_MODE ? "@" :
+            (user.mode & User::VOICE_MODE ? "+" : ""))  +  user.nick + " ";
+  length += user.nick.length() + 1;
+  
+  if (length >= 256) {
+    from->sendNotice(result);
+    result = ""; length = 0;
+  }
+}
+
 void
 UserCommands::Names(ServerConnection *cnx, Person *from,
                      String channel, String rest)
 {
   String nick = from->getNick();
-  String result = "";
-  int length = 0;
   Channel *c = cnx->bot->channelList->getChannel(channel);
-  std::map<String, User *, std::less<String> >::iterator it;
+  std::string result;
 
   from->sendNotice(String("\002Names on ") +
                     channel + ":\002");
 
-  for (it = c->channelMemory.begin();
-       it != c->channelMemory.end(); ++it) {
-    result = result +
-      ((*it).second->mode & User::OP_MODE ? "@" :
-       ((*it).second->mode & User::VOICE_MODE ? "+" : "")) +
-      (*it).second->nick + " ";
-    length += (*it).first.length() + 1;
-    if (length >= 256) {
-      from->sendNotice(result);
-      result = ""; length = 0;
-    }
-  }
+  map_names f (from, result);
+  c->for_each_channel_users (f);
 
   if (result != "")
     from->sendNotice(result);
@@ -1003,7 +998,7 @@ UserCommands::NsLookup(ServerConnection *cnx, Person *from,
   struct in_addr iaddr;
 
   if (isdigit(target[0])) { // An IP ?
-    iaddr.s_addr = inet_addr((const char *)target);
+    iaddr.s_addr = inet_addr(target.c_str ());
     host = gethostbyaddr((char *)(&iaddr),
                          sizeof(struct in_addr),
                          AF_INET);
@@ -1014,7 +1009,7 @@ UserCommands::NsLookup(ServerConnection *cnx, Person *from,
       return;
     }
   } else {
-    host = gethostbyname((const char *)target);
+    host = gethostbyname(target.c_str ());
     if (host) {
       std::memcpy((char *)&iaddr, (char *)host->h_addr,
             host->h_length);
@@ -1028,106 +1023,70 @@ UserCommands::NsLookup(ServerConnection *cnx, Person *from,
                     target);
 }
 
-// FIXME: Convert
 void
 UserCommands::Op(ServerConnection *cnx, Person *from,
                  String channel, String rest)
 {
-  String nick = from->getNick();
-
-  if (!cnx->bot->iAmOp(channel)) {
-    from->sendNotice(String("\002I am not channel op on\002 ") +
-                     channel);
-    return;
-  }
-
-  if (Utils::wildcard_p(rest)) {
-    from->sendNotice("\002Mass op is not allowed.\002");
-    return;
-  }
-
-  String target;
-
-  if (rest.length() == 0)
-    target = nick;
-  else
-    target = rest;
-
-  User *u = cnx->bot->channelList->getChannel(channel)->getUser(target);
-  if (!u) {
-    from->sendNotice(String("\002I cannot find\002 ") + target + " \002on channel\002 " + channel);
-    return;
-  }
-
-  ShitEntry *se = cnx->bot->shitList->getShit(target, channel);
-  if (se && se->isStillValid() && se->getShitLevel() >= ShitEntry::SHIT_NOOP) {
-    from->sendNotice(String("\002I can not op\002 ")+target+" \002on channel\002 "+channel+" \002(shitlist).\002");
-    return;
-  }
-
-  if (!(u->mode & User::OP_MODE))
-    cnx->queue->sendChannelMode(channel, "+o", target);
-  else {
-    if (target == nick)
-      from->sendNotice(String("\002You are already channel "
-                              "operator on\002 ") + channel);
-    else
-      from->sendNotice(target + " \002is already channel "
-                       "operator on\002 " + channel);
-  }
+  Message ret = Commands::Op (cnx->bot, channel, 
+                             rest.length () == 0 ? from->getNick () : rest);
+  
+  if (ret.getCode () != 0)
+    from->sendNotice (ret.getMessage ());
 }
 
-// FIXME: Convert
 void
 UserCommands::Part(ServerConnection *cnx, Person *from,
                    String channel, String rest)
 {
-  wantedChannel *w = cnx->bot->wantedChannels[channel];
-  cnx->bot->wantedChannels.erase(channel);
-  delete w;
-  cnx->queue->sendPart(channel);
+  Message ret = Commands::Part (cnx->bot, channel);
+  
+  if (ret.getCode () != 0)
+    from->sendNotice (ret.getMessage ());
 }
 
 void
 UserCommands::Password(ServerConnection *cnx, Person *from,
                        String channel, String rest)
 {
-  Channel *c = cnx->bot->channelList->getChannel(channel);
-
   if (rest.length() == 0) {
     from->sendNotice("\002No password.\002");
     return;
   }
 
-  User * u = c->getUser(from->getNick());
-  if (!u) {
-    from->sendNotice(String("\002To change your password for\002") +
-                     channel + "\002, you need to be on the "
-                     "channel.\002");
-    return;
-  }
-
-  if (!u->userListItem) {
-    from->sendNotice("\002You are not in my userlist.\002");
-    return;
-  }
-
-  if (rest.toLower() == "none") {
-    u->userListItem->passwd = "";
-    from->sendNotice("\002Password cleared.\002");
-    return;
-  }
-  
-  static char saltChars[] = "abcdefghijklmnopqrstuvwxyz"
-    "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./";
-  char salt[3];
-  srand(time(0));
-  salt[0] = saltChars[rand() % 64];
-  salt[1] = saltChars[rand() % 64];
-  salt[2] = '\0';
-
-  u->userListItem->passwd = crypt((const char *)rest, salt);
-  from->sendNotice("\002Password changed.\002");
+  try
+    {
+      Channel *c = cnx->bot->channelList->getChannel(channel);
+      User u = c->getUser(from->getNick());
+      
+      if (!u.userListItem) {
+       from->sendNotice("\002You are not in my userlist.\002");
+       return;
+      }
+      
+      if (rest.toLower() == "none") {
+       u.userListItem->passwd = "";
+       from->sendNotice("\002Password cleared.\002");
+       return;
+      }
+      
+      static char saltChars[] = "abcdefghijklmnopqrstuvwxyz"
+       "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./";
+      char salt[3];
+      srand(time(0));
+      salt[0] = saltChars[rand() % 64];
+      salt[1] = saltChars[rand() % 64];
+      salt[2] = '\0';
+      
+      u.userListItem->passwd = crypt(rest.c_str (), salt);
+      from->sendNotice("\002Password changed.\002");
+    }
+  catch (const ChannelUserList::user_not_found &e)
+    {
+      from->sendNotice(String("\002To change your password for\002") +
+                      channel + "\002, you need to be on the "
+                      "channel.\002");
+      return;
+    }
 }
 
 void
@@ -1161,7 +1120,7 @@ UserCommands::Server(ServerConnection *cnx, Person *from,
     return;
   }
 
-  serverNumber = atoi(rest);
+  serverNumber = atoi(rest.c_str ());
 
   if (serverNumber < 0 || serverNumber >= cnx->bot->serverList->size()) {
     from->sendNotice(String((long)serverNumber) +
@@ -1205,11 +1164,11 @@ void
 UserCommands::SetFloodRate(ServerConnection *cnx, Person *from,
                           String channel, String rest)
 {
-  Message m = Commands::SetFloodRate (cnx->bot, std::atoi (rest));
+  Message m = Commands::SetFloodRate (cnx->bot, std::atoi (rest.c_str ()));
   if (m.getCode ())
     from->sendNotice (m.getMessage ());
   else
-    from->sendNotice ("Flood Rate set to:" + String(std::atol(rest)));
+    from->sendNotice ("Flood Rate set to:" + String(std::atol(rest.c_str ())));
 }
 
 void
@@ -1328,17 +1287,14 @@ UserCommands::Stats(ServerConnection *cnx, Person *from,
                     channel);
 }
 
-// FIXME: Convert
 void
 UserCommands::TBan(ServerConnection *cnx, Person *from,
                    String channel, String rest)
 {
   Channel * c = cnx->bot->channelList->getChannel(channel);
-
   StringTokenizer st(rest);
   String who = st.next_token();
   String t = st.next_token();
-  String dest;
 
   if (who == "" || t == "") {
     if (from)
@@ -1347,8 +1303,8 @@ UserCommands::TBan(ServerConnection *cnx, Person *from,
   }
 
   if (Utils::wildcard_p(who) && from) {
-    User * u = c->getUser(from->getNick());
-    if (u && u->getLevel() < User::TRUSTED_USER) {
+    if (c->hasNick (from->getNick ()) 
+       && c->getUser(from->getNick()).getLevel() < User::TRUSTED_USER) {
       if (from)
         from->sendNotice("\002You need an higher level to use"
                          " wildcards.\002");
@@ -1356,56 +1312,9 @@ UserCommands::TBan(ServerConnection *cnx, Person *from,
     }
   }
 
-  if (!cnx->bot->iAmOp(channel)) {
-    if (from)
-    from->sendNotice(String("\002I am not channel op on\002 ") +
-                     channel);
-    return;
-  }
-
-  if (!Utils::wildcard_p(who))
-    dest = cnx->bot->getUserhost(channel, who);
-  else
-    dest = who;
-
-  if (dest == "") {
-    if (from)
-      from->sendNotice(String("\002I can not find\002 ") + who);
-    return;
-  }
-
-  time_t w;
-
-  if ((w = Utils::str2time(t)) == 0) {
-    if (from)
-      from->sendNotice(t + " \002is an invalid time.\002");
-    return;
-  }
-
-  dest = Utils::make_wildcard(dest);
-  Mask m(dest);
-
-  for (std::list<UserListItem *>::iterator it = cnx->bot->userList->l.begin();
-       it != cnx->bot->userList->l.end();
-       it++)
-    if (m.matches((*it)->mask) &&
-        (*it)->channelMask.matches(channel) &&
-        (*it)->prot >= User::NO_BAN) {
-      if (from)
-        from->sendNotice(String("\002I can not ban\002 ") +
-                         who + " \002on channel\002 " +
-                         channel + " \002(protection).\002");
-      return;
-    }
-
-  for (std::vector<BanEntry *>::iterator it = c->channelBanlist.begin();
-       it != c->channelBanlist.end(); ++it)
-    if (m.matches((*it)->getMask()))
-      cnx->queue->sendChannelMode(channel, "-b", (*it)->getMask().getMask());
-
-  cnx->bot->channelList->getChannel(channel)->addBan(dest, w);
-  cnx->queue->sendChannelMode(channel, "+b", dest);
-  cnx->bot->todoList->addDeban(channel, dest, (time_t)w);
+  Message ret = Commands::TBan (cnx->bot, channel, who, Utils::str2time (t));
+  if (ret.getCode () && from)
+    from->sendNotice ("\002" + ret.getMessage () + "\002");
 }
 
 // FIXME: Convert
@@ -1475,34 +1384,33 @@ UserCommands::Who(ServerConnection *cnx, Person *from,
                  String channel, String rest)
 {
   String nick = from->getNick();
-  User * u = cnx->bot->channelList->getChannel(channel)->getUser(nick);
   UserListItem * uli;
-
-  if (u)
-    uli = u->userListItem;
+  
+  if (cnx->bot->channelList->getChannel(channel)->hasNick(nick))
+    uli = cnx->bot->channelList->getChannel(channel)->getUser(nick).userListItem;
   else
     uli = cnx->bot->userList->getUserListItem(from->getAddress(),
-                                         channel);
-
+                                             channel);
+  
   if (uli) {
     from->sendNotice(String("\002You are\002 ") +
-                      uli->mask.getMask() + " \002on\002 " +
-                      uli->channelMask.getMask());
+                    uli->mask.getMask() + " \002on\002 " +
+                    uli->channelMask.getMask());
     from->sendNotice(String("\002Lvl:\002 ") +
-                     Utils::level2str(uli->level) +
-                     " \002Prot:\002 " +
-                     Utils::prot2str(uli->prot) +
-                     " \002Aop:\002 " +
-                     Utils::bool2str(uli->aop) +
-                     " \002Expired:\002 " +
-                     Utils::bool2str(!uli->isStillValid()) +
-                     " \002Ident:\002 " +
-                     (uli && !uli->identified ? "\026" : "") +
-                     Utils::bool2str(uli && uli->identified) +
-                     (uli && !uli->identified ? "\026" : ""));
+                    Utils::level2str(uli->level) +
+                    " \002Prot:\002 " +
+                    Utils::prot2str(uli->prot) +
+                    " \002Aop:\002 " +
+                    Utils::bool2str(uli->aop) +
+                    " \002Expired:\002 " +
+                    Utils::bool2str(!uli->isStillValid()) +
+                    " \002Ident:\002 " +
+                    (uli && !uli->identified ? "\026" : "") +
+                    Utils::bool2str(uli && uli->identified) +
+                    (uli && !uli->identified ? "\026" : ""));
   } else
     from->sendNotice(String("\002You are not in the userlist for\002 ") +
-                      channel);
+                    channel);
 }
 
 void
@@ -1519,11 +1427,10 @@ UserCommands::Whois(ServerConnection *cnx, Person *from,
   StringTokenizer st(rest);
   String otherNick = st.next_token();
 
-  User * u = cnx->bot->channelList->getChannel(channel)->getUser(otherNick);
   UserListItem * uli;
 
-  if (u)
-    uli = u->userListItem;
+  if (cnx->bot->channelList->getChannel(channel)->hasNick(otherNick))
+    uli = cnx->bot->channelList->getChannel(channel)->getUser(otherNick).userListItem;
   else
     uli = cnx->bot->userList->getUserListItem(otherNick + "!" +
                                          cnx->bot->getUserhost(channel,