/***************************************************************************
 *                                                                         *
 *   TLCDCMD.CPP                                                           *
 *                                                                         *
 *   Copyright (c) 1997 Galacticomm, Inc.         All Rights Reserved      *
 *                                                                         *
 *   Default Command Handlers                                              *
 *   Implementation                                                        *
 *                                               - Phil Henning 6/4/97     *
 *                                                                         *
 ***************************************************************************/

#include "gcomm.h"
#include "majorbbs.h"
#include "tlcapi.hpp"
#include "tlctmtra.h"
#include <time.h>

#define FILREV "$Revision: 91 $"

// local function declarations

static VOID ScanListChan(CTlcChannel* pChannel,CTlcUser* pUser);
static VOID ScanListUser(CTlcUser *pUser,CTlcUser *pOthUser);

// function definitions begin here

MARKSOURCE(tlcdcmd);

SHORT CcmdJoin::DoCmd(CCommandParam* pParam)
{
     CTlcChannel* pNewChannel;
     CTlcChannel* pCurrentChannel;
     CTlcUser* pUser;
     CTlcJoinInf* pJoin;
     GBOOL joinpriv=FALSE;

     if (!CTlcCommand::DoCmd(pParam)) {
          return(1);
     }
     pUser=UserStructToClass(pParam->m_pUser);
     if (!(pUser->m_fFlags&USR_INCHAN)) {
          return(0);
     }
     if (curUser->IsSwitchingTooFast()) {
         curUser->CmdResult(CMD_JOIN,FALSE,CMD_JOIN_TOOFAST);
         return(1);
     }
     pJoin=static_cast<CTlcJoinInf*>(tlcwrk);
     stzcpy(input,pParam->m_pszCmdParam,tinpsz);
     parsin();
     pCurrentChannel=tlcAPI->chanGetByName(pUser->GetChannelName());
     if (pCurrentChannel->GetType()&CHAN_TYPE_FORUM
      && pUser->GetTransport() == transTerm
      && (aachat[pUser->GetUsrnum()].flags&XTOOTH)
      && !tlcAPI->m_bForSameChg
      && !tlcAPI->m_bSwitFor) {
          pUser->CmdResult(CMD_JOIN,FALSE,CMD_JOIN_CANTLFORUM);
          return(1);
     }
     if (margc == 0) {
          if (pCurrentChannel->GetType()&CHAN_TYPE_PRIVATE) {
               const CHAR* pszOwner;
               pszOwner=(dynamic_cast<CTlcPrivateChannel*>(pCurrentChannel))->GetOwner();
               if (pszOwner != NULL && sameas(pszOwner,pUser->GetName()))  {
                    // they're in their private channel, so we
                    //  want to go to main
                    if ((pNewChannel=tlcAPI->chanCheckPub(dftchan,TRUE)) == NULL) {
                         if ((pNewChannel=tlcAPI->chanCheckPub(mainchan,TRUE)) == NULL) {
                              catastro("No default channel avaliable!");
                         }
                    }
               }
               else {
                    // they're in a private channel, but not their's
                    tlcAPI->chanCheckPrivate(pUser->GetName(),&pNewChannel);
               }
          }
          else {
               // they're not even in a private channel
               tlcAPI->chanCheckPrivate(pUser->GetName(),&pNewChannel);
          }
     }
     else {
          CTlcPrivateChannel* pPrivate;
          rstrin();
          stzcpy(pJoin->m_strName,margv[0],CHAN_MAX_SIZE);
          switch (tlcAPI->chanCheckPrivate(pJoin->m_strName,&pNewChannel)) {
          case CHAN_PRIVATE_FOUND:
               // make sure user is invited
               pPrivate=dynamic_cast<CTlcPrivateChannel*>(pNewChannel);
               if (sameas(pUser->GetName(),pPrivate->GetOwner())
                || pUser->IsTypeOf(USR_OPERATOR)
                || pPrivate->CheckInvite(pUser)) {
                    joinpriv=TRUE;
                    break;
               }
               else {
                    stzcpy(pJoin->m_strName,pPrivate->GetOwner(),TLCUIDSIZ);
                    pUser->CmdResult(CMD_JOIN,FALSE,CMD_JOIN_NOT_INVITED);
                    return(1);
               }
          case CHAN_PRIVATE_NOTFND:
               break;
          case CHAN_PRIVATE_AMBIG:
               pUser->CmdResult(CMD_JOIN,FALSE,CMD_JOIN_AMBIG);
               return(1);
          }
          if (!joinpriv) {
               if ((pNewChannel=tlcAPI->chanCheckPub(margv[0],FALSE)) == NULL) {
                    if (sameas(dftchan,margv[0])) {
                        pNewChannel=tlcAPI->chanCheckPub(mainchan,TRUE);
                    }
                    else {
                        pUser->CmdResult(CMD_JOIN,FALSE,CMD_JOIN_NOCHAN);
                        return(1);
                    }
               }
          }
     }
     // we got a channel! now lets check access!
     // private channel security was handled already, so let them by
     if (!joinpriv) {
          if (pNewChannel->GetType()&CHAN_TYPE_FORUM
           && !tlcAPI->m_bForSameChg && !tlcAPI->m_bSwitFor) {
               pUser->CmdResult(CMD_JOIN,FALSE,CMD_JOIN_CANTJFORUM);
               return(1);
          }
          if (!(pNewChannel->CanAccess(pUser,CHAN_AXS_JOIN))
           || (pNewChannel->m_flags&CHAN_FLAG_CLOSED))  {
               if (!(pUser->IsTypeOf(USR_MODERATOR)
                || pNewChannel->CanAccess(pUser,CHAN_AXS_MODERATOR))) {
                    pUser->CmdResult(CMD_JOIN,FALSE,CMD_JOIN_NOACS);
                    return(1);
               }
          }
     }
     // we have access, so lets join it!
     if (!sameas(pCurrentChannel->GetName(),pNewChannel->GetName())) {
          CHAR name[TLCUIDSIZ];
          CTlcUser* pNewUser;
          strcpy(name,pUser->GetName());
          pUser->m_fFlags|=USR_INCHAN;
          pNewChannel->AddUser(pUser);
          pNewUser=tlcAPI->chanFindUser(pNewChannel->GetName(),name);
          pCurrentChannel->RemoveUser(pUser);
          pNewUser->CmdResult(CMD_JOIN,TRUE,0);
          pNewUser->Switched();
     }
     else {
          // user already is in this channel!
          if (!joinpriv) {
               pUser->CmdResult(CMD_JOIN,FALSE,CMD_JOIN_ALREADY);
          }
          else {
               stzcpy(pJoin->m_strName,(dynamic_cast<CTlcPrivateChannel*>(pNewChannel))->GetOwner(),TLCUIDSIZ);
               pUser->CmdResult(CMD_JOIN,FALSE,CMD_JOIN_PRIV_ALREADY);
          }
     }
     return(1);
}

SHORT CcmdMain::DoCmd(CCommandParam* pParam)
{
     if (!CTlcCommand::DoCmd(pParam)) {
          return(1);
     }
     stzcpy(input,pParam->m_pszCmdParam,tinpsz);
     parsin();
     if (margc != 0) {
          return(0);
     }
     pParam->m_pszCmdParam=mainchan;
     return(cmdJoin->DoCmd(pParam));
}


SHORT CcmdScan::DoCmd(CCommandParam* pParam)
{
     CTlcChannel* pChannel;

     CTlcUser*    pUser;
     CTlcUser*    pOthUsr;

     if (!CTlcCommand::DoCmd(pParam)) {
          return(1);
     }
     pUser=UserStructToClass(pParam->m_pUser);
     if (!(pUser->m_fFlags&USR_INCHAN)) {
          return(0);
     }
     stlcpy(input,pParam->m_pszCmdParam,tinpsz);
     parsin();
     if (margc == 0) {
          /* list only local users */
          pUser->CmdResult(CMD_SCAN,FALSE,CMD_SCAN_START);
          pOthUsr=tlcAPI->usrGetFirst();
          while (pOthUsr != NULL) {
               VOID* SavePos=tlcAPI->usrGetPos();
               if (teleIsLocal(pOthUsr)) {
                    ScanListUser(pUser,pOthUsr);
               }
               tlcAPI->usrSetPos(SavePos);
               pOthUsr=tlcAPI->usrGetNext();
          }
          pUser->CmdResult(CMD_SCAN,TRUE,CMD_SCAN_DONE);
     }
     else if (margc == 1 && sameas(margv[0],"all")) {
          /* list all users on all channels */
          pUser->CmdResult(CMD_SCAN,FALSE,CMD_SCAN_START);
          pChannel=tlcAPI->chanGetFirst();
          while (pChannel != NULL) {
               VOID* SavePos=tlcAPI->chanGetPos();
               ScanListChan(pChannel,pUser);
               tlcAPI->chanSetPos(SavePos);
               pChannel=tlcAPI->chanGetNext();
          }
          pUser->CmdResult(CMD_SCAN,TRUE,CMD_SCAN_DONE);
     }
     else if ((margc == 1 || margc == 2)
           && (sameas(margv[0],"c")
            || sameas(margv[0],"chan")
            || sameas(margv[0],"channel"))) {
          /* list all the users on a particular channel */
          pChannel=tlcAPI->chanGetByName(margc == 1 ? pUser->GetChannelName()
                                                    : margv[1]);
          if (pChannel != NULL) {
               pUser->CmdResult(CMD_SCAN,FALSE,CMD_SCAN_START);
               ScanListChan(pChannel,pUser);
          }
          else {
               /* if bad channel name, rebuff the guy! */
               pUser->CmdResult(CMD_SCAN,FALSE,CMD_SCAN_NOSUCH);
               return(1);
          }
          pUser->CmdResult(CMD_SCAN,TRUE,CMD_SCAN_DONE);
     }
     else {
          /* list all users on a paricular board */
          pUser->CmdResult(CMD_SCAN,FALSE,CMD_SCAN_START);
          pOthUsr=tlcAPI->usrGetFirst();
          while (pOthUsr != NULL) {
               if (findstg(margv[0],const_cast<CHAR*>(pOthUsr->GetName())) > 0) {
                    VOID* SavePos=tlcAPI->usrGetPos();
                    ScanListUser(pUser,pOthUsr);
                    tlcAPI->usrSetPos(SavePos);
               }
               pOthUsr=tlcAPI->usrGetNext();
          }
          pUser->CmdResult(CMD_SCAN,TRUE,CMD_SCAN_DONE);
    }
    return(1);
}

static VOID
ScanListChan(
CTlcChannel* pChannel,
CTlcUser* pUser)
{
     CTlcUser* pOthUsr=pChannel->GetFirstUser();

     while (pOthUsr != NULL) {
          VOID* SavePos=tlcAPI->usrGetPos();
          ScanListUser(pUser,pOthUsr);
          tlcAPI->usrSetPos(SavePos);
          pOthUsr=pChannel->GetNextUser();
     }
}

static VOID
ScanListUser(
CTlcUser *pUser,
CTlcUser *pOthUsr)
{
     CTlcScanInf* pScanInf=static_cast<CTlcScanInf*>(tlcwrk);
     CTlcChannel* pChannel;
     SHORT        visInfo;
     CHAR         chanName[CHAN_MAX_SIZE];

     visInfo=FULL;

     if (pOthUsr->m_fFlags&USR_INVISB) {
          return;
     }
     pChannel=tlcAPI->chanGetByName(pOthUsr->GetChannelName());
     if (pChannel == NULL) {
          return;
     }
     if (!pChannel->CanAccess(pUser,CHAN_AXS_SEE)) {
          visInfo|=CHANUN;
     }
     else if (!pOthUsr->IsListed()) {
          visInfo|=UNLIST;
     }
     if (visInfo != FULL) {
          if (pOthUsr == pUser || pUser->CheckAccess(tlcAPI->keyGetSys())) {
               visInfo|=PARA;
          }
          if (visInfo&CHANUN
           && (pChannel->CanAccess(pUser,CHAN_AXS_MODERATOR)
            || pUser->IsTypeOf(USR_MODERATOR))) {
               visInfo|=PARA;
          }
          if (!teleIsLocal(pOthUsr)) {
               visInfo&=~PARA;
          }
     }
     if (pOthUsr->m_fFlags&USR_CHATTING) {
          stzcpy(pScanInf->m_strChan,"(Chatting...)",CHAN_MAX_SIZE);
     }
     else if (!(pOthUsr->m_fFlags&USR_INCHAN)) {
          stzcpy(pScanInf->m_strChan,"(Editing...)",CHAN_MAX_SIZE);
     }
     else if (visInfo == FULL) {
          stzcpy(pScanInf->m_strChan,pChannel->GetName(),CHAN_MAX_SIZE);
     }
     else if (visInfo&PARA) {
          stzcpy(pScanInf->m_strChan,spr("Unlisted... [%s]",pChannel->GetName()),CHAN_MAX_SIZE);
     }
     else {
          stzcpy(pScanInf->m_strChan,"Unlisted...",CHAN_MAX_SIZE);
     }
     stzcpy(pScanInf->m_strUserid,pOthUsr->GetName(),TLCUIDSIZ);
     pScanInf->m_fFlags=0;
     pScanInf->m_fFlags&=~(USR_INVITE|USR_FORGOT);
     stlcpy(chanName,pOthUsr->GetChannelName(),CHAN_MAX_SIZE);
     if (pUser->CheckInvite(pOthUsr)) {
          pScanInf->m_fFlags|=USR_INVITE;
     }
     if (pUser->CheckForget(pOthUsr)) {
          pScanInf->m_fFlags|=USR_FORGOT;
     }
     tlcAPI->chanGetByName(chanName);
     pUser->CmdResult(CMD_SCAN,FALSE,CMD_SCAN_ITEM);
}

SHORT CcmdIgnore::DoCmd(CCommandParam* pParam)
{
     CTlcUser* pUser;
     CTlcUser* pToUser;
     CTlcJoinInf* pIgnore;
     CHAR* pszName;
     SHORT iMatch;

     if (!CTlcCommand::DoCmd(pParam)) {
          return(1);
     }
     pUser=UserStructToClass(pParam->m_pUser);
     ASSERT(pUser != NULL);
     if (!(pUser->m_fFlags&USR_INCHAN)) {
          return(0);
     }
     if (!pUser->CheckAccess(rawmsg(IGNKEY))) {
          pUser->CmdResult(CMD_IGNORE,FALSE,CMD_IGNORE_NOACS);
          return(1);
     }
     stzcpy(input,pParam->m_pszCmdParam,tinpsz);
     parsin();
     rstrin();
     if (margc == 0) {
          pUser->CmdResult(CMD_IGNORE,FALSE,CMD_IGNORE_NOONE);
     }
     else {
          pszName=&margv[0][0];
          pIgnore=static_cast<CTlcJoinInf*>(tlcwrk);
          iMatch=tlcAPI->usrFind(pszName,&pToUser);

          if (iMatch > 1) {
               stzcpy(pIgnore->m_strName,pszName,TLCUIDSIZ);
               pUser->CmdResult(CMD_IGNORE,FALSE,CMD_IGNORE_AMBIG);
          }
          else if (iMatch == 0) {
               stzcpy(pIgnore->m_strName,pszName,TLCUIDSIZ);
               pUser->CmdResult(CMD_IGNORE,FALSE,CMD_IGNORE_NOSUCH);
          }
          else if (sameas(pToUser->GetName(),pUser->GetName())) {
               pUser->CmdResult(CMD_IGNORE,FALSE,CMD_IGNORE_NOSELF);
          }
          else if (pToUser->IsTypeOf(USR_MODERATOR)
                && !pUser->IsTypeOf(USR_OPERATOR)) {
               stzcpy(pIgnore->m_strName,pToUser->GetName(),TLCUIDSIZ);
               pUser->CmdResult(CMD_IGNORE,FALSE,CMD_IGNORE_NOSYS);
          }
          else {
               stzcpy(pIgnore->m_strName,pToUser->GetName(),TLCUIDSIZ);
               if (pUser->CheckIgnore(pToUser)) {
                    pUser->CmdResult(CMD_IGNORE,FALSE,CMD_IGNORE_ALRDY);
               }
               else if (pUser->ToggleIgnore(pToUser)) {
                    pUser->CmdResult(CMD_IGNORE,TRUE,0);
               }
               else {
                    pUser->CmdResult(CMD_IGNORE,FALSE,CMD_IGNORE_TOOMANY);
               }
          }
     }
     return(1);
}

SHORT CcmdNotice::DoCmd(CCommandParam* pParam)
{
     CTlcUser* pUser;
     CTlcUser* pToUser;
     CTlcJoinInf* pNotice;
     CHAR* pszName;
     SHORT iMatch;

     if (!CTlcCommand::DoCmd(pParam)) {
          return(1);
     }
     pUser=UserStructToClass(pParam->m_pUser);
     if (!(pUser->m_fFlags&USR_INCHAN)) {
          return(0);
     }
     stzcpy(input,pParam->m_pszCmdParam,tinpsz);
     parsin();
     rstrin();
     if (margc == 0) {
          pUser->CmdResult(CMD_NOTICE,FALSE,CMD_NOTICE_NOONE);
     }
     else {
          pszName=&margv[0][0];
          pNotice=static_cast<CTlcJoinInf*>(tlcwrk);
          iMatch=tlcAPI->usrFind(pszName,&pToUser);
          if (iMatch > 1) {
               stzcpy(pNotice->m_strName,pszName,TLCUIDSIZ);
               pUser->CmdResult(CMD_NOTICE,FALSE,CMD_NOTICE_AMBIG);
          }
          else if (iMatch == 0) {
               stzcpy(pNotice->m_strName,pszName,TLCUIDSIZ);
               pUser->CmdResult(CMD_NOTICE,FALSE,CMD_NOTICE_NOSUCH);
          }
          else if (sameas(pToUser->GetName(),pUser->GetName())) {
               pUser->CmdResult(CMD_NOTICE,FALSE,CMD_NOTICE_NOSELF);
          }
          else {
               stzcpy(pNotice->m_strName,pToUser->GetName(),TLCUIDSIZ);
               if (!pUser->CheckIgnore(pToUser)) {
                    pUser->CmdResult(CMD_NOTICE,FALSE,CMD_NOTICE_NOTIGN);
               }
               else {
                    pUser->ToggleIgnore(pToUser);
                    pUser->CmdResult(CMD_NOTICE,TRUE,0);
               }
          }
     }
     return(1);
}

SHORT CcmdWhisper::DoCmd(CCommandParam* pParam)
{
     CTlcUser* pUser;
     CTlcUser* pToUser;
     CTlcWhisInf* pWhis;
     CHAR* pszName;
     CHAR* pszMsg;
     VOID* pageCmdInfo;
     INT iMatch;

     if (!CTlcCommand::DoCmd(pParam)) {
          return(1);
     }
     pUser=UserStructToClass(pParam->m_pUser);
     if (!(pUser->m_fFlags&USR_INCHAN) || (pUser->m_fFlags&USR_INVISB)) {
          return(0);
     }
     if (!pUser->IsTypeOf(USR_NORMAL)
       && pUser->m_iTimesSpoken >= tlcAPI->m_npaymx) {
          return(0);
     }
     SHORT spd=curUser->IsTalkingTooFast();
     if (spd == USR_SPEED_TOOFAST) {
         curUser->CmdResult(CMD_SPEAK,FALSE,CMD_SPEAK_TOOFAST);
         return(1);
     }
     else if (spd == USR_SPEED_DROP && curUser->GetUsrnum() >= 0) {
         INT SaveUser=usrnum;
         curusr(curUser->GetUsrnum());
         byenow(TOOANOY);
         curusr(SaveUser);
         return(1);
     }
     stzcpy(input,pParam->m_pszCmdParam,tinpsz);
     parsin();
     if (margc == 0) {
          pUser->CmdResult(CMD_WHISPER,FALSE,CMD_WHISPER_NOONE);
     }
     else {
          pszName=&margv[0][0];
          pWhis=static_cast<CTlcWhisInf*>(tlcwrk);
          if (margc >= 1 || margv[0][0] == '/') {
               if (margv[0][0] == '/') {
                    pszName=const_cast<CHAR*>(pUser->GetLastWhispered());
                    if (pszName == NULL || *pszName == '\0') {
                         pUser->CmdResult(CMD_WHISPER,FALSE,CMD_WHISPER_REFAILED);
                         return(1);
                    }
                    // add cnf
                    if ((iMatch=tlcAPI->HowManyMatch(pszName,&pToUser,FALSE)) == 0) {
                         pUser->CmdResult(CMD_WHISPER,FALSE,CMD_WHISPER_REFAILED);
                         pUser->SetLastWhispered("");
                         return(1);
                    }
                    else if (margv[0][1] == '\0' && margc > 1) {
                         pszMsg=&margv[1][0];
                    }
                    else {
                         pszMsg=&margv[0][1];
                    }
               }
               else {
                    pszMsg=curChannel->FindUser(pszName,&iMatch,&pToUser);
               }
               if (iMatch > 1) {
                    strcpy(pWhis->m_strName,pszName);
                    pUser->CmdResult(CMD_WHISPER,FALSE,CMD_WHISPER_PAMBIG);
               }
               else if (iMatch == 0) {
                    if (tlcAPI->m_bWhs2Pag) {
                        pUser->CmdResult(CMD_WHISPER,FALSE,CMD_WHISPER_PAGATT);
                        stlcpy(input,"/p ",tinpsz);
                        stlcat(input,pParam->m_pszCmdParam,tinpsz);
                        parsin();
                        rstrin();
                        pageCmdInfo=static_cast<VOID*>(tlcwrk);

                        INT savstate=usrptr->state;
                        usrptr->state=GetTeleState();
                        (*hdlPageCmdRou)(pageUserMessage(NULL,pageCmdInfo),pageCmdInfo);
                        usrptr->state=savstate;
                        curUser->GetTransport()->Output(curUser);
                        clrprf();
                    }
                    else {
                         pUser->CmdResult(CMD_WHISPER,FALSE,CMD_WHISPER_NOSUCH);
                    }
               }
               else if (iMatch != 1) {
                    strcpy(pWhis->m_strName,pszName);
                    pUser->CmdResult(CMD_WHISPER,FALSE,CMD_WHISPER_AMBIG);
               }
               else {
                    if (*pszMsg == '\0') {
                         pUser->CmdResult(CMD_WHISPER,FALSE,CMD_WHISPER_NOONE);
                    }
                    else if (pToUser->CheckForget(pUser)) {
                         strcpy(pWhis->m_strName,pToUser->GetName());
                         pUser->CmdResult(CMD_WHISPER,FALSE,CMD_WHISPER_FGT);
                    }
                    else {
                         rstrin();
                         pToUser->OnRecvText(pUser->GetName(),NULL,pszMsg,RECV_TYPE_WHISPER,WHMSG_WHIS_SEND);
                         pUser->OnRecvText(pUser->GetName(),NULL,pszMsg,RECV_TYPE_WHISPERFR,WHSFRM3,pToUser->GetName());
                         pUser->SetLastWhispered(pToUser->GetName());
                         pUser->CmdResult(CMD_WHISPER,TRUE,0);
                    }
               }
          }
          else {
               pUser->CmdResult(CMD_WHISPER,FALSE,CMD_WHISPER_NOONE);
          }
     }
     return(1);
}

SHORT CcmdDirect::DoCmd(CCommandParam* pParam)
{
     CTlcUser* pUser;
     CTlcUser* pToUser;
     CTlcWhisInf* pWhis;
     CHAR* pszName;
     CHAR* pszMsg;
     INT iMatch;

     if (!CTlcCommand::DoCmd(pParam)) {
          return(1);
     }
     pUser=UserStructToClass(pParam->m_pUser);
     if (!(pUser->m_fFlags&USR_INCHAN) || (pUser->m_fFlags&USR_INVISB)) {
          return(0);
     }
     if (!pUser->IsTypeOf(USR_NORMAL) &&
      pUser->m_iTimesSpoken >= tlcAPI->m_npaymx) {
          return(0);
     }
     SHORT spd=curUser->IsTalkingTooFast();
     if (spd == USR_SPEED_TOOFAST) {
         curUser->CmdResult(CMD_SPEAK,FALSE,CMD_SPEAK_TOOFAST);
         return(1);
     }
     else if (spd == USR_SPEED_DROP && curUser->GetUsrnum() >= 0) {
         INT SaveUser=usrnum;
         curusr(curUser->GetUsrnum());
         byenow(TOOANOY);
         curusr(SaveUser);
         return(1);
     }
     stzcpy(input,pParam->m_pszCmdParam,tinpsz);
     parsin();
     if (margc == 0) {
          pUser->CmdResult(CMD_DIRECT,FALSE,CMD_DIRECT_NOONE);
     }
     else {
          stzcpy(input,pParam->m_pszCmdParam,tinpsz);
          parsin();
          pszName=&margv[0][0];
          pWhis=static_cast<CTlcWhisInf*>(tlcwrk);
          if (margc > 1) {
               CTlcChannel* pChannel=tlcAPI->chanGetByName(pUser->GetChannelName());
               ASSERT(pChannel != NULL);
               pszMsg=pChannel->FindUser(pszName,&iMatch,&pToUser);
               if (iMatch > 1) {
                    strcpy(pWhis->m_strName,pszName);
                    pUser->CmdResult(CMD_DIRECT,FALSE,CMD_DIRECT_DAMBIG);
               }
               else if (iMatch == 0) {
                    pUser->CmdResult(CMD_DIRECT,FALSE,CMD_DIRECT_NOSUCH);
               }
               else if (iMatch != 1) {
                    strcpy(pWhis->m_strName,pszName);
                    pUser->CmdResult(CMD_DIRECT,FALSE,CMD_DIRECT_AMBIG);
               }
               else {
                    strcpy(pWhis->m_strName,pToUser->GetName());
                    if (*pszMsg == '\0') {
                         pUser->CmdResult(CMD_DIRECT,FALSE,CMD_DIRECT_NOONE);
                    }
                    else if (pUser->m_fFlags&USR_SQUELCH) {
                         pUser->CmdResult(CMD_DIRECT,FALSE,CMD_DIRECT_SQ);
                    }
                    else if (pToUser->CheckForget(pUser)) {
                         pUser->CmdResult(CMD_DIRECT,FALSE,CMD_DIRECT_FGT);
                    }
                    else {
                         pChannel->PublicSend(pUser->GetName(),NULL,pszMsg,RECV_TYPE_DIRECTED,DIMSG_DIR_SEND,pWhis->m_strName);
                         pUser->CmdResult(CMD_DIRECT,TRUE,0);
                    }
               }
          }
          else {
               pUser->CmdResult(CMD_DIRECT,FALSE,CMD_DIRECT_NOONE);
          }
     }
     return(1);
}

SHORT CcmdUnlist::DoCmd(CCommandParam* pParam)
{
     CTlcUser*    pUser;

     if (!CTlcCommand::DoCmd(pParam)) {
          return(1);
     }
     pUser=UserStructToClass(pParam->m_pUser);
     if (!(pUser->m_fFlags&USR_INCHAN)) {
          return(0);
     }
     stzcpy(input,pParam->m_pszCmdParam,tinpsz);
     parsin();
     if (margc != 0) {
          return(0);
     }
     pUser->List();
     if (pUser->IsListed()) {
          pUser->CmdResult(CMD_UNLIST,TRUE,0);
     }
     else {
          pUser->CmdResult(CMD_UNLIST,FALSE,0);
     }
     curChannel->PublicSendAllChanNoEx(pUser->GetName(),pUser->GetName(),NULL,
                                      RECV_TYPE_LISTCHG,0);
     return(1);
}


SHORT CcmdList::DoCmd(CCommandParam* pParam)
{
     CTlcChannel* pChannel;
     CTlcListInf* pListInf;
     CTlcUser*    pUser;

     if (!CTlcCommand::DoCmd(pParam)) {
          return(1);
     }
     pUser=UserStructToClass(pParam->m_pUser);
     if (!(pUser->m_fFlags&USR_INCHAN)) {
          return(0);
     }
     pChannel=tlcAPI->chanGetFirst();
     pUser->CmdResult(CMD_LIST,FALSE,CMD_LIST_START);
     pListInf=static_cast<CTlcListInf*>(tlcwrk);
     while (pChannel != NULL) {
          VOID* SavePos=tlcAPI->chanGetPos();
          if (pChannel->GetType()&CHAN_TYPE_PRIVATE) {
               CTlcPrivateChannel* pPrivate;
               pPrivate=dynamic_cast<CTlcPrivateChannel*>(pChannel);
               if (!pPrivate->CheckInvite(pUser)
                && !sameas(curUser->GetName(),pPrivate->GetOwner())) {
                    tlcAPI->chanSetPos(SavePos);
                    pChannel=tlcAPI->chanGetNext();
                    continue;
               }
          }
          if (pChannel->m_flags&CHAN_FLAG_NOLIST) {
               tlcAPI->chanSetPos(SavePos);
               pChannel=tlcAPI->chanGetNext();
               continue;
          }
          if (pChannel->CanAccess(pUser,CHAN_AXS_SEE)
           || pUser->CheckAccess(tlcAPI->keyGetSys())) {
               stzcpy(pListInf->m_strName,pChannel->GetName(),CHAN_MAX_SIZE);
               stzcpy(pListInf->m_strTopic,pChannel->GetTopic(),CHAN_MAX_TOPIC_SIZE);
               pListInf->m_iUsers=pChannel->GetNumVisible();
               pUser->CmdResult(CMD_LIST,FALSE,CMD_LIST_ITEM);
          }
          tlcAPI->chanSetPos(SavePos);
          pChannel=tlcAPI->chanGetNext();
     }
     pUser->CmdResult(CMD_LIST,TRUE,CMD_LIST_DONE);
     return(1);
}

SHORT CcmdHelp::DoCmd(CCommandParam* pParam)
{
     CTlcUser* pUser;

     if (!CTlcCommand::DoCmd(pParam)) {
          return(1);
     }
     stzcpy(input,pParam->m_pszCmdParam,tinpsz);
     parsin();
     if (margc != 0) {
          return(0);
     }
     pUser=UserStructToClass(pParam->m_pUser);
     if (!(pUser->m_fFlags&USR_INCHAN)) {
          return(0);
     }
     pUser->CmdResult(CMD_HELP,TRUE,CMD_HELP_ALL);
     return(1);
}

SHORT CcmdEdit::DoCmd(CCommandParam* pParam)
{
     CTlcUser* pUser;
     CTlcChannel* pChannel;

     if (!CTlcCommand::DoCmd(pParam)) {
          return(1);
     }
     pUser=UserStructToClass(pParam->m_pUser);
     if (!(pUser->m_fFlags&USR_INCHAN)) {
          return(0);
     }
     stzcpy(input,pParam->m_pszCmdParam,tinpsz);
     parsin();
     if (margc != 0) {
          return(0);
     }
     pUser->CmdResult(CMD_EDIT,TRUE,CMD_EDIT_ENTER);
     pChannel=tlcAPI->chanGetByName(pUser->GetChannelName());
     ASSERT(pChannel != NULL);
     pChannel->PublicSend(pUser->GetName(),NULL,NULL,RECV_TYPE_ENTEREDEDIT);
     return(1);
}

SHORT CcmdMenu::DoCmd(CCommandParam* pParam)
{
     CTlcUser* pUser;
     CTlcChannel* pChannel;

     if (!CTlcCommand::DoCmd(pParam)) {
          return(1);
     }
     stzcpy(input,pParam->m_pszCmdParam,tinpsz);
     parsin();
     if (margc != 0) {
          return(0);
     }
     pUser=UserStructToClass(pParam->m_pUser);
     if (!(pUser->m_fFlags&USR_INCHAN)) {
          return(0);
     }
     if (!pUser->CheckAccess(rawmsg(MNUKEY))) {
          return(2);
     }
     if (tlcsysedt.m_usrnum < 0) {
          pUser->CmdResult(CMD_MENU,TRUE,0);
          pChannel=tlcAPI->chanGetByName(pUser->GetChannelName());
          ASSERT(pChannel != NULL);
          pChannel->PublicSend(pUser->GetName(),NULL,NULL,RECV_TYPE_ENTEREDEDIT);
     }
     else {
          pUser->CmdResult(CMD_MENU,FALSE,0);
     }
     return(1);
}

SHORT CcmdChannel::DoCmd(CCommandParam* pParam)
{
     CTlcUser* pUser;
     CTlcChannel* pChannel;

     if (!CTlcCommand::DoCmd(pParam)) {
          return(1);
     }
     pUser=UserStructToClass(pParam->m_pUser);
     if (!(pUser->m_fFlags&USR_INCHAN)) {
          return(0);
     }
     pChannel=tlcAPI->chanGetByName(pUser->GetChannelName());
     ASSERT(pChannel != NULL);

     SHORT OpType;
     if (pUser->IsTypeOf(USR_OPERATOR)) {
          OpType=CMD_CHANNEL_ENTER_SYS;
     }
     else if (!(pChannel->GetType()&CHAN_TYPE_NOEDIT)
      && (pUser->IsTypeOf(USR_MODERATOR)
      || pChannel->CanAccess(pUser,CHAN_AXS_MODERATOR))) {
          OpType=CMD_CHANNEL_ENTER_MOD;
     }
     else {
          return(2);
     }
     if (cedctrl.user < 0) {
          pUser->CmdResult(CMD_CHANNEL,TRUE,OpType);
          pChannel->PublicSend(pUser->GetName(),NULL,NULL,RECV_TYPE_ENTEREDEDIT);
     }
     else {
          pUser->CmdResult(CMD_CHANNEL,FALSE,0);
     }
     return(1);
}

SHORT CcmdAction::DoCmd(CCommandParam* pParam)
{
     CTlcUser* pUser;
     CTlcAList* pList;
     const CHAR* pAction;

     if (!CTlcCommand::DoCmd(pParam)) {
          return(1);
     }
     pUser=UserStructToClass(pParam->m_pUser);
     if (!(pUser->m_fFlags&USR_INCHAN)) {
          return(0);
     }
     stzcpy(input,pParam->m_pszCmdParam,tinpsz);
     parsin();
     if (margc == 0 || (margc == 1 && sameas(margv[0],"?"))) {
          // display help
          pUser->CmdResult(CMD_ACTION,TRUE,CMD_ACTION_HELP);
     }
     else if (margc == 1 && sameas(margv[0],"list")) {
          // display all lists in this channel
          CTlcActInf* actinf;
          LPCHANINFO cconfig;
          GBOOL listed=FALSE;
          actinf=reinterpret_cast<CTlcActInf*>(tlcwrk);
          pList=tlcAPI->actGetFirst();
          cconfig=tlcAPI->chanGetByName(pUser->GetChannelName())->GetConfig();
          while (pList != NULL) {
               int num;
               if (sameas(pList->GetName(),cconfig->m_actList1)
                || sameas(pList->GetName(),cconfig->m_actList2)) {
                    stzcpy(actinf->m_listname,pList->GetName(),LISTSIZ);
                    pUser->CmdResult(CMD_ACTION,TRUE,CMD_ACTION_NEXTLINE);
                    pUser->CmdResult(CMD_ACTION,TRUE,CMD_ACTION_LISTHEADER);
                    pAction=pList->wordGetFirst();
                    num=0;
                    while (pAction != NULL) {
                         if (pUser->CheckAccess(pList->actionGetCurrent().actkey)) {
                              num++;
                              stzcpy(actinf->m_act,pAction,ACTSIZ);
                              pUser->CmdResult(CMD_ACTION,TRUE,CMD_ACTION_LIST);
                              if (num == 4) {
                                   pUser->CmdResult(CMD_ACTION,TRUE
                                                   ,CMD_ACTION_NEXTLINE);
                                   num=0;
                              }
                              listed=TRUE;
                         }
                         pAction=pList->wordGetNext();
                    }
                    pUser->CmdResult(CMD_ACTION,TRUE,CMD_ACTION_NEXTLINE);
               }
               pList=tlcAPI->actGetNext();
          }
          if (!listed) {
               pUser->CmdResult(CMD_ACTION,FALSE,CMD_ACTION_NONE);
          }
     }
     else if (margc == 1 && sameas(margv[0],"edit")) {
          // do edit stuff
          if (!pUser->CheckAccess(rawmsg(AEDTKEY))
           && !pUser->CheckAccess(rawmsg(TSYSKEY))) {
               // display help
               pUser->CmdResult(CMD_ACTION,TRUE,CMD_ACTION_HELP);
          }
          else if (aedctrl.user < 0) {
               // go into editor
               pUser->CmdResult(CMD_ACTION,TRUE,CMD_ACTION_EDITOR);
               curChannel->PublicSend(pUser->GetName(),NULL,NULL
                                     ,RECV_TYPE_ENTEREDEDIT);
          }
          else {
               // editor busy
               pUser->CmdResult(CMD_ACTION,FALSE,CMD_ACTION_EDITOR);
          }
     }
     else if (margc == 1 && sameas(margv[0],"on")) {
          pUser->m_fFlags&=~USR_NOACTIONS;
          pUser->CmdResult(CMD_ACTION,TRUE,CMD_ACTION_ON);
     }
     else if (margc == 1 && sameas(margv[0],"off")) {
          pUser->m_fFlags|=USR_NOACTIONS;
          pUser->CmdResult(CMD_ACTION,TRUE,CMD_ACTION_OFF);
     }
     else {
          // check margv[1] for list name, and if list is ok
          if ((pList=tlcAPI->actGetByName(margv[1])) != NULL) {
               CTlcActInf* actinf;
               actinf=reinterpret_cast<CTlcActInf*>(tlcwrk);
               stzcpy(actinf->m_listname,pList->GetName(),LISTSIZ);
               pUser->CmdResult(CMD_ACTION,TRUE,CMD_ACTION_LISTHEADER);
               pAction=pList->wordGetFirst();
               while (pAction != NULL) {
                    stzcpy(actinf->m_act,pAction,ACTSIZ);
                    pAction=pList->wordGetNext();
                    pUser->CmdResult(CMD_ACTION,TRUE,CMD_ACTION_LIST);
               }
          }
          else {
               pUser->CmdResult(CMD_ACTION,FALSE,CMD_ACTION_NOSUCHLIST);
          }
     }
     return(1);
}

SHORT CcmdTopic::DoCmd(CCommandParam* pParam)
{
     CTlcUser* pUser;
     CHAR* pTopic;

     if (!CTlcCommand::DoCmd(pParam)) {
          return(1);
     }
     stzcpy(input,pParam->m_pszCmdParam,tinpsz);
     parsin();
     pUser=UserStructToClass(pParam->m_pUser);
     if (!(pUser->m_fFlags&USR_INCHAN)) {
          return(0);
     }
     if (pUser->CheckAccess(rawmsg(TOPKEY))) {
          if (strlen(pParam->m_pszCmdParam) >= CHAN_MAX_TOPIC_SIZE) {
               pUser->CmdResult(CMD_TOPIC,TRUE,CMD_TOPIC_TOOLONG);
          }
          else {
               pUser->SetPrivateTopic(pParam->m_pszCmdParam);
               if (*(pParam->m_pszCmdParam) == '\0') {
                    pUser->CmdResult(CMD_TOPIC,TRUE,CMD_TOPIC_CLEARED);
               }
               else {
                    pTopic=static_cast<CHAR*>(tlcwrk);
                    stzcpy(pTopic,pUser->GetPrivateTopic(),WRKBUFSIZ);
                    pUser->CmdResult(CMD_TOPIC,TRUE,CMD_TOPIC_CHANGED);
               }
          }
     }
     else {
          pUser->SetPrivateTopic("");
          pUser->CmdResult(CMD_TOPIC,FALSE,CMD_TOPIC_NOACCESS);
     }
     return(1);
}

SHORT CcmdInvite::DoCmd(CCommandParam* pParam)
{
     CTlcUser* pUser;
     CTlcUser* pToUser;
     CTlcJoinInf* pInvite;
     CHAR* pszName;
     SHORT iMatch;

     if (!CTlcCommand::DoCmd(pParam)) {
          return(1);
     }
     pUser=UserStructToClass(pParam->m_pUser);
     ASSERT(pUser != NULL);
     if (!(pUser->m_fFlags&USR_INCHAN)) {
          return(0);
     }
     if (!pUser->CheckAccess(rawmsg(INVKEY))) {
          pUser->CmdResult(CMD_INVITE,FALSE,CMD_INVITE_NOACS);

          return(1);
     }
     stzcpy(input,pParam->m_pszCmdParam,tinpsz);
     parsin();
     rstrin();
     if (margc == 0) {
          pUser->CmdResult(CMD_INVITE,FALSE,CMD_INVITE_NOONE);
     }
     else {
          pszName=&margv[0][0];
          pInvite=static_cast<CTlcJoinInf*>(tlcwrk);
          iMatch=tlcAPI->usrFind(pszName,&pToUser);
          if (iMatch > 1) {
               stzcpy(pInvite->m_strName,pszName,TLCUIDSIZ);
               pUser->CmdResult(CMD_INVITE,FALSE,CMD_INVITE_AMBIG);
          }
          else if (iMatch == 0) {
               stzcpy(pInvite->m_strName,pszName,TLCUIDSIZ);
               pUser->CmdResult(CMD_INVITE,FALSE,CMD_INVITE_NOSUCH);
          }
          else if (sameas(pToUser->GetName(),pUser->GetName())) {
               pUser->CmdResult(CMD_INVITE,FALSE,CMD_INVITE_NOSELF);
          }
          else {
               stzcpy(pInvite->m_strName,pToUser->GetName(),TLCUIDSIZ);
               if (!(pToUser->GetTransport()->m_fFlags&TRANS_IMPLPRIV)) {
                    strcat((CHAR*)tlcwrk,"\t");
                    strcat((CHAR*)tlcwrk,pToUser->GetTransport()->GetName());
                    pUser->CmdResult(CMD_INVITE,FALSE,CMD_INVITE_CANT);
               }
               else if (pUser->CheckInvite(pToUser)) {
                    pUser->CmdResult(CMD_INVITE,FALSE,CMD_INVITE_ALRDY);
               }
               else if (pToUser->CheckForget(pUser)) {
                    pUser->CmdResult(CMD_INVITE,FALSE,CMD_INVITE_FGT);
               }
               else if (pUser->ToggleInvite(pToUser)) {
                    pUser->CmdResult(CMD_INVITE,TRUE,0);
                    stzcpy(pInvite->m_strName,pUser->GetName(),TLCUIDSIZ);
                    pToUser->CmdResult(CMD_INVITE,TRUE,CMD_INVITE_NOTIFY);
                    if (pToUser->GetUsrnum() > -1) {
                         CTlcChannel* pChannel=tlcAPI->chanGetByName(tlcPrivateFromUser(pUser->GetName()));
                         csnotaddchan(pChannel,pToUser->GetUsrnum());
                    }
               }
               else {
                    pUser->CmdResult(CMD_INVITE,FALSE,CMD_INVITE_TOOMANY);
               }
          }
     }

     return(1);
}

SHORT CcmdUnInvite::DoCmd(CCommandParam* pParam)
{
     CTlcUser* pUser;
     CTlcUser* pToUser;
     CTlcJoinInf* pInvite;
     CHAR* pszName;
     SHORT iMatch;
     CTlcChannel* pChannel;

     if (!CTlcCommand::DoCmd(pParam)) {
          return(1);
     }
     pUser=UserStructToClass(pParam->m_pUser);
     ASSERT(pUser != NULL);
     if (!(pUser->m_fFlags&USR_INCHAN)) {
          return(0);
     }
     stzcpy(input,pParam->m_pszCmdParam,tinpsz);
     parsin();
     rstrin();
     if (margc == 0) {
          pUser->CmdResult(CMD_UNINVITE,FALSE,CMD_UNINVITE_NOONE);
     }
     else {
          pszName=&margv[0][0];
          pInvite=static_cast<CTlcJoinInf*>(tlcwrk);
          iMatch=tlcAPI->usrFind(pszName,&pToUser);
          if (iMatch > 1) {
               // TODO: check so it only checks invited list
               stzcpy(pInvite->m_strName,pszName,TLCUIDSIZ);
               pUser->CmdResult(CMD_UNINVITE,FALSE,CMD_UNINVITE_AMBIG);
          }
          else if (iMatch == 0) {
               stzcpy(pInvite->m_strName,pszName,TLCUIDSIZ);
               pUser->CmdResult(CMD_UNINVITE,FALSE,CMD_UNINVITE_NOSUCH);
          }
          else if (sameas(pToUser->GetName(),pUser->GetName())) {
               pUser->CmdResult(CMD_UNINVITE,FALSE,CMD_UNINVITE_NOSELF);
          }
          else if (pToUser->IsTypeOf(USR_OPERATOR)) {
               pUser->CmdResult(CMD_UNINVITE,FALSE,CMD_UNINVITE_MODERATOR);
               if (pUser->CheckInvite(pToUser)) {
                    pUser->ToggleInvite(pToUser);
               }
          }
          else {
               stzcpy(pInvite->m_strName,pToUser->GetName(),TLCUIDSIZ);
               if (!pUser->CheckInvite(pToUser)) {
                    pUser->CmdResult(CMD_UNINVITE,FALSE,CMD_UNINVITE_NOTINV);
               }
               else {
                    pUser->ToggleInvite(pToUser);
                    tlcAPI->chanCheckPrivate(pUser->GetName(),&pChannel);
                    if (sameas(pToUser->GetChannelName(),pChannel->GetName())) {
                         CTlcChannel* pNewChan;
                         CTlcUser* pNewUser;

                         pUser->CmdResult(CMD_UNINVITE,TRUE,CMD_UNINVITE_MYKICK);
                         stzcpy(pInvite->m_strName,pUser->GetName(),TLCUIDSIZ);
                         pToUser->CmdResult(CMD_UNINVITE,TRUE,CMD_UNINVITE_KICK);
                         if ((pNewChan=tlcAPI->chanGetByName(dftchan)) == NULL) {
                              pNewChan=tlcAPI->chanGetByName(mainchan);
                         }
                         pNewChan->AddUser(pToUser);
                         pNewUser=tlcAPI->chanFindUser(pNewChan->GetName(),pToUser->GetName());

                         pChannel->RemoveUser(pToUser,LEAVE_PRIV_KICK);
                         pNewUser->CmdResult(CMD_JOIN,TRUE,0);
                    }
                    else {
                         stzcpy(pInvite->m_strName,pToUser->GetName(),TLCUIDSIZ);
                         pUser->CmdResult(CMD_UNINVITE,TRUE,CMD_UNINVITE_MYUNINV);
                    }
                    if (pToUser->GetUsrnum() > -1) {
                         CTlcChannel* pChannel=tlcAPI->chanGetByName(tlcPrivateFromUser(pUser->GetName()));
                         csnotdelchan(pChannel,pToUser->GetUsrnum());
                    }
               }
          }
     }
     return(1);
}

SHORT CcmdForget::DoCmd(CCommandParam* pParam)
{
     CTlcUser* pUser;
     CTlcUser* pToUser;
     CTlcJoinInf* pForget;
     CHAR* pszName;
     SHORT iMatch;

     if (!CTlcCommand::DoCmd(pParam)) {
          return(1);
     }
     pUser=UserStructToClass(pParam->m_pUser);
     if (!(pUser->m_fFlags&USR_INCHAN)) {
          return(0);
     }
     if (!pUser->CheckAccess(rawmsg(FGTKEY))) {
          pUser->CmdResult(CMD_FORGET,FALSE,CMD_FORGET_NOACS);

          return(1);
     }
     stzcpy(input,pParam->m_pszCmdParam,tinpsz);
     parsin();
     rstrin();
     if (margc == 0) {
          pUser->CmdResult(CMD_FORGET,FALSE,CMD_FORGET_NOONE);
     }
     else {
          pszName=&margv[0][0];
          pForget=static_cast<CTlcJoinInf*>(tlcwrk);
          iMatch=tlcAPI->usrFind(pszName,&pToUser);
          if (iMatch > 1) {
               stzcpy(pForget->m_strName,pszName,TLCUIDSIZ);
               pUser->CmdResult(CMD_FORGET,FALSE,CMD_FORGET_AMBIG);
          }
          else if (iMatch == 0) {
               stzcpy(pForget->m_strName,pszName,TLCUIDSIZ);
               pUser->CmdResult(CMD_FORGET,FALSE,CMD_FORGET_NOSUCH);
          }
          else if (sameas(pToUser->GetName(),pUser->GetName())) {
               pUser->CmdResult(CMD_FORGET,FALSE,CMD_FORGET_NOSELF);
          }
          else if (pToUser->IsTypeOf(USR_MODERATOR)
                    && !(pUser->IsTypeOf(USR_OPERATOR))) {
               pUser->CmdResult(CMD_FORGET,FALSE,CMD_FORGET_MODERATOR);
          }
          else if (pToUser->CheckAccess(rawmsg(NFGTKEY))
                    && !(pUser->IsTypeOf(USR_MODERATOR))) {
               pUser->CmdResult(CMD_FORGET,FALSE,CMD_FORGET_NOFORGET);
          }
          else {
               stzcpy(pForget->m_strName,pToUser->GetName(),TLCUIDSIZ);
               if (pUser->CheckForget(pToUser)) {
                    pUser->CmdResult(CMD_FORGET,FALSE,CMD_FORGET_ALRDY);
               }
               else if (pUser->ToggleForget(pToUser)) {
                    CTlcChannel* pChannel;
                    if (pUser->CheckInvite(pToUser)) {
                         pUser->ToggleInvite(pToUser);
                         tlcAPI->chanCheckPrivate(pUser->GetName(),&pChannel);
                         if (sameas(pToUser->GetChannelName(),pChannel->GetName())) {
                              CTlcChannel* pNewChan;
                              CTlcUser* pNewUser;

                              stzcpy(pForget->m_strName,pUser->GetName(),TLCUIDSIZ);
                              pToUser->CmdResult(CMD_UNINVITE,TRUE,CMD_UNINVITE_KICK);
                              if ((pNewChan=tlcAPI->chanGetByName(dftchan)) == NULL) {
                                   pNewChan=tlcAPI->chanGetByName(mainchan);
                              }
                              pNewChan->AddUser(pToUser);
                              pNewUser=tlcAPI->chanFindUser(pNewChan->GetName(),pToUser->GetName());

                              pChannel->RemoveUser(pToUser,LEAVE_PRIV_KICK);
                              pNewUser->CmdResult(CMD_JOIN,TRUE,0);
                         }
                         if (pToUser->GetUsrnum() > -1) {
                              CTlcChannel* pChannel=tlcAPI->chanGetByName(tlcPrivateFromUser(pUser->GetName()));
                              csnotdelchan(pChannel,pToUser->GetUsrnum());
                         }
                    }
                    pUser->CmdResult(CMD_FORGET,TRUE,0);
               }
               else {
                    pUser->CmdResult(CMD_FORGET,FALSE,CMD_FORGET_TOOMANY);
               }
          }
     }
     return(1);
}

SHORT CcmdRemember::DoCmd(CCommandParam* pParam)
{
     CTlcUser* pUser;
     CTlcUser* pToUser;
     CTlcJoinInf* pRemember;
     CHAR* pszName;
     SHORT iMatch;

     if (!CTlcCommand::DoCmd(pParam)) {
          return(1);
     }
     pUser=UserStructToClass(pParam->m_pUser);
     if (!(pUser->m_fFlags&USR_INCHAN)) {
          return(0);
     }
     stzcpy(input,pParam->m_pszCmdParam,tinpsz);
     parsin();
     rstrin();
     if (margc == 0) {
          pUser->CmdResult(CMD_REMEMBER,FALSE,CMD_REMEMBER_NOONE);
     }
     else {
          pszName=&margv[0][0];
          pRemember=static_cast<CTlcJoinInf*>(tlcwrk);
          iMatch=tlcAPI->usrFind(pszName,&pToUser);
          if (iMatch > 1) {
               stzcpy(pRemember->m_strName,pszName,TLCUIDSIZ);
               pUser->CmdResult(CMD_REMEMBER,FALSE,CMD_REMEMBER_AMBIG);
          }
          else if (iMatch == 0) {
               stzcpy(pRemember->m_strName,pszName,TLCUIDSIZ);
               pUser->CmdResult(CMD_REMEMBER,FALSE,CMD_REMEMBER_NOSUCH);
          }
          else if (sameas(pToUser->GetName(),pUser->GetName())) {
               pUser->CmdResult(CMD_REMEMBER,FALSE,CMD_REMEMBER_NOSELF);
          }
          else {
               stzcpy(pRemember->m_strName,pToUser->GetName(),TLCUIDSIZ);
               if (!pUser->CheckForget(pToUser)) {
                    pUser->CmdResult(CMD_REMEMBER,FALSE,CMD_REMEMBER_NOTFGT);
               }
               else {
                    pUser->ToggleForget(pToUser);
                    pUser->CmdResult(CMD_REMEMBER,TRUE,0);
               }
          }
     }

     return(1);
}

SHORT CcmdPost::DoCmd(CCommandParam* pParam)
{
     CTlcUser* pUser;
     CHAR uid[UIDSIZ];

     if (!CTlcCommand::DoCmd(pParam)) {
          return(1);
     }
     pUser=UserStructToClass(pParam->m_pUser);
     if (!pUser->CheckAccess(rawmsg(TLCOPKY))) {
          return(2);
     }
     stzcpy(input,pParam->m_pszCmdParam,tinpsz);
     parsin();
     if (margc == 0) {
          return(0);
     }
     rstrin();
     if (tlcAPI->m_iEtlpst == 0) {
          prfmsg(NOTPST2);
     }
     else {
          rstrin();
          stlcpy(uid,margv[0],UIDSIZ);
          switch (addcrd(uid,spr("%d",tlcAPI->m_iEtlpst),0)) {
          case -1:
               prfmsg(BDPUID2);
               break;
          case 1:
               saycrd(spr("%d",tlcAPI->m_iEtlpst),0);
          case 0:
               prfmsg(OKPUID2,tlcAPI->m_iEtlpst,uid);
               break;
          }
     }
     curUser->GetTransport()->Output(curUser);
     clrprf();
     return(1);
}

SHORT CcmdClose::DoCmd(CCommandParam* pParam)
{
     CTlcUser* pUser;

     if (!CTlcCommand::DoCmd(pParam)) {
          return(1);
     }
     stzcpy(input,pParam->m_pszCmdParam,tinpsz);
     parsin();
     if (margc != 0) {
          return(0);
     }
     pUser=UserStructToClass(pParam->m_pUser);
     if (!(pUser->IsTypeOf(USR_MODERATOR))
      && !(curChannel->CanAccess(pUser,CHAN_AXS_MODERATOR))) {
          return(0);
     }
     if (curChannel->m_type&CHAN_TYPE_PRIVATE) {
          pUser->CmdResult(CMD_CLOSE,FALSE,CMD_CLOSE_PRIVATE);
     }
     else if (curChannel->m_flags&CHAN_FLAG_CLOSED) {
          pUser->CmdResult(CMD_CLOSE,FALSE,CMD_CLOSE_ALREADY);
     }
     else {
          curChannel->m_flags|=CHAN_FLAG_CLOSED;
          pUser->CmdResult(CMD_CLOSE,TRUE,0);
     }

     return(1);
}


SHORT CcmdEcho::DoCmd(CCommandParam* pParam)
{
     CTlcUser* pUser;

     if (!CTlcCommand::DoCmd(pParam)) {
          return(1);
     }
     pUser=UserStructToClass(pParam->m_pUser);
     stzcpy(input,pParam->m_pszCmdParam,tinpsz);
     parsin();
     if (margc == 0) {
          pUser->CmdResult(CMD_ECHO,TRUE,CMD_ECHO_HELP);
     }
     else if (sameas(margv[0],"on")) {
          btuech(pUser->GetUsrnum(),2);
          pUser->CmdResult(CMD_ECHO,TRUE,CMD_ECHO_ON);
     }
     else if (sameas(margv[0],"off")) {
          btuech(pUser->GetUsrnum(),0);
          pUser->CmdResult(CMD_ECHO,TRUE,CMD_ECHO_OFF);
     }
     else if (sameas(margv[0],"px")) {
          btuech(pUser->GetUsrnum(),1);
          pUser->CmdResult(CMD_ECHO,TRUE,CMD_ECHO_PX);
     }
     else {
          pUser->CmdResult(CMD_ECHO,TRUE,CMD_ECHO_HELP);
     }

     return(1);
}


SHORT CcmdOpen::DoCmd(CCommandParam* pParam)
{
     CTlcUser* pUser;

     if (!CTlcCommand::DoCmd(pParam)) {
          return(1);
     }
     stzcpy(input,pParam->m_pszCmdParam,tinpsz);
     parsin();
     if (margc != 0) {
          return(0);
     }
     pUser=UserStructToClass(pParam->m_pUser);
     if (!(pUser->IsTypeOf(USR_MODERATOR))
      && !(curChannel->CanAccess(pUser,CHAN_AXS_MODERATOR))) {
          return(0);
     }
     if (!(curChannel->m_flags&CHAN_FLAG_CLOSED)) {
          pUser->CmdResult(CMD_OPEN,FALSE,CMD_OPEN_ALREADY);
     }
     else {
          curChannel->m_flags&=~CHAN_FLAG_CLOSED;
          pUser->CmdResult(CMD_OPEN,TRUE,0);
     }

     return(1);
}

SHORT CcmdZappo::DoCmd(CCommandParam* pParam)
{
     CTlcUser* pUser;
     INT unum;

     if (!CTlcCommand::DoCmd(pParam)) {
          return(0);
     }
     pUser=UserStructToClass(pParam->m_pUser);
     if (!(pUser->IsTypeOf(USR_MODERATOR))) {
          return(0);
     }

	 // /z / GP's.  Arash Aghlara
	 if (margv[1][0]=='/') {
			  return 0;
	 }

     stzcpy(input,pParam->m_pszCmdParam,tinpsz);
     parsin();
     rstrin();
     if (margc < 1) {
          pUser->CmdResult(CMD_ZAPPO,FALSE,CMD_ZAPPO_NOUSR);
     }
     else {
          rstrin();
          if (margv[margc-1][0] == '/') {
               margn[margc-2][0]='\0';
          }
          if (onsysn(margv[0],1)) {
               unum=othusn;
               kilchn(othusn);
               pUser->CmdResult(CMD_ZAPPO,TRUE,0);
               if (margv[margc-1][0] == '/' && pUser->CheckAccess(rawmsg(DELKEY))) {
                    if (tolower(margv[margc-1][1]) == 'd') {
                         if (delacct(uacoff(unum)->userid) >= 0) {
                              pUser->CmdResult(CMD_ZAPPO,TRUE,CMD_ZAPPO_DELETED);
                              shocst("TELE-USER DELETED","%s deleted by %s",
                                     uacoff(unum)->userid,pUser->GetName());
                         }
                         else {
                              pUser->CmdResult(CMD_ZAPPO,FALSE,CMD_ZAPPO_NODELETE);
                         }
                    }
                    else if (tolower(margv[margc-1][1]) == 's') {
                         kiluid(uacoff(unum)->userid);
                         pUser->CmdResult(CMD_ZAPPO,TRUE,CMD_ZAPPO_SUSPENDED);
                    }
               }
          }
          else {
               pUser->CmdResult(CMD_ZAPPO,FALSE,CMD_ZAPPO_NOUSRON);
          }
     }
     return(1);
}

SHORT CcmdSquelch::DoCmd(CCommandParam* pParam)
{
     CTlcUser* pUser;
     CTlcUser* pToUser;
     CTlcJoinInf* pSquelch;
     CHAR* pszName;
     SHORT iMatch;

     if (!CTlcCommand::DoCmd(pParam)) {
          return(1);
     }
     pUser=UserStructToClass(pParam->m_pUser);
     if (!(pUser->m_fFlags&USR_INCHAN)) {
          return(0);
     }
     if (!(pUser->IsTypeOf(USR_MODERATOR))) {
          return(0);
     }
     stzcpy(input,pParam->m_pszCmdParam,tinpsz);
     parsin();
     rstrin();
     if (margc == 0) {
          pUser->CmdResult(CMD_SQUELCH,FALSE,CMD_SQUELCH_NOONE);
     }
     else {
          pszName=&margv[0][0];
          pSquelch=static_cast<CTlcJoinInf*>(tlcwrk);
          iMatch=tlcAPI->usrFind(pszName,&pToUser);
          if (iMatch > 1) {
               stzcpy(pSquelch->m_strName,pszName,TLCUIDSIZ);
               pUser->CmdResult(CMD_SQUELCH,FALSE,CMD_SQUELCH_AMBIG);
          }
          else if (iMatch == 0) {
               stzcpy(pSquelch->m_strName,pszName,TLCUIDSIZ);
               pUser->CmdResult(CMD_SQUELCH,FALSE,CMD_SQUELCH_NOSUCH);
          }
          else if (sameas(pToUser->GetName(),pUser->GetName())) {
               pUser->CmdResult(CMD_SQUELCH,FALSE,CMD_SQUELCH_NOSELF);
          }
          else if (pToUser->IsTypeOf(USR_MODERATOR)
                    && !(pUser->IsTypeOf(USR_OPERATOR))) {
               pUser->CmdResult(CMD_SQUELCH,FALSE,CMD_SQUELCH_MODERATOR);
          }
          else {
               stzcpy(pSquelch->m_strName,pToUser->GetName(),TLCUIDSIZ);
               if (pToUser->m_fFlags&USR_SQUELCH) {
                    pUser->CmdResult(CMD_SQUELCH,FALSE,CMD_SQUELCH_ALRDY);
               }
               else {
                    CTlcUser* pNotifyUser;
                    pToUser->m_fFlags|=USR_SQUELCH;
                    pUser->CmdResult(CMD_SQUELCH,TRUE,0);
                    pNotifyUser=tlcAPI->usrGetFirst();
                    while (pNotifyUser != NULL) {
                         cschgstatus(pNotifyUser,pToUser);
                         pNotifyUser=tlcAPI->usrGetNext();
                    }
               }
          }
     }
     return(1);
}

SHORT CcmdPage::DoCmd(CCommandParam* pParam)
{
     CTlcUser* pUser;
     VOID* pageCmdInfo;

     if (!CTlcCommand::DoCmd(pParam)) {
          return(1);
     }
     pUser=UserStructToClass(pParam->m_pUser);
     if (!(pUser->m_fFlags&USR_INCHAN)) {
          return(0);
     }
     strcpy(input,"/p ");
     stlcat(input,pParam->m_pszCmdParam,INPSIZ);
     parsin();
     pageCmdInfo=static_cast<VOID*>(tlcwrk);

     INT savstate=usrptr->state;
     usrptr->state=GetTeleState();
     (*hdlPageCmdRou)((*parsePageCmdRou)(NULL,pageCmdInfo),pageCmdInfo);
     usrptr->state=savstate;
     curUser->OnRecvText(SYSUID,NULL,NULL,RECV_TYPE_PAGE);
     return(1);
}

SHORT CcmdUnSquelch::DoCmd(CCommandParam* pParam)
{
     CTlcUser* pUser;
     CTlcUser* pToUser;
     CTlcJoinInf* pUnSquelch;
     CHAR* pszName;
     SHORT iMatch;

     if (!CTlcCommand::DoCmd(pParam)) {
          return(1);
     }
     pUser=UserStructToClass(pParam->m_pUser);
     if (!(pUser->m_fFlags&USR_INCHAN)) {
          return(0);
     }
     if (!(pUser->IsTypeOf(USR_MODERATOR))) {
          return(0);
     }
     clrinp();
     stlcpy(input,pParam->m_pszCmdParam,tinpsz);
     parsin();
     rstrin();
     if (margc == 0) {
          pUser->CmdResult(CMD_UNSQUELCH,FALSE,CMD_UNSQUELCH_NOONE);
     }
     else {
          rstrin();
          pszName=margv[0];
          pUnSquelch=static_cast<CTlcJoinInf*>(tlcwrk);
          iMatch=tlcAPI->usrFind(pszName,&pToUser);
          if (iMatch > 1) {
               stzcpy(pUnSquelch->m_strName,pszName,TLCUIDSIZ);
               pUser->CmdResult(CMD_UNSQUELCH,FALSE,CMD_UNSQUELCH_AMBIG);
          }
          else if (iMatch == 0) {
               stzcpy(pUnSquelch->m_strName,pszName,TLCUIDSIZ);
               pUser->CmdResult(CMD_UNSQUELCH,FALSE,CMD_UNSQUELCH_NOSUCH);
          }
          else {
               stzcpy(pUnSquelch->m_strName,pToUser->GetName(),TLCUIDSIZ);
               if (!(pToUser->m_fFlags&USR_SQUELCH)) {
                    pUser->CmdResult(CMD_UNSQUELCH,FALSE,CMD_UNSQUELCH_NOTSQ);
               }
               else {
                    CTlcUser* pNotifyUser;
                    pToUser->m_fFlags&=~USR_SQUELCH;
                    pUser->CmdResult(CMD_UNSQUELCH,TRUE,0);
                    pNotifyUser=tlcAPI->usrGetFirst();
                    while (pNotifyUser != NULL) {
                         cschgstatus(pNotifyUser,pToUser);
                         pNotifyUser=tlcAPI->usrGetNext();
                    }
               }
          }
     }
     return(1);
}

SHORT CcmdChat::DoCmd(CCommandParam* pParam)
{
     CTlcUser* pUser;
     CHAR* pszName;
     INT iMatch;
     CTlcUser* pToUser;
     LONG t;

     if (!CTlcCommand::DoCmd(pParam)) {
          return(1);
     }
     pUser=UserStructToClass(pParam->m_pUser);
     if (!(pUser->m_fFlags&USR_INCHAN) || (pUser->m_fFlags&USR_INVISB)) {
          return(0);
     }
     if (pUser->m_fFlags&USR_CHATTING) {
          pUser->CmdResult(CMD_CHAT,FALSE,CMD_CHAT_YOUALREADY);
          return(1);
     }
     stzcpy(input,pParam->m_pszCmdParam,tinpsz);
     parsin();
     rstrin();
     pszName=&margv[0][0];
     if (margc > 0) {
          curChannel->FindUser(pszName,&iMatch,&pToUser);
          if (iMatch > 1) {
               strcpy((CHAR*)tlcwrk,pszName);
               pUser->CmdResult(CMD_CHAT,FALSE,CMD_CHAT_CAMBIG);
          }
          else if (iMatch == 0) {
               strcpy((CHAR*)tlcwrk,pszName);
               pUser->CmdResult(CMD_CHAT,FALSE,CMD_CHAT_NOSUCH);
          }
          else if (iMatch != 1) {
               strcpy((CHAR*)tlcwrk,pszName);
               pUser->CmdResult(CMD_CHAT,FALSE,CMD_CHAT_AMBIG);
          }
          else if (sameas(pToUser->GetChatUser(),pUser->GetName())) {
               INT oth, usr;
               if (pToUser->m_fFlags&USR_INCHAN) {
                    pUser->SetChatUser(pToUser->GetName());
                    usr=pUser->GetUsrnum();
                    oth=pToUser->GetUsrnum();
                    if (usr >= 0) {
                         aachat[usr].chatch=oth;
                    }
                    if (oth >= 0) {
                         aachat[oth].chatch=usr;
                    }
                    pToUser->ChatBegin(CHAT_ACCEPTED);
                    pUser->ChatBegin(CHAT_START);
               }
               else {
                    pUser->CmdResult(CMD_CHAT,FALSE,CMD_CHAT_BUSY);
               }
               return(1);
          }
          else if (pUser->CheckAccess(rawmsg(CHTKEY))) {
               // check status of other user
               strcpy((CHAR*)tlcwrk,pToUser->GetName());
               if (!(pToUser->GetTransport()->m_fFlags&TRANS_IMPLCHAT)) {
                    strcat((CHAR*)tlcwrk,"\t");
                    strcat((CHAR*)tlcwrk,pToUser->GetTransport()->GetName());
                    pUser->CmdResult(CMD_CHAT,FALSE,CMD_CHAT_CANT);
               }
               else if (pToUser->m_fFlags&USR_CHATTING) {
                    pUser->CmdResult(CMD_CHAT,FALSE,CMD_CHAT_ALREADY);
               }
               else if (sameas(pToUser->GetName(),pUser->GetName())) {
                    pUser->CmdResult(CMD_CHAT,FALSE,CMD_CHAT_SELF);
               }
               else if (pagesetUid(pToUser->GetName()) == PAGE_OFF) {
                    pUser->CmdResult(CMD_CHAT,FALSE,CMD_CHAT_NOCHAT);
               }
               else if (pageIgnoredRou(pToUser->GetName(),pUser->GetName())) {
                    pUser->CmdResult(CMD_CHAT,FALSE,CMD_CHAT_NOCHATU);
               }
               else if (pToUser->CheckForget(pUser)) {
                    pUser->CmdResult(CMD_CHAT,FALSE,CMD_CHAT_FGT);
               }
               else if (!(pToUser->m_fFlags&USR_INCHAN)) {
                    pUser->CmdResult(CMD_CHAT,FALSE,CMD_CHAT_CANTCHAT);
               }
               else if ((t=pToUser->GetChatReqTime()) > 0
                    && (time(NULL) - t < pToUser->GetChatInterval()*60)) {
                         pUser->CmdResult(CMD_CHAT,FALSE,CMD_CHAT_TOOSOON);
               }
               else {
                    pUser->SetChatUser(pToUser->GetName());
                    pToUser->SetChatReqTime();
                    if (pUser->m_fFlags&USR_NOCHAT) {
                         pUser->m_fFlags&=~USR_NOCHAT;
                    }
                    // notify other user of chat request.
                    pUser->CmdResult(CMD_CHAT,TRUE,CMD_CHAT_NOTIFIED);
                    strcpy((CHAR*)tlcwrk,pUser->GetName());
                    pToUser->CmdResult(CMD_CHAT,TRUE,CMD_CHAT_NOTIFY);
               }
          }
          else {
               pUser->CmdResult(CMD_CHAT,FALSE,CMD_CHAT_NOACCESS);
          }
     }
     else {
          pUser->CmdResult(CMD_CHAT,FALSE,CMD_CHAT_HELP);
     }
     return(1);
}

SHORT CcmdUsers::DoCmd(CCommandParam* pParam)
{
     CTlcUser* psavUser;

     if (!CTlcCommand::DoCmd(pParam,TRUE)) {
          // do for c/s and active-h manually
          psavUser=curUser;
          curUser=UserStructToClass(pParam->m_pUser);
          tlcusrson();
          curUser=psavUser;
     }
     else {
          // call terminal mode vector
          usrson();
          clrprf();
          curUser->OnRecvText(SYSUID,NULL,NULL,RECV_TYPE_USERLIST);
     }
     return(1);
}

SHORT CcmdDiag::DoCmd(CCommandParam* pParam)
{
     CTlcChannel* pChannel;
     CTlcTransport* pTransport;
     CTlcUser* pUser;
     CHAR* pszName;


     if (!CTlcCommand::DoCmd(pParam)) {
          return(1);
     }

     stzcpy(input,pParam->m_pszCmdParam,tinpsz);
     parsin();
     rstrin();
     pszName=&margv[0][0];
     if (margc == 0) {
          pChannel=tlcAPI->chanGetFirst();
          while (pChannel != NULL) {
               // dump chan info
               prf("\nChannel %s:\n", pChannel->GetName());
               pUser=pChannel->GetFirstUser();
               while (pUser != NULL) {
                    // dump info on users in this channel
                    prf("User %s on %s:\n", pUser->GetName(),pUser->GetChannelName());
                    pUser=pChannel->GetNextUser();
               }
               pChannel=tlcAPI->chanGetNext();
          }

          prf("****\n");

          pTransport=tlcAPI->transGetFirst();
          while (pTransport != NULL) {
               // dump out transport info
               pUser=pTransport->GetFirstUser(NULL);
               while (pUser != NULL) {
                    prf("User %s on %s:\n", pUser->GetName(),pUser->GetChannelName());
                    pUser=pTransport->GetNextUser(NULL);
               }
               pTransport=tlcAPI->transGetNext();
          }
          outprf(usrnum);
     }
     else {
          SHORT iMatch;
          CTlcUser* pUser;
          if ((iMatch=tlcAPI->usrFind(pszName,&pUser)) == 1) {
               prf("User: %s  Internal Alias: %s\n",margv[0],pUser->GetName());
               prf("Channel: %s\n",pUser->GetChannelName());
               prf("Last Whispered to: %s\n",pUser->GetLastWhispered() == NULL ? "" : pUser->GetLastWhispered());
               prf("Chatting with: %s\n",pUser->GetChatUser() == NULL ? "" : pUser->GetChatUser());
               prf("Type: %hd   usrnum: %d   TlcUnum:  %ld    TlcBoard: %hd\n",
                   pUser->GetType(), pUser->GetUsrnum(), pUser->GetTlcUnum(),
                   pUser->GetTlcBoardNum());
               prf("FLAGS\n=====\n");
               prf("USR_NORMAL: %s ",pUser->IsTypeOf(USR_NORMAL) ? "YES" : "NO");
               prf("USR_SQUELCH: %s\n",pUser->m_fFlags&USR_SQUELCH ? "YES" : "NO");
               prf("USR_MODERATE: %s ",pUser->IsTypeOf(USR_MODERATOR) ? "YES" : "NO");
               prf("USR_OPERATOR: %s\n",pUser->IsTypeOf(USR_OPERATOR) ? "YES" : "NO");
               prf("USR_INVISB: %s ",pUser->m_fFlags&USR_INVISB ? "YES" : "NO");
               prf("USR_UNLIST: %s ",pUser->m_fFlags&USR_UNLIST ? "YES" : "NO");
               prf("USR_INEDIT: %s\n",pUser->m_fFlags&USR_INEDIT ? "YES" : "NO");
               prf("USR_INCHAN: %s ",pUser->m_fFlags&USR_INCHAN ? "YES" : "NO");
               prf("USR_CHATTING: %s ",pUser->m_fFlags&USR_CHATTING ? "YES" : "NO");
               prf("USR_INMENU: %s\n",pUser->m_fFlags&USR_INMENU ? "YES" : "NO");
          }
          else if (iMatch == 0) {
               prf("enter a userid\n");
          }
          else {
               prf("multiple matches\n");
          }
          outprf(usrnum);
     }
     return(1);
}

CcmdDiag* cmdDiag;
CcmdJoin* cmdJoin;
CcmdScan* cmdScan;
CcmdList* cmdList;
CcmdWhisper* cmdWhisper;
CcmdDirect* cmdDirect;
CcmdHelp* cmdHelp;
CcmdUnlist* cmdUnlist;
CcmdEdit* cmdEdit;
CcmdTopic* cmdTopic;
CcmdInvite* cmdInvite;
CcmdUnInvite* cmdUnInvite;
CcmdForget* cmdForget;
CcmdRemember* cmdRemember;
CcmdSquelch* cmdSquelch;
CcmdUnSquelch* cmdUnSquelch;
CcmdChat* cmdChat;
CcmdChannel* cmdChannel;
CcmdAction* cmdAction;
CcmdMenu* cmdMenu;
CcmdPost* cmdPost;
CcmdClose* cmdClose;
CcmdOpen* cmdOpen;
CcmdEcho* cmdEcho;
CcmdZappo* cmdZappo;
CcmdIgnore* cmdIgnore;
CcmdNotice* cmdNotice;
CcmdPage* cmdPage;
CcmdUsers* cmdUsers;
CcmdMain* cmdMain;

