Factor out sorted list insertion into utility function
[clinton/bobotpp.git] / source / Parser.C
index 257f26c..021ebf2 100644 (file)
@@ -1,6 +1,6 @@
 // Parser.C  -*- C++ -*-
 // Copyright (c) 1997, 1998 Etienne BERNARD
-// Copyright (C) 2002 Clinton Ebadi
+// Copyright (C) 2002,2003,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
 
 // 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+// 02110-1301, USA.
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
 
+#include <cstdlib>
 #include <sys/types.h>
 #include <netinet/in.h>
 
 #include "StringTokenizer.H"
 #include "Parser.H"
 #include "UserCommands.H"
+#include "Commands.H"
 #include "Macros.H"
 #include "Utils.H"
 #include "ShitList.H"
 
 typedef void (*fptr) (ServerConnection *, Person *, String);
-std::map < std::string, fptr, std::less < std::string > >Parser::functions;
+std::map < std::string, fptr, std::less < std::string > > Parser::functions;
 
 void
 Parser::init ()
@@ -78,27 +81,32 @@ Parser::parseLine (ServerConnection * cnx, String line)
   Person *from = 0;
 #ifdef USESCRIPTS
   cnx->bot->botInterp->RunHooks (Hook::RAW, line,
-                                scm_listify (Utils::
-                                             string2SCM (line),
+                                scm_list_n (Utils::
+                                             str2scm (line),
                                              SCM_UNDEFINED));
 #endif
   if (line[0] == ':')
     {
-      String fromMask = st.nextToken ().subString (1);
+      String fromMask = st.next_token ().substr (1);
       if (fromMask.find ('!') != -1)
        from = new Person (cnx->bot, fromMask);
     }
 
-  String command = st.nextToken ();
+  String command = st.next_token ();
   String rest = st.rest ();
-  /*  for (int i = 0; functions[i].name != 0; i++)
-     if (command == functions[i].name) {
-     functions[i].function(cnx, from, rest);
-     break;
-     }
-   */
-  if (fptr temp_func = functions[command])
-    temp_func (cnx, from, rest);
+
+  // We must use map<>::find or else a new entry will be created in
+  // the map which will cause another lookup of the same invalid
+  // command to segfault the bot
+  std::map<std::string, fptr, std::less<std::string> >::const_iterator cit 
+    = functions.find (command);
+
+  if (cit != functions.end ())
+    {
+      fptr temp_func = cit->second;
+      temp_func (cnx, from, rest);
+    }
+
   delete from;
 }
 
@@ -107,8 +115,8 @@ Parser::parse001 (ServerConnection * cnx, Person * from, String rest)
 {
   String temp = "";
   StringTokenizer st (rest);
-  String realNick = st.nextToken ();
-  if ((cnx->bot->nickName).toLower () != realNick)
+  String realNick = st.next_token ();
+  if ((cnx->bot->nickName).toLower () != realNick.toLower ())
     {
       // Yes, this can happen, and it was a very subtle bug
       cnx->bot->nickName = realNick;
@@ -140,12 +148,12 @@ Parser::parse302 (ServerConnection * cnx, Person * from, String rest)
 {
   unsigned long num = cnx->bot->receivedUserhostID++;
   StringTokenizer st (rest);
-  st.nextToken (':');
+  st.next_token (':');
   if (st.rest ().length ())
     {
-      st.nextToken ('=');
+      st.next_token ('=');
       String parameters = st.rest ();
-      parameters = parameters.subString (1);
+      parameters = parameters.substr (1);
       cnx->bot->userhostMap[num] = parameters;
     }
   else
@@ -156,10 +164,10 @@ void
 Parser::parse311 (ServerConnection * cnx, Person * from, String rest)
 {
   StringTokenizer st (rest);
-  st.nextToken ();
-  String nuh = st.nextToken () + "!";
-  String uh = st.nextToken () + "@";
-  uh = uh + st.nextToken ();
+  st.next_token ();
+  String nuh = st.next_token () + "!";
+  String uh = st.next_token () + "@";
+  uh = uh + st.next_token ();
   nuh = nuh + uh;
   cnx->bot->userList->addUserFirst (nuh, "*", 0, 3, true, -1, "");
   cnx->bot->userHost = uh;
@@ -169,8 +177,8 @@ void
 Parser::parse315 (ServerConnection * cnx, Person * from, String rest)
 {
   StringTokenizer st (rest);
-  st.nextToken ();
-  String channel = st.nextToken ();
+  st.next_token ();
+  String channel = st.next_token ();
   Channel *c = cnx->bot->channelList->getChannel (channel);
   if (!c)
     return;
@@ -181,8 +189,8 @@ void
 Parser::parse324 (ServerConnection * cnx, Person * from, String rest)
 {
   StringTokenizer st (rest);
-  st.nextToken ();
-  String channel = st.nextToken ();
+  st.next_token ();
+  String channel = st.next_token ();
   if (Channel * c = cnx->bot->channelList->getChannel (channel))
     if (c)
       c->parseMode (from, st.rest ());
@@ -192,24 +200,24 @@ void
 Parser::parse332 (ServerConnection * cnx, Person * from, String rest)
 {
   StringTokenizer st (rest);
-  st.nextToken ();
-  String channel = st.nextToken ();
+  st.next_token ();
+  String channel = st.next_token ();
   if (Channel * c = cnx->bot->channelList->getChannel (channel))
     if (c)
-      c->channelTopic = st.rest ().subString (1);
+      c->channelTopic = st.rest ().substr (1);
 }
 
 void
 Parser::parse352 (ServerConnection * cnx, Person * from, String rest)
 {
   StringTokenizer st (rest);
-  st.nextToken ();
-  String ch = st.nextToken ();
-  String uh = st.nextToken () + "@";
-  uh = uh + st.nextToken ();
-  st.nextToken ();
-  String n = st.nextToken ();
-  String m = st.nextToken ();
+  st.next_token ();
+  String ch = st.next_token ();
+  String uh = st.next_token () + "@";
+  uh = uh + st.next_token ();
+  st.next_token ();
+  String n = st.next_token ();
+  String m = st.next_token ();
   int mode = 0;
   for (int i = 0; i < m.length (); i++)
     switch (m[i])
@@ -240,24 +248,24 @@ Parser::parse353 (ServerConnection * cnx, Person * from, String rest)
   int mode = 0;
   String nick;
   StringTokenizer st (rest);
-  st.nextToken ();
-  st.nextToken ();
-  Channel *c = cnx->bot->channelList->getChannel (st.nextToken ());
+  st.next_token ();
+  st.next_token ();
+  Channel *c = cnx->bot->channelList->getChannel (st.next_token ());
   if (!c)
     return;
-  StringTokenizer st2 (st.nextToken (':'));
-  while (st2.hasMoreTokens ())
+  StringTokenizer st2 (st.next_token (':'));
+  while (st2.more_tokens_p ())
     {
-      nick = st2.nextToken ();
+      nick = st2.next_token ();
       if (nick[0] == '@')
        {
          mode = User::OP_MODE;
-         nick = nick.subString (1);
+         nick = nick.substr (1);
        }
       else if (nick[0] == '+')
        {
          mode = User::VOICE_MODE;
-         nick = nick.subString (1);
+         nick = nick.substr (1);
        }
       c->addNick (nick, "", mode, 0, true);
     }
@@ -267,8 +275,8 @@ void
 Parser::parse366 (ServerConnection * cnx, Person * from, String rest)
 {
   StringTokenizer st (rest);
-  st.nextToken ();
-  String ch = st.nextToken ();
+  st.next_token ();
+  String ch = st.next_token ();
   if (Channel * c = cnx->bot->channelList->getChannel (ch))
     c->joined = true;
 }
@@ -277,18 +285,18 @@ void
 Parser::parse367 (ServerConnection * cnx, Person * from, String rest)
 {
   StringTokenizer st (rest);
-  st.nextToken ();
-  String ch = st.nextToken ();
+  st.next_token ();
+  String ch = st.next_token ();
   if (Channel * c = cnx->bot->channelList->getChannel (ch))
-    c->addBan (st.nextToken (), -1);
+    c->addBan (st.next_token (), -1);
 }
 
 void
 Parser::parse401 (ServerConnection * cnx, Person * from, String rest)
 {
   StringTokenizer st (rest);
-  st.nextToken ();
-  String nick = st.nextToken ();
+  st.next_token ();
+  String nick = st.next_token ();
   if (cnx->bot->spyList.find (nick) != cnx->bot->spyList.end ())
     {
       delete cnx->bot->spyList[nick];
@@ -309,11 +317,11 @@ Parser::parse433 (ServerConnection * cnx, Person * from, String rest)
           && cnx->bot->nickName[i] == '_'; i++);
       if (i < cnx->bot->nickName.length ())
        cnx->bot->nickName =
-         cnx->bot->nickName.subString (0,
+         cnx->bot->nickName.substr (0,
                                        i - 1) + "_" +
-         cnx->bot->nickName.subString (i + 1);
+         cnx->bot->nickName.substr (i + 1);
       else
-       cnx->bot->nickName = cnx->bot->nickName.subString (0, 4) +
+       cnx->bot->nickName = cnx->bot->nickName.substr (0, 4) +
          String ((long) (rand () % 10000));
     }
   else
@@ -325,9 +333,9 @@ void
 Parser::parse473 (ServerConnection * cnx, Person * from, String rest)
 {
   StringTokenizer st (rest);
-  st.nextToken ();
+  st.next_token ();
   cnx->bot->logLine (String ("Unable to join channel ") +
-                    st.nextToken () + ".");
+                    st.next_token () + ".");
 }
 
 void
@@ -346,15 +354,15 @@ Parser::parseInvite (ServerConnection * cnx, Person * from, String rest)
 {
   String nick = from->getNick ();
   StringTokenizer st (rest);
-  st.nextToken (':');
+  st.next_token (':');
   String channel = st.rest ();
 #ifdef USESCRIPTS
   cnx->bot->botInterp->RunHooks (Hook::INVITE,
                                 nick + " " + channel,
-                                scm_listify (Utils::
-                                             string2SCM (nick),
+                                scm_list_n (Utils::
+                                             str2scm (nick),
                                              Utils::
-                                             string2SCM
+                                             str2scm
                                              (channel), SCM_UNDEFINED));
 #endif
   if (cnx->bot->wantedChannels.find (channel) !=
@@ -366,25 +374,25 @@ void
 Parser::parseJoin (ServerConnection * cnx, Person * from, String rest)
 {
   StringTokenizer st (from->getAddress ());
-  String n = st.nextToken ('!');
-  String uh = st.nextToken ();
+  String n = st.next_token ('!');
+  String uh = st.next_token ();
   StringTokenizer st2 (rest);
-  String c = st2.nextToken (':');
+  String c = st2.next_token (':');
   String mode;
   bool joinAndMode = false;
 #ifdef USESCRIPTS
   cnx->bot->botInterp->RunHooks (Hook::JOIN, n + " " + c,
-                                scm_listify (Utils::
-                                             string2SCM (n),
+                                scm_list_n (Utils::
+                                             str2scm (n),
                                              Utils::
-                                             string2SCM (c), SCM_UNDEFINED));
+                                             str2scm (c), SCM_UNDEFINED));
 #endif
   // This part of code is for the combined JOIN & MODE of ircd 2.9
   if (c.find ('\007') >= 0)
     {
       joinAndMode = true;
       StringTokenizer st3 (c);
-      c = st3.nextToken ('\007');
+      c = st3.next_token ('\007');
       String m = st3.rest ();
       mode = c + " +" + m;
       for (int i = 0; i < m.length (); i++)
@@ -422,9 +430,9 @@ Parser::parseJoin (ServerConnection * cnx, Person * from, String rest)
          && !(ch->getUser (n)->mode & User::OP_MODE) && cnx->bot->iAmOp (c))
        {
          // This is a part of the antispoof code
-         ch->getUser (n)->userkey = Utils::getKey ();
-         cnx->queue->sendCTCP (n, "PING",
-                               ch->getUser (n)->userkey + " " + c);
+         ch->getUser(n)->userkey = Utils::get_key ();
+         Commands::CTCP (cnx->bot, n, "PING", 
+                         ch->getUser(n)->userkey + " " + c);
        }
     }
 
@@ -436,26 +444,26 @@ void
 Parser::parseKick (ServerConnection * cnx, Person * from, String rest)
 {
   StringTokenizer st (rest);
-  String channel = st.nextToken ();
-  String target = st.nextToken ();
-  String reason = st.rest ().subString (1);
+  String channel = st.next_token ();
+  String target = st.next_token ();
+  String reason = st.rest ().substr (1);
 #ifdef USESCRIPTS
   cnx->bot->botInterp->RunHooks (Hook::KICK,
                                 target + " " +
                                 from->getNick () + " " +
                                 channel + " " + reason,
-                                scm_listify (Utils::
-                                             string2SCM
+                                scm_list_n (Utils::
+                                             str2scm
                                              (target),
                                              Utils::
-                                             string2SCM (from->
+                                             str2scm (from->
                                                          getNick
                                                          ()),
                                              Utils::
-                                             string2SCM
+                                             str2scm
                                              (channel),
                                              Utils::
-                                             string2SCM
+                                             str2scm
                                              (reason), SCM_UNDEFINED));
 #endif
   if (target == cnx->bot->nickName)
@@ -495,24 +503,24 @@ void
 Parser::parseMode (ServerConnection * cnx, Person * from, String rest)
 {
   StringTokenizer st (rest);
-  String ch = st.nextToken ();
+  String ch = st.next_token ();
   String modes = st.rest ();
 #ifdef USESCRIPTS
   if (from)
     cnx->bot->botInterp->RunHooks (Hook::MODE,
                                   from->getNick () + " " + ch +
                                   " " + modes,
-                                  scm_listify (Utils::
-                                               string2SCM (from->
+                                  scm_list_n (Utils::
+                                               str2scm (from->
                                                            getNick
                                                            ()),
                                                Utils::
-                                               string2SCM (ch),
+                                               str2scm (ch),
                                                Utils::
-                                               string2SCM (modes),
+                                               str2scm (modes),
                                                SCM_UNDEFINED));
 #endif
-  if (Utils::isChannel (ch))
+  if (Utils::channel_p (ch))
     {
       Channel *c = cnx->bot->channelList->getChannel (ch);
       if (!c)
@@ -529,16 +537,16 @@ Parser::parseNick (ServerConnection * cnx, Person * from, String rest)
 {
   String on_orig = from->getNick ();
   String on = on_orig.toLower ();
-  String nn = rest.subString (1);
+  String nn = rest.substr (1);
   String nn_lower = nn.toLower ();
 #ifdef USESCRIPTS
   cnx->bot->botInterp->RunHooks (Hook::NICKNAME,
                                 on_orig + " " + nn,
-                                scm_listify (Utils::
-                                             string2SCM
+                                scm_list_n (Utils::
+                                             str2scm
                                              (on_orig),
                                              Utils::
-                                             string2SCM (nn),
+                                             str2scm (nn),
                                              SCM_UNDEFINED));
 #endif
   if ((cnx->bot->nickName).toLower () == on)
@@ -573,53 +581,53 @@ Parser::parseNotice (ServerConnection * cnx, Person * from, String rest)
   if (from)
     nick = from->getNick ();
   StringTokenizer st (rest);
-  String to = st.nextToken ();
-  rest = st.rest ().subString (1);
+  String to = st.next_token ();
+  rest = st.rest ().substr (1);
   if (rest[0] != '\001')
     {
 #ifdef USESCRIPTS
-      if (Utils::isChannel (to))
+      if (Utils::channel_p (to))
        cnx->bot->botInterp->RunHooks (Hook::PUBLIC_NOTICE,
                                       nick + " " + to + " " + rest,
-                                      scm_listify (Utils::
-                                                   string2SCM (nick),
+                                      scm_list_n (Utils::
+                                                   str2scm (nick),
                                                    Utils::
-                                                   string2SCM (to),
+                                                   str2scm (to),
                                                    Utils::
-                                                   string2SCM (rest),
+                                                   str2scm (rest),
                                                    SCM_UNDEFINED));
       else
        cnx->bot->botInterp->RunHooks (Hook::NOTICE, nick + " " + rest,
-                                      scm_listify (Utils::
-                                                   string2SCM (nick),
+                                      scm_list_n (Utils::
+                                                   str2scm (nick),
                                                    Utils::
-                                                   string2SCM (rest),
+                                                   str2scm (rest),
                                                    SCM_UNDEFINED));
 #endif
       return;
     }
 
-  rest = rest.subString (1, rest.length () - 2);
+  rest = rest.substr (1, rest.length () - 2);
   StringTokenizer st2 (rest);
-  String command = st2.nextToken ();
+  String command = st2.next_token ();
   rest = st2.rest ();
 #ifdef USESCRIPTS
   cnx->bot->botInterp->RunHooks (Hook::CTCP_REPLY,
                                 nick + " " + command + " " +
                                 rest,
-                                scm_listify (Utils::
-                                             string2SCM (nick),
+                                scm_list_n (Utils::
+                                             str2scm (nick),
                                              Utils::
-                                             string2SCM
+                                             str2scm
                                              (command),
                                              Utils::
-                                             string2SCM (rest),
+                                             str2scm (rest),
                                              SCM_UNDEFINED));
 #endif
   if (command == "PING")
     {
       StringTokenizer st3 (rest);
-      rest = st3.nextToken ();
+      rest = st3.next_token ();
       String c = st3.rest ();
       if (cnx->bot->channelList->getChannel (c) &&
          cnx->bot->channelList->getChannel (c)->getUser (nick) &&
@@ -638,23 +646,23 @@ Parser::parsePrivmsg (ServerConnection * cnx, Person * from, String rest)
 {
   String nick = from->getNick ();
   StringTokenizer st (rest);
-  String to = st.nextToken ();
-  String fromUserhost = Utils::getUserhost (from->getAddress ());
-  rest = st.rest ().subString (1);
+  String to = st.next_token ();
+  String fromUserhost = Utils::get_userhost (from->getAddress ());
+  rest = st.rest ().substr (1);
   if (++(cnx->bot->ignoredUserhosts[fromUserhost]) > Bot::MAX_MESSAGES)
     {
       if (cnx->bot->ignoredUserhosts[fromUserhost] == Bot::MAX_MESSAGES + 1)
        {
 #ifdef USESCRIPTS
          cnx->bot->botInterp->RunHooks (Hook::FLOOD, nick,
-                                        scm_listify (Utils::
-                                                     string2SCM (nick),
+                                        scm_list_n (Utils::
+                                                     str2scm (nick),
                                                      SCM_UNDEFINED));
 #endif
          cnx->bot->ignoredUserhosts[fromUserhost] += Bot::IGNORE_DELAY;
          cnx->bot->logLine (from->getAddress () +
                             " is flooding me. We will ignore him/her/it.");
-         if (!Utils::isChannel (to))
+         if (!Utils::channel_p (to))
            from->
              sendNotice (String ("\002You are now being ignored for ") +
                          String ((long) Bot::IGNORE_DELAY) +
@@ -676,8 +684,8 @@ Parser::parsePrivmsg (ServerConnection * cnx, Person * from, String rest)
 
   if (rest[0] == '\001')
     {
-      rest = rest.subString (1, rest.length () - 2);
-      if (!Utils::isChannel (to))
+      rest = rest.substr (1, rest.length () - 2);
+      if (!Utils::channel_p (to))
        for (std::map < String, Person *,
             std::less < String > >::iterator it =
             cnx->bot->spyList.begin (); it != cnx->bot->spyList.end (); ++it)
@@ -688,10 +696,10 @@ Parser::parsePrivmsg (ServerConnection * cnx, Person * from, String rest)
   else
     {
       if ((rest.length () < 5 ||
-          rest.subString (1, 5).toUpper () != "IDENT") &&
+          rest.substr (1, 5).toUpper () != "IDENT") &&
          (rest.length () < 8 ||
-          rest.subString (1, 8).toUpper () != "PASSWORD") &&
-         !Utils::isChannel (to))
+          rest.substr (1, 8).toUpper () != "PASSWORD") &&
+         !Utils::channel_p (to))
        for (std::map < String, Person *,
             std::less < String > >::iterator it =
             cnx->bot->spyList.begin (); it != cnx->bot->spyList.end (); ++it)
@@ -705,18 +713,18 @@ Parser::parsePart (ServerConnection * cnx, Person * from, String rest)
 {
   String n = from->getNick ();
   StringTokenizer st (rest);
-  String channel = st.nextToken ();
+  String channel = st.next_token ();
 #ifdef USESCRIPTS
-  cnx->bot->botInterp->RunHooks (Hook::LEAVE, n + " " + channel,
-                                scm_listify (Utils::
-                                             string2SCM (n),
+  cnx->bot->botInterp->RunHooks (Hook::PART, n + " " + channel,
+                                scm_list_n (Utils::
+                                             str2scm (n),
                                              Utils::
-                                             string2SCM
+                                             str2scm
                                              (channel), SCM_UNDEFINED));
 #endif
   if (n.toLower () == cnx->bot->nickName.toLower ())
     {
-      cnx->bot->logLine (String ("Leaved channel ") + channel + ".");
+      cnx->bot->logLine (String ("Left channel ") + channel + ".");
       cnx->bot->channelList->delChannel (channel);
     }
   else
@@ -753,10 +761,10 @@ Parser::parseQuit (ServerConnection * cnx, Person * from, String rest)
   String n = from->getNick ();
 #ifdef USESCRIPTS
   cnx->bot->botInterp->RunHooks (Hook::SIGNOFF, n + " " + rest,
-                                scm_listify (Utils::
-                                             string2SCM (n),
+                                scm_list_n (Utils::
+                                             str2scm (n),
                                              Utils::
-                                             string2SCM (rest),
+                                             str2scm (rest),
                                              SCM_UNDEFINED));
 #endif
   if (n == cnx->bot->nickName)
@@ -772,22 +780,22 @@ void
 Parser::parseTopic (ServerConnection * cnx, Person * from, String rest)
 {
   StringTokenizer st (rest);
-  String channel = st.nextToken ();
-  String newTopic = st.rest ().subString (1);
+  String channel = st.next_token ();
+  String newTopic = st.rest ().substr (1);
   Channel *c = cnx->bot->channelList->getChannel (channel);
 #ifdef USESCRIPTS
   cnx->bot->botInterp->RunHooks (Hook::TOPIC,
                                 from->getNick () + " " +
                                 channel + " " + newTopic,
-                                scm_listify (Utils::
-                                             string2SCM (from->
+                                scm_list_n (Utils::
+                                             str2scm (from->
                                                          getNick
                                                          ()),
                                              Utils::
-                                             string2SCM
+                                             str2scm
                                              (channel),
                                              Utils::
-                                             string2SCM
+                                             str2scm
                                              (newTopic), SCM_UNDEFINED));
 #endif
   if (!c)
@@ -802,10 +810,10 @@ Parser::parseCTCP (ServerConnection * cnx,
                   Person * from, String to, String parameters)
 {
   StringTokenizer st (parameters);
-  String command = st.nextToken ().toUpper ();
+  String command = Utils::to_upper (st.next_token ());
   String nick = from->getNick ();
   String rest;
-  if (st.hasMoreTokens ())
+  if (st.more_tokens_p ())
     rest = st.rest ();
   else
     rest = "";
@@ -813,351 +821,197 @@ Parser::parseCTCP (ServerConnection * cnx,
   cnx->bot->botInterp->RunHooks (Hook::CTCP,
                                 nick + " " + to + " " +
                                 command + " " + rest,
-                                scm_listify (Utils::
-                                             string2SCM (nick),
+                                scm_list_n (Utils::
+                                             str2scm (nick),
                                              Utils::
-                                             string2SCM (to),
+                                             str2scm (to),
                                              Utils::
-                                             string2SCM
+                                             str2scm
                                              (command),
                                              Utils::
-                                             string2SCM (rest),
+                                             str2scm (rest),
                                              SCM_UNDEFINED));
 #endif
   if (command == "PING")
-    cnx->queue->sendCTCPReply (nick, "PING", rest);
+    {
+      Commands::CTCPReply (cnx->bot, nick, "PING", rest);
+    }
   else if (command == "VERSION")
-    cnx->queue->sendCTCPReply (nick, "VERSION", cnx->bot->versionString);
+    {
+      Commands::CTCPReply (cnx->bot, nick, "VERSION", 
+                          cnx->bot->versionString);
+    }
   else if (command == "CLOCK")
     {
       time_t diff = time (NULL) - cnx->bot->startTime;
-      cnx->queue->sendCTCPReply (nick, "CLOCK",
-                                String ("elapsed time: ") +
-                                String ((long) (diff / 86400)) +
-                                "d" +
-                                String ((long) (diff % 86400) /
-                                        3600) + "h" +
-                                String ((long) (diff % 3600) / 60) +
-                                "m" + String ((long) (diff % 60)) + "s");
+      Commands::CTCPReply (cnx->bot, nick, "CLOCK",
+                          String ("elapsed time: ") +
+                          String ((long) (diff / 86400)) +
+                          "d" +
+                          String ((long) (diff % 86400) /
+                                  3600) + "h" +
+                          String ((long) (diff % 3600) / 60) +
+                          "m" + String ((long) (diff % 60)) + "s");
     }
   else if (command == "COMMAND")
-    cnx->queue->sendCTCPReply (nick,
-                              "COMMAND", String (cnx->bot->commandChar));
+    {
+      Commands::CTCPReply (cnx->bot, nick,
+                          "COMMAND", String (cnx->bot->commandChar));
+    }
   else if (command == "LAG")
-    cnx->queue->sendCTCPReply (nick, "LAG",
-                              String ((long) cnx->lag) + " second(s)");
+    {
+      Commands::CTCPReply (cnx->bot, nick, "LAG",
+                          String ((long) cnx->lag) + " second(s)");
+    }
   else if (command == "DCC")
     {
       StringTokenizer st2 (rest);
-      command = st2.nextToken ().toUpper ();
+      command = Utils::to_upper (st2.next_token ());
       if (command == "CHAT")
        {
-         // FIXME: Re-activate and debug DCC
-         st2.nextToken ();
+         // FIXME: debug DCC
+         st2.next_token ();
          unsigned long address =
-           ntohl (strtoul ((const char *) st2.nextToken (), 0, 0));
-         int port = atoi ((const char *) st2.nextToken ());
-         if (port >= 1024 && Utils::getLevel (cnx->bot, from->getAddress ()))
-           cnx->bot->addDCC (from, address, port);
+           std::strtoul (st2.next_token ().c_str(), 0, 0);
+         int port = std::atoi (st2.next_token().c_str());
+         if (port >= 1024 && Utils::get_level (cnx->bot, from->getAddress ()))
+           cnx->bot->addDCC (from, address, port, Bot::CHAT);
+         else
+           cnx->bot->logLine ("DCC Chat Failed in Parser");
        }
     }
 #ifdef USESCRIPTS
   else if (command == "ACTION")
     {
       cnx->bot->botInterp->RunHooks (Hook::ACTION,
-                                    from->getAddress () + " " + to +
+                                    from->getNick () + " " + to +
                                     " " + rest,
-                                    scm_listify (Utils::
-                                                 string2SCM (from->
-                                                             getAddress
+                                    scm_list_n (Utils::
+                                                 str2scm (from->
+                                                             getNick
                                                              ()),
                                                  Utils::
-                                                 string2SCM (to),
+                                                 str2scm (to),
                                                  Utils::
-                                                 string2SCM (rest),
+                                                 str2scm (rest),
                                                  SCM_UNDEFINED));
     }
 #endif
 }
 
-// struct userFunctionsStruct userFunctionsInit[] = {
-//   {
-//    "ACTION", UserCommands::Action, User::USER, true}
-//   ,
-//   {
-//    "ADDUSER", UserCommands::AddUser, User::FRIEND, false}
-//   ,
-//   {
-//    "ADDSERVER", UserCommands::AddServer, User::FRIEND, false}
-//   ,
-//   {
-//    "ADDSHIT", UserCommands::AddShit, User::FRIEND, false}
-//   ,
-//   {
-//    "ALIAS", UserCommands::Alias, User::MASTER, false}
-//   ,
-//   {
-//    "BAN", UserCommands::Ban, User::USER, true}
-//   ,
-//   {
-//    "BANLIST", UserCommands::BanList, User::USER, true}
-//   ,
-//   //  { "CHANGELEVEL", UserCommands::ChangeLevel, User::FRIEND,       false },
-//   {
-//    "CHANNELS", UserCommands::Channels, User::FRIEND, false}
-//   ,
-//   {
-//    "CYCLE", UserCommands::Cycle, User::FRIEND, true}
-//   ,
-//   {
-//    "DCCLIST", UserCommands::DCCList, User::FRIEND, false}
-//   ,
-//   {
-//    "DEBAN", UserCommands::Deban, User::USER, true}
-//   ,
-//   {
-//    "DELSERVER", UserCommands::DelServer, User::FRIEND, false}
-//   ,
-//   {
-//    "DELUSER", UserCommands::DelUser, User::FRIEND, false}
-//   ,
-//   {
-//    "DELSHIT", UserCommands::DelShit, User::FRIEND, false}
-//   ,
-//   {
-//    "DEOP", UserCommands::Deop, User::TRUSTED_USER, true}
-//   ,
-//   {
-//    "DIE", UserCommands::Die, User::MASTER, false}
-//   ,
-//   {
-//    "DO", UserCommands::Do, User::MASTER, false}
-//   ,
-// #ifdef USESCRIPTS
-//   {
-//    "EXECUTE", UserCommands::Execute, User::MASTER, false}
-//   ,
-// #endif
-//   {
-//    "HELP", UserCommands::Help, User::NONE, false}
-//   ,
-//   {
-//    "IDENT", UserCommands::Ident, User::NONE, true}
-//   ,
-//   {
-//    "INVITE", UserCommands::Invite, User::USER, true}
-//   ,
-//   {
-//    "JOIN", UserCommands::Join, User::FRIEND, false}
-//   ,
-//   {
-//    "KEEP", UserCommands::Keep, User::FRIEND, true}
-//   ,
-//   {
-//    "KICK", UserCommands::Kick, User::USER, true}
-//   ,
-//   {
-//    "KICKBAN", UserCommands::KickBan, User::USER, true}
-//   ,
-//   {
-//    "LOAD", UserCommands::Load, User::FRIEND, false}
-//   ,
-// #ifdef USESCRIPTS
-//   {
-//    "LOADSCRIPT", UserCommands::LoadScript, User::MASTER, false}
-//   ,
-// #endif
-//   {
-//    "LOCK", UserCommands::Lock, User::FRIEND, true}
-//   ,
-//   {
-//    "MODE", UserCommands::Mode, User::FRIEND, true}
-//   ,
-//   {
-//    "MSG", UserCommands::Msg, User::USER, false}
-//   ,
-//   {
-//    "NAMES", UserCommands::Names, User::USER, true}
-//   ,
-//   {
-//    "NEXTSERVER", UserCommands::NextServer, User::FRIEND, false}
-//   ,
-//   {
-//    "NICK", UserCommands::Nick, User::FRIEND, false}
-//   ,
-//   {
-//    "NSLOOKUP", UserCommands::NsLookup, User::USER, false}
-//   ,
-//   {
-//    "OP", UserCommands::Op, User::TRUSTED_USER, true}
-//   ,
-//   {
-//    "PART", UserCommands::Part, User::FRIEND, true}
-//   ,
-//   {
-//    "PASSWORD", UserCommands::Password, User::USER, true}
-//   ,
-//   {
-//    "RECONNECT", UserCommands::Reconnect, User::FRIEND, false}
-//   ,
-//   {
-//    "RSPYMESSAGE", UserCommands::RSpyMessage, User::USER, false}
-//   ,
-//   {
-//    "SAVE", UserCommands::Save, User::FRIEND, false}
-//   ,
-//   {
-//    "SAY", UserCommands::Say, User::USER, true}
-//   ,
-//   {
-//    "SERVER", UserCommands::Server, User::FRIEND, false}
-//   ,
-//   {
-//    "SERVERLIST", UserCommands::ServerList, User::FRIEND, false}
-//   ,
-//   {
-//    "SETVERSION", UserCommands::SetVersion, User::MASTER, false}
-//   ,
-//   {
-//    "SHITLIST", UserCommands::ShitList, User::FRIEND, false}
-//   ,
-//   {
-//    "SPYLIST", UserCommands::SpyList, User::USER, false}
-//   ,
-//   {
-//    "SPYMESSAGE", UserCommands::SpyMessage, User::USER, false}
-//   ,
-//   {
-//    "STATS", UserCommands::Stats, User::FRIEND, true}
-//   ,
-//   {
-//    "TBAN", UserCommands::TBan, User::USER, true}
-//   ,
-//   {
-//    "TKBAN", UserCommands::TKBan, User::USER, true}
-//   ,
-//   {
-//    "TOPIC", UserCommands::Topic, User::USER, true}
-//   ,
-//   {
-//    "UNLOCK", UserCommands::Unlock, User::FRIEND, true}
-//   ,
-//   {
-//    "USERLIST", UserCommands::UserList, User::FRIEND, false}
-//   ,
-//   {
-//    "WHO", UserCommands::Who, User::NONE, true}
-//   ,
-//   {
-//    "WHOIS", UserCommands::Whois, User::FRIEND, true}
-//   ,
-//   {
-//    "", 0, 0, false}
-// };
 void
 Parser::parseMessage (ServerConnection * cnx,
                      Person * from, String to, String parameters)
 {
 #ifdef USESCRIPTS
-  if (Utils::isChannel (to))
+  if (Utils::channel_p (to))
     cnx->bot->botInterp->RunHooks (Hook::PUBLIC,
                                   from->getNick () + " " + to +
                                   " " + parameters,
-                                  scm_listify (Utils::
-                                               string2SCM (from->
+                                  scm_list_n (Utils::
+                                               str2scm (from->
                                                            getNick
                                                            ()),
                                                Utils::
-                                               string2SCM (to),
+                                               str2scm (to),
                                                Utils::
-                                               string2SCM
+                                               str2scm
                                                (parameters), SCM_UNDEFINED));
   else
     cnx->bot->botInterp->RunHooks (Hook::MESSAGE,
                                   from->getNick () + " " +
                                   parameters,
-                                  scm_listify (Utils::
-                                               string2SCM (from->
+                                  scm_list_n (Utils::
+                                               str2scm (from->
                                                            getNick
                                                            ()),
                                                Utils::
-                                               string2SCM
+                                               str2scm
                                                (parameters), SCM_UNDEFINED));
 #endif
   if (parameters[0] != cnx->bot->commandChar)
     return;
 
   StringTokenizer st (parameters);
-  String command = st.nextToken ().subString (1).toUpper ();
-  String rest = st.rest ().trim ();
+  String command = Utils::to_upper (st.next_token ().substr (1));
+  String rest = Utils::trim_str (st.rest ());
   int level;
   bool identified = false;
-  userFunction * f = cnx->bot->userFunctions[command];
+  std::map<std::string, class userFunction*, 
+    std::less<std::string> >::const_iterator  uf_iter 
+    = cnx->bot->userFunctions.find (command);
+  userFunction * f = 0;
+  
+  if (uf_iter != cnx->bot->userFunctions.end ())
+    f = uf_iter->second;
+  else
+    return;
+  
   if (f)
     {
       if (f->needsChannelName)
        {
-         if (Utils::isChannel (rest))
+         if (Utils::channel_p (rest))
            {
              StringTokenizer st2 (rest);
-             to = st.nextToken ();
+             to = st.next_token ();
              rest = st.rest ();
            }
-           if (!Utils::isChannel (to))
-             {
-               from->sendNotice ("\002You need to supply a channel name"
-                                 " for this command\002");
-               return;
-             }
-           if (!cnx->bot->channelList->getChannel (to))
-             {
-               from->sendNotice (String ("\002I am not on channel\002 ") +
-                                 to);
-               return;
-             }
-           level = Utils::getLevel (cnx->bot, from->getAddress (), to);
-           User *u = 0;
-           if (Channel * c = cnx->bot->channelList->getChannel (to))
-             u = c->getUser (from->getNick ());
-           if (!u || !u->userListItem)
-             identified = true;
-           else
-             identified = u->userListItem->passwd == ""
-               || u->userListItem->identified > 0;
-         }
-       else
-         {
-           level = Utils::getLevel (cnx->bot, from->getAddress ());
+         if (!Utils::channel_p (to))
+           {
+             from->sendNotice ("\002You need to supply a channel name"
+                               " for this command\002");
+             return;
+           }
+         if (!cnx->bot->channelList->getChannel (to))
+           {
+             from->sendNotice (String ("\002I am not on channel\002 ") +
+                               to);
+             return;
+           }
+         level = Utils::get_level (cnx->bot, from->getAddress (), to);
+         User *u = 0;
+         if (Channel * c = cnx->bot->channelList->getChannel (to))
+           u = c->getUser (from->getNick ());
+         if (!u || !u->userListItem)
            identified = true;
-         }
-       if (level >= f->minLevel)
-         {
-           cnx->bot->logLine (from->getAddress () + " did " + command +
-                              " " + rest);
+         else
+           identified = u->userListItem->passwd == ""
+             || u->userListItem->identified > 0;
+       }
+      else
+           {
+             level = Utils::get_level (cnx->bot, from->getAddress ());
+             identified = true;
+           }
+      if (level >= f->minLevel)
+       {
+         cnx->bot->logLine (from->getAddress () + " did " + command +
+                            " " + rest);
 #ifdef USESCRIPTS
-           if (f->argsCount != -1)
-             {
-               Parser::parseScriptFunction (cnx, to, f->needsChannelName,
-                                            f->scmFunc, f->argsCount,
-                                            rest);
-             }
-           else
-             {
-               f->function (cnx, from, to, rest);
-             }
+         if (f->argsCount != -1)
+           {
+             Parser::parseScriptFunction (cnx, to, f->needsChannelName,
+                                          f->scmFunc, f->argsCount,
+                                          rest);
+           }
+         else
+           {
+             f->function (cnx, from, to, rest);
+           }
 #else
-           f->function (cnx, from, to, rest);
+         f->function (cnx, from, to, rest);
 #endif
-         }
-       else
-         {
-           if (!identified)
-             from->
-               sendNotice (String
-                           ("\002You are not identified on channel\002 ") +
-                           to);
-         }
-      }
+       }
+      else
+       {
+         if (!identified)
+           from->
+             sendNotice (String
+                         ("\002You are not identified on channel\002 ") +
+                         to);
+       }
+    }
 }
 
 #ifdef USESCRIPTS
@@ -1168,13 +1022,13 @@ Parser::parseScriptFunction (ServerConnection * cnx,
                             SCM scmFunc, int argsCount, String parameters)
 {
   String param;
-  SCM args_list = scm_listify (SCM_UNDEFINED);
+  SCM args_list = scm_list_n (SCM_UNDEFINED);
   if (needsChannelName)
     {
-      args_list = gh_append2 (args_list,
-                             scm_listify (Utils::
-                                          string2SCM (channel),
-                                          SCM_UNDEFINED));
+      args_list = scm_append (scm_list_2 (args_list,
+                                         scm_list_n (Utils::
+                                                     str2scm (channel),
+                                                     SCM_UNDEFINED)));
       argsCount--;
     }
 
@@ -1184,16 +1038,18 @@ Parser::parseScriptFunction (ServerConnection * cnx,
       if (i == 1)
        param = st.rest ();
       else
-       param = st.nextToken ();
-      args_list = gh_append2 (args_list,
-                             scm_listify (Utils::string2SCM (param),
-                                          SCM_UNDEFINED));
+       param = st.next_token ();
+      args_list = scm_append (scm_list_2 (args_list,
+                                         scm_list_n (Utils::str2scm (param),
+                                                     SCM_UNDEFINED)));
     }
 
   struct wrapper_data wd;
   wd.func = scmFunc;
   wd.args = args_list;
-  gh_catch (SCM_BOOL_T, (scm_t_catch_body) scm_apply_wrapper,
-           (void *) &wd, (scm_t_catch_handler) Interp::ErrorHandler, 0);
+  scm_internal_catch (SCM_BOOL_T,
+                     (scm_t_catch_body) Interp::LazyApplyWrapper, 
+                     (void *) &wd,
+                     (scm_t_catch_handler) Interp::EmptyHandler, 0);
 }
 #endif