/////////////////////////////////////////////////////////////////////////////
//
//   TLCAH.CPP
//
//   Copyright (c) 1997 Galacticomm, Inc.         All Rights Reserved
//
//   Active HTML Teleconference interface
//
//                                               - Phil Henning 6/13/97
//
/////////////////////////////////////////////////////////////////////////////

#pragma option -w-par    // fixes warning in memory.h
#define _RWSTDLL
#include "gcomm.h"
#include "majorbbs.h"
#include <stdcomp.h>
#define RWSTD_NO_BOOL
#pragma option -w-aus
#include <deque>
#pragma option -w-aus.
#include "iterand.h"
using namespace std;
#include "galacth.h"
#include "tlcapi.hpp"
#include "ahtrans.hpp"
#include "tlcahusr.hpp"
#include <cstring.h>
#include "dnf.h"
#include "tvb.h"
#include "ahutil.h"
#include "gcspsrv.h"
#include <time.h>
#include "tlcahlit.h"

#define FILREV "$Revision: 125 $"

MARKSOURCE(tlcah);


#define PPFIX  "galacth/galtele/"

#define ENCRYPSEND  0x54697421L
#define ENCRYPRECV  0x67138173L
#define ALREADYON   "900 Already Online"
#define NEEDJAVA    "901 Need Java Client to Access"
#define NEEDTOLOGIN "902 Need to Login"
#define NEEDENCRYPT "903 Missing authentication value"
#define BADENCRYPT  "904 Bad authentication value"
#define MULTLOGIN   "905 Multiple login error"
#define MSGSENT     "910 Message Sent"
#define LOGOFF      "911 Logged Off"

#define ENCSIZ 30
#define MXDPKSIZ  16383

#define GETINPUT(X)      (ses->param(X,m_strInp,tinpsz))
#define STRCPY(X)        (strcpy(X,m_strInp))
#define STLCPY(X,Y)      (stlcpy(X,m_strInp,Y))
#define STRCAT(X)        (strcat(X,m_strInp))
#define STLCAT(X,Y)      (stlcat(X,m_strInp,Y))
#define INSTAB(X)        (strcat(X,"\t"))

enum
{
     ARCHIVETYPE,INITCHAN
};

//   DNF table for tele.htm (the applet-loading page)
//   used to specify JAR archives for Netscape 4, ZIP for Netscape 3
//
dnfStep mainSteps[] =
{
     dnfStep(DNFWATCH,ARCHIVETYPE,"ZIP"),
     dnfStep(DNFWATCH,INITCHAN,"INITCHANNEL"),
     dnfStep(DNFMAPEND)
};
dnfMap mainMap( PPFIX "tele2.htm", "Main", mainSteps);

CAHTransport transAH;
CHAR* dbbuffer;
INT maxtime;
INT iAHTrans;
VOID initagent(VOID);

class AutoNew {
public:
     AutoNew(size_t bytes);
     ~AutoNew();
     inline VOID* getRegion();
private:
     VOID* _mem;
};

AutoNew::AutoNew(size_t bytes)
{
     _mem=new CHAR[bytes];
     memset(_mem,0,bytes);
}

AutoNew::~AutoNew()
{
     delete [] _mem;
}

VOID*
AutoNew::getRegion()
{
     return(_mem);
}

VOID add2recent(CTlcUser* pUser);
VOID myusrson(VOID);
VOID (*oldusrson)(VOID);

extern "C" {

VOID check_logoffs(VOID)
{
     LONG curtime;
     static INT acb;
     static INT cnt;
     CHAR user[TLCUIDSIZ];

     setmbk(msgTlc);
     CTlcAHUser* pUser=(CTlcAHUser*)transAH.GetFirstUser(NULL);
     curtime=time(NULL);
     while (pUser != NULL) {
          GBOOL delusr=FALSE;
          CTlcChannel* pChannel=tlcAPI->chanGetByName(pUser->GetChannelName());

          stlcpy(user,pUser->GetName(),TLCUIDSIZ);
          if (cnt == 15) {
               LONG credconsumed=tlcAPI->m_iTlcSur;
               if (pChannel != NULL) {
                    credconsumed=pChannel->m_iCrConsumptionRate;
               }
               if (onsysn(pUser->GetName(),1)) {
                    credconsumed-=mmucrr;
               }
               // we charge 4 times a minute
               if (credconsumed > 0 && !gdedcrd(user,(credconsumed/4),0,0)) {
                    delusr=TRUE;
               }
          }
          if (curtime-pUser->GetTime() > maxtime || delusr) {
               // the user timed-out or ran out of credits
               CHAR chanName[CHAN_MAX_SIZE];
               CHAR userid[TLCUIDSIZ];

               stzcpy(chanName,tlcPrivateFromUser(pUser->GetName())
                         ,CHAN_MAX_SIZE);
               curChannel=pChannel;
               curUser=pUser;
               if (pUser->m_fFlags&USR_CHATTING) {
                    ExitChat(TRUE,pUser->GetName(),TRUE);
               }
               pUser->SaveRecord();
               transAH.RemoveUser(pUser);
               RemoveInvite(pUser);
               RemoveForget(pUser);
               add2recent(pUser);
               strcpy(userid,pUser->GetName());
               pChannel->RemoveUser(pUser,LEAVE_LOGOFF);
               if (!onsysn(userid,1)) {
                    tlcAPI->chanMoveAllUsers(chanName,dftchan
                                        ,CHAN_SWITCH_USER_LOGOFF
                                        ,SCMSG_USER_LOGOFF);
                    tlcAPI->chanRemoveByName(chanName);
               }
               tlcexit(userid);
          }
          if (cnt == 15 && (acb&1) && pUser->m_pfnacc != 0) {
               pUser->m_pfnacc--;
          }
          pUser=(CTlcAHUser*)transAH.GetUserGT(user,NULL);
     }
     if (cnt == 15) {
          cnt=0;
     }
     cnt+=3;
     acb+=3;
     rstmbk();
     rtkick(3,check_logoffs);
}

static VOID
pagetck(VOID)
{
     CTlcAHUser* pUser;
     struct pageInfo* pInfo;
     pUser=(CTlcAHUser*)(transAH.GetFirstUser(NULL));
     while (pUser != NULL) {
          pInfo=pUser->GetPageInfo();
          if (pInfo->pagedCtr > 0) {
               pInfo->pagedCtr--;
          }
          if (pInfo->pagedConsCtr > 0) {
               pInfo->pagedConsCtr-=1;
          }
          pUser=(CTlcAHUser*)(transAH.GetNextUser(NULL));
     }
     rtkick(PAGETCKINT,pagetck);
}


VOID
initactiveh(VOID)
{
     tlcAPI->DeclareObjSize(sizeof(CTlcAHUser),0);
     iAHTrans=tlcAPI->transRegister("Active HTML",&transAH);
     setmbk(msgTlc);
     maxtime=numopt(AHTIME,5,1200);
     rstmbk();
     oldusrson=hdlusrson;
     hdlusrson=myusrson;
     rtkick(1,check_logoffs);
     hook_startup(initagent);
     rtkick(PAGETCKINT,pagetck);
}
}


class tlcAgent : public acthAgent {
private:
     AutoNew*  _dbbuf;

public:
     tlcAgent() : acthAgent("Active HTML Teleconference","tele")
     {
          registerAgent(acthVersion);
          _dbbuf=new AutoNew(MXDPKSIZ);
     }
     acthSynthesis* newSynthesis(acthSession *ses);

     ~tlcAgent()
     {
          delete _dbbuf;
     }

     CHAR* getDbBuf()
     {
          return(static_cast<CHAR*>(_dbbuf->getRegion()));
     }
};

class tlcSynthesis : public acthSynthesis {
public:
     tlcSynthesis(acthSession *_ses) : acthSynthesis(_ses), dnf(NULL),
                                       m_flag(FALSE), m_pChannel(NULL),
                                       m_pUser(NULL), m_pszUserid(NULL),
                                       m_dbData(NULL), isbout(FALSE)
     {
          m_strInp       = new CHAR[tinpsz];
          m_encryp       = new CHAR[ENCSIZ];
          *m_encryp      = '\0';
     }

     ~tlcSynthesis()
     {
          if (dnf != NULL) {
               delete dnf;
               dnf=NULL;
          }
          if (m_dbData != NULL) {
               delete m_dbData;
               m_dbData=NULL;
          }
          delete m_strInp;
          delete m_encryp;
     }
     ACTHCODE proceed();

private:
     VOID ParseInput();
     VOID JoinDefault(const CHAR *requestedChannel);
     ACTHCODE ChkLogEncrypt();
     GBOOL RequestEntExit(SHORT iType, GBOOL change);
     VOID ClearEntExit(SHORT iType);
     VOID SendDbData();
     VOID redirectToLite(CHAR *chan);

private:
     dnfHandler* dnf;
     GBOOL m_flag;
     CHAR* m_strInp;
     CTlcChannel* m_pChannel;
     CTlcAHUser* m_pUser;
     CHAR* m_encryp;
     CHAR* m_dbData;
     const CHAR* m_pszUserid;
     GBOOL isbout;
     CHAR tmpname[GCMAXFNM];
     CHAR usrto[TLCUIDSIZ];
     FILE* fp;

};

tlcAgent* thetlcAgent;

VOID
initagent(VOID)
{
     thetlcAgent=new tlcAgent;
     dbbuffer=thetlcAgent->getDbBuf();
}

acthSynthesis*
teleNewSynthesis(
acthSession* ses)
{
     CHAR type[sizeof("html")+1];

     ses->param("type",type,sizeof(type));
     INT nargs=ses->urlargc();
     if (nargs > 0) {
          if (sameas(ses->urlargv(0),"file")) {
               return(new fileSyn(ses));
          }
          if (sameas(ses->urlargv(0),"list") &&  nargs > 1) {
               if (sameas(ses->urlargv(1),"action")) {
                    return(new actionSyn(ses));
               }
               if (sameas(ses->urlargv(1),"channel"))  {
                    return(new channelSyn(ses));
               }
               if (sameas(ses->urlargv(1),"user")) {
                    return(new userSyn(ses));
               }
          }
          if (sameas(ses->urlargv(0),"receive")) {
               return(new receiveSyn(ses));
          }
          if (sameas(ses->urlargv(0),"send")) {
               return(new sendSyn(ses));
          }
          if (sameas(ses->urlargv(0),"profile")) {
               return(new profileSyn(ses));
          }
     }
     if (sameas(type,"html") && (nargs == 0 || ses->urlargv(0) && strchr(ses->urlargv(0),'.') != 0)) {
          return(new initialSyn(ses));
     }
     return(new tlcSynthesis(ses));
}


acthSynthesis*
tlcAgent::newSynthesis(acthSession* ses)
{
     return(::teleNewSynthesis(ses));
}


ACTHCODE
tlcSynthesis::proceed()
{
     ACTHCODE retval;

     acthUserID *usr=ses->getUser();
     if (usr == NULL) {
          return(ACTHNOANON);
     }
     if (!tlcAPI->isinit()) {
          return(ACTHMORE);
     }
     setmbk(msgTlc);
     m_pszUserid = usr->userid();

     if (ses->urlargc() == 1) {
          if (sameas("logon",(ses->urlargv(0)))) {
               CHAR reqChanBuf[CHAN_MAX_SIZE];
               ses->param("iChan",reqChanBuf,CHAN_MAX_SIZE);
               CTlcUser* pUser;
               if ((pUser = tlcAPI->usrGetByName(m_pszUserid)) != NULL) {
                    bout << ALREADYON << endl;
                    retval=ACTHDONE;
               }
               else {
                    m_pUser=dynamic_cast<CTlcAHUser*>(pUser);
                    CTlcAHUser User;
                    LONG curtime;
                    ULONG unum;

                    m_pUser=dynamic_cast<CTlcAHUser*>(pUser);
                    User.SetName(m_pszUserid);
                    User.SetTransport(&transAH);
                    if ((unum=tlcAPI->FindIDByUser(m_pszUserid)) == 0L) {
                         unum=tlcAPI->CreateUniqueID(m_pszUserid);
                    }
                    User.SetTlcUnum(unum);
                    User.SetTlcBoardNum(0);
                    usaptr = GetAccPtr(m_pszUserid);
                    User.SetSex(usaptr->sex == 'F' ? 'F' : 'M');
                    User.SetAge(usaptr->age);
                    User.LoadRecord();
                    User.SetQueues(new MSGQUE, new MSGQUE);
                    m_pUser=dynamic_cast<CTlcAHUser*>(tlcAPI->usrAdd(&User));
                    User.Cleanup();
                    transAH.AddUser(m_pUser);
                    if (!onsysn(m_pszUserid,1)) {
                         tlcChannelCreatePrivate(m_pszUserid);
                    }
                    JoinDefault(reqChanBuf);
                    curtime=time(NULL);
                    m_pUser->SetTime(curtime);
                    bout << (curtime^ENCRYPSEND) << endl;
                    retval=ACTHDONE;
               }
          }
          else if (sameas("options",ses->urlargv(0))) {
               if ((retval=ChkLogEncrypt()) != ACTHDONE) {
                    bout << m_pszUserid << "\t" ;
                    bout << (m_pUser->CheckAccess(rawmsg(FGTKEY)) ? "Y" : "N");
                    bout << "\t";
                    bout << (m_pUser->CheckAccess(rawmsg(INVKEY)) ? "Y" : "N");
                    bout << "\t";
                    bout << (m_pUser->IsTypeOf(USR_MODERATOR) ? "Y" : "N");
                    bout << "\t";
                    bout << (m_pUser->CheckAccess(rawmsg(PALKEY)) ? "Y" : "N");
                    bout << "\t";
                    bout << (m_pUser->CheckAccess(rawmsg(IGNKEY)) ? "Y" : "N");
                    bout << "\t";
                    bout << (m_pUser->CheckAccess(rawmsg(CHTKEY)) ? "Y" : "N");
                    bout << "\t";
                    bout << "Y\tY\t";
                    bout << tinpsz;
                    bout << endl;
                    retval=ACTHDONE;
               }
          }
          else if (sameas("getprofile",ses->urlargv(0))) {
               if ((retval=ChkLogEncrypt()) != ACTHDONE) {
                    bout << "actent=" << m_pUser->GetEntrance(MSG_CURRENT);
                    bout << "\t";
                    bout << "actex="  << m_pUser->GetExit(MSG_CURRENT);
                    bout << "\t";
                    bout << "defchan=";
                    bout << (m_pUser->GetDefaultChan() ? "Private" : "Main");
                    bout << "\t";
                    bout << "chatreq=";
                    bout << spr("%hd", m_pUser->GetChatInterval()) << "\t";
                    bout << "topic=" << m_pUser->GetPrivateTopic() << "\t";
                    bout << "reqent=" << m_pUser->GetEntrance(MSG_REQUESTED);
                    bout << "\t";
                    bout << "reqex=" << m_pUser->GetExit(MSG_REQUESTED) << endl;
                    retval=ACTHDONE;
               }
          }
          else if (sameas("setprofile",ses->urlargv(0))) {
               if ((retval=ChkLogEncrypt()) != ACTHDONE) {
                    SHORT scr;
                    if (GETINPUT("chatreq")) {
                         scr=atoi(m_strInp);
                         if (m_pUser->SetChatInterval(scr) != scr) {
                              bout << "The Chat Interval You Entered is Invalid!";
                              bout << endl;
                              isbout=TRUE;
                              rstmbk();
                              return(ACTHDONE);
                         }
                    }
                    if (GETINPUT("defchan")) {
                         scr=atoi(m_strInp);
                         if (scr != CHANDFT_MAIN && scr != CHANDFT_PRIVATE) {
                              bout << "The Default Channel Selection is Invalid!";
                              bout << endl;
                              isbout=TRUE;
                              rstmbk();
                              return(ACTHDONE);
                         }
                         else {
                              m_pUser->SetDefaultChan(scr);
                         }
                    }
                    if (GETINPUT("topic")) {
                         m_pUser->SetPrivateTopic(m_strInp);
                    }
                    else {
                         m_pUser->SetPrivateTopic("");
                    }
                    if (GETINPUT("reqent")) {
                         if (!RequestEntExit(REQENT3,FALSE)) {
                              rstmbk();
                              return(ACTHDONE);
                         }
                         RequestEntExit(REQENT3,TRUE);
                    }
                    else {
                         ClearEntExit(REQENT3);
                    }
                    if (GETINPUT("reqex")) {
                         if (!RequestEntExit(REQEXT3,FALSE)) {
                              rstmbk();
                              return(ACTHDONE);
                         }
                         RequestEntExit(REQEXT3,TRUE);
                    }
                    else {
                         ClearEntExit(REQEXT3);
                    }
                    retval=ACTHDONE;
                    if (!isbout) {
                         bout << "/";
                    }
               }
          }
          else if (sameas("forget",ses->urlargv(0))) {
               if ((retval=ChkLogEncrypt()) != ACTHDONE) {
                    ASSERT(m_pUser != NULL);
                    if (GETINPUT("user")) {
                         CTlcUser* pOthUser;
                         pOthUser=tlcAPI->usrGetByName(m_strInp);
                         if (pOthUser != NULL) {
                              if (sameas(pOthUser->GetName(),m_pUser->GetName())
                               || (pOthUser->IsTypeOf(USR_MODERATOR)
                                   && !(m_pUser->IsTypeOf(USR_OPERATOR)))
                               || pOthUser->CheckAccess(rawmsg(NFGTKEY))
                               || !m_pUser->CheckAccess(rawmsg(FGTKEY))
                               || pOthUser->IsTypeOf(USR_OPERATOR)) {
                                   bout << "Sorry but you are unable to forget ";
                                   bout << pOthUser->GetName() << "." << endl;
                              }
                              else {
                                   m_pUser->ToggleForget(pOthUser);
                                   if (m_pUser->CheckForget(pOthUser)) {
                                        if (m_pUser->CheckInvite(pOthUser)) {
                                             CTlcChannel* pChannel;
                                             m_pUser->ToggleInvite(pOthUser);
                                             tlcAPI->chanCheckPrivate(m_pUser->GetName(),&pChannel);
                                             if (sameas(pOthUser->GetChannelName()
                                                ,pChannel->GetName())) {
                                                  CTlcChannel* pNewChan;
                                                  CTlcUser* pNewUser;

                                                  stzcpy((CHAR*)(tlcwrk)
                                                        ,m_pUser->GetName()
                                                        ,TLCUIDSIZ);
                                                  pOthUser->CmdResult(
                                                        CMD_UNINVITE
                                                       ,TRUE
                                                       ,CMD_UNINVITE_KICK);
                                                  if ((pNewChan=tlcAPI->chanGetByName(dftchan)) == NULL) {
                                                      pNewChan=tlcAPI->chanGetByName(mainchan);
                                                  }
                                                  pNewChan->AddUser(pOthUser);
                                                  pNewUser=tlcAPI->chanFindUser(pNewChan->GetName()
                                                                               ,pOthUser->GetName());

                                                  pChannel->RemoveUser(pOthUser
                                                                      ,LEAVE_PRIV_KICK);
                                                  pNewUser->CmdResult(CMD_JOIN
                                                                     ,TRUE,0);
                                             }
                                        }
                                   }
                                   bout << "/";
                              }
                         }
                         else {
                              bout << m_strInp;
                              bout << " is no longer on the system!";
                              bout << endl;
                         }
                    }
                    else {
                         int cnt;
                         struct flist* flist;
                         CTlcUser* pOthUser;
                         flist=m_pUser->GetForgetListPtr();
                         cnt=0;
                         while (cnt < n2fgt
                          && flist != NULL
                          && flist[cnt].user != 0) {
                              pOthUser=tlcAPI->usrGetByTlcID(flist[cnt].board
                                                            ,flist[cnt].user);
                              if (pOthUser != NULL) {
                                   bout << pOthUser->GetName() << "\t";
                              }
                              cnt++;
                         }
                         if (cnt != 0) {
                              bout << endl;
                         }
                         else {
                              bout << "/";
                         }
                    }
                    retval=ACTHDONE;
               }
          }
          else if (sameas("invite",ses->urlargv(0))) {
               if ((retval=ChkLogEncrypt()) != ACTHDONE) {
                    if (GETINPUT("user")) {
                         CTlcUser* pOthUser;
                         ASSERT(m_pUser != NULL);
                         pOthUser=tlcAPI->usrGetByName(m_strInp);
                         if (pOthUser != NULL) {
                              if (sameas(pOthUser->GetName(),curUser->GetName())) {
                                   bout << "You can't invite or uninvite yourself!";
                                   bout << endl;
                              }
                              else if (pOthUser->IsTypeOf(USR_OPERATOR)
                                && m_pUser->CheckInvite(pOthUser)) {
                                   bout << "You can't uninvite ";
                                   bout << pOthUser->GetName() << "." << endl;
                              }
                              else if (!(pOthUser->GetTransport()->m_fFlags&TRANS_IMPLPRIV)) {
                                  bout << "You can't invite a "
                                       << pOthUser->GetTransport()->GetName()
                                       << " user!";
                              }
                              else {
                                   m_pUser->ToggleInvite(pOthUser);
                                   if (m_pUser->CheckInvite(pOthUser)) {
                                        stzcpy(static_cast<CHAR*>(tlcwrk)
                                               ,m_pUser->GetName(),TLCUIDSIZ);
                                        pOthUser->CmdResult(CMD_INVITE,TRUE
                                                           ,CMD_INVITE_NOTIFY);
                                   }
                                   else {
                                        CTlcChannel* pChannel;
                                        if (tlcAPI->chanCheckPrivate(tlcPrivateFromUser(m_pUser->GetName())
                                                                    ,&pChannel)) {
                                             if (sameas(pOthUser->GetChannelName()
                                                       ,pChannel->GetName())) {
                                                  CTlcChannel* pNewChan;
                                                  CTlcUser* pNewUser;

                                                  stzcpy((CHAR*)tlcwrk
                                                        ,m_pUser->GetName()
                                                        ,TLCUIDSIZ);
                                                  pOthUser->CmdResult(CMD_UNINVITE
                                                                     ,TRUE
                                                                     ,CMD_UNINVITE_KICK);
                                                  if ((pNewChan=tlcAPI->chanGetByName(dftchan)) == NULL) {
                                                      pNewChan=tlcAPI->chanGetByName(mainchan);
                                                  }
                                                  pNewChan->AddUser(pOthUser);
                                                  pNewUser=tlcAPI->chanFindUser(pNewChan->GetName()
                                                                               ,pOthUser->GetName());

                                                  pChannel->RemoveUser(pOthUser
                                                                      ,LEAVE_PRIV_KICK);
                                                  pNewUser->CmdResult(CMD_JOIN
                                                                     ,TRUE,0);
                                             }
                                        }
                                   }
                                   bout << "/";
                              }
                         }
                         else {
                              bout << m_strInp;
                              bout << " is no longer on the system!";
                              bout << endl;
                         }
                    }
                    else {
                         int cnt;
                         struct flist* flist;
                         CTlcUser* pOthUser;
                         flist=m_pUser->GetInviteListPtr();
                         cnt=0;
                         while (cnt < n2inv
                          && flist != NULL
                          && flist[cnt].user != 0) {
                              pOthUser=tlcAPI->usrGetByTlcID(flist[cnt].board
                                                            ,flist[cnt].user);
                              if (pOthUser != NULL) {
                                   bout << pOthUser->GetName() << "\t";
                              }
                              cnt++;
                         }
                         if (cnt != 0) {
                              bout << endl;
                         }
                         else {
                              bout << "/";
                         }
                    }
                    retval=ACTHDONE;
               }
          }
          else if (sameas("squelch",ses->urlargv(0))) {
               if ((retval=ChkLogEncrypt()) != ACTHDONE) {
                    if (GETINPUT("user")) {
                         CTlcUser* pOthUser;
                         pOthUser=tlcAPI->usrGetByName(m_strInp);
                         if (pOthUser != NULL) {
                              if (sameas(pOthUser->GetName(),m_pUser->GetName())
                               || (pOthUser->IsTypeOf(USR_MODERATOR)
                                   && !(m_pUser->IsTypeOf(USR_OPERATOR)))
                               || !(m_pUser->IsTypeOf(USR_MODERATOR))
                               || pOthUser->IsTypeOf(USR_OPERATOR)) {
                                   bout << "Sorry but you are unable to squelch ";
                                   bout << pOthUser->GetName() << "." << endl;
                              }
                              else if (pOthUser->m_fFlags&USR_SQUELCH) {
                                   pOthUser->m_fFlags&=~USR_SQUELCH;
                                   bout << "/";
                              }
                              else {
                                   pOthUser->m_fFlags|=USR_SQUELCH;
                                   bout << "/";
                              }
                         }
                         else {
                              bout << m_strInp << " is no longer on the system!";
                              bout << endl;
                         }
                    }
                    else {
                         int cnt=0;
                         CTlcUser* pOthUser;
                         pOthUser=tlcAPI->usrGetFirst();
                         while (pOthUser != NULL) {
                              if (pOthUser->m_fFlags&USR_SQUELCH) {
                                   bout << pOthUser->GetName() << "\t";
                                   bout << pOthUser->GetChannelName() << "\t";
                                   cnt++;
                              }
                              pOthUser=tlcAPI->usrGetNext();
                         }
                         if (cnt != 0) {
                              bout << endl;
                         }
                         else {
                              bout << "/";
                         }
                    }
                    retval=ACTHDONE;
               }
          }
          else if (sameas("ignore",ses->urlargv(0))) {
               if ((retval=ChkLogEncrypt()) != ACTHDONE) {
                    if (GETINPUT("user")) {
                         CTlcUser* pOthUser;
                         pOthUser=tlcAPI->usrGetByName(m_strInp);
                         if (pOthUser != NULL) {
                              if (sameas(pOthUser->GetName(),m_pUser->GetName())
                               || (pOthUser->IsTypeOf(USR_MODERATOR)
                               && !(m_pUser->IsTypeOf(USR_OPERATOR)))) {
                                   bout << "Sorry but you are unable to ignore ";
                                   bout << pOthUser->GetName() << "." << endl;
                              }
                              else {
                                   m_pUser->ToggleIgnore(pOthUser);
                                   bout << "/";
                              }
                         }
                         else {
                              bout << m_strInp << " is no longer on the system!";
                              bout << m_strInp << endl;
                         }
                    }
                    else {
                         int cnt;
                         struct flist* flist;
                         CTlcUser* pOthUser;
                         flist=m_pUser->GetIgnoreListPtr();
                         cnt=0;
                         while (cnt < n2ign
                          && flist != NULL
                          && flist[cnt].user != 0) {
                              pOthUser=tlcAPI->usrGetByTlcID(flist[cnt].board
                                                            ,flist[cnt].user);
                              if (pOthUser != NULL) {
                                   bout << pOthUser->GetName() << "\t";
                              }
                              cnt++;
                         }
                         if (cnt != 0) {
                              bout << endl;
                         }
                         else {
                              bout << "/";
                         }
                    }
                    retval=ACTHDONE;
               }
          }
          else if (sameas("sendmsg",ses->urlargv(0))) {
               if ((retval=ChkLogEncrypt()) != ACTHDONE) {
                    if (GETINPUT("inp")) {
                         ParseInput();
                         bout << MSGSENT << endl;
                         retval=ACTHDONE;
                    }
                    else {
                         retval=ACTHNOTFND;
                    }
               }
          }
          else if (sameas("chatmsg",ses->urlargv(0))) {
               if ((retval=ChkLogEncrypt()) != ACTHDONE) {
                    if (m_pUser->m_fFlags&USR_CHATTING) {
                         if (GETINPUT("inp")) {
                              CTlcUser* pOthUser=tlcAPI->usrGetByName(m_pUser->GetChatUser());
                              if (pOthUser != NULL) {
                                   pOthUser->OnRecvText(m_pUser->GetName()
                                                       ,NULL,m_strInp
                                                       ,RECV_TYPE_CHATMSG);
                              }
                         }
                    }
                    bout << "/";
                    retval=ACTHDONE;
               }
          }
          else if (sameas("getmsg",ses->urlargv(0))) {
               if ((retval=ChkLogEncrypt()) != ACTHDONE) {
                    if (GETINPUT("flag")
                     && sameas(m_strInp,"donothing")) {
                         // to keep client alive during scrollback
                         bout << "/";
                    }
                    else if (m_pUser->GetMsg() != NULL) {
                         while (m_pUser->GetMsg() != NULL) {
                              bout << m_pUser->GetMsg() << endl;
                              m_pUser->PopMsg();
                         }
                    }
                    else {
                         bout << "/";
                    }
                    retval=ACTHDONE;
               }
          }
          else if (sameas("chaninfo",ses->urlargv(0))) {
               CTlcChannel* pChannel;
               CTlcUser* pUser;
               if ((retval=ChkLogEncrypt()) != ACTHDONE) {
                    pChannel=tlcAPI->chanGetFirst();
                    while (pChannel != NULL) {
                         VOID* chanSavePos=tlcAPI->chanGetPos();
                         CTlcPrivateChannel* pPrivate;
                         if (pChannel->GetType()&CHAN_TYPE_PRIVATE) {
                              pPrivate=dynamic_cast<CTlcPrivateChannel*>(pChannel);
                              if (!pPrivate->CheckInvite(m_pUser)
                               && !sameas(m_pUser->GetName(),pPrivate->GetOwner())) {
                                   tlcAPI->chanSetPos(chanSavePos);
                                   pChannel=tlcAPI->chanGetNext();
                                   continue;
                              }
                         }
                         if (pChannel->m_flags&CHAN_FLAG_NOLIST) {
                              tlcAPI->chanSetPos(chanSavePos);
                              pChannel=tlcAPI->chanGetNext();
                              continue;
                         }
                         if (pChannel->CanAccess(m_pUser,CHAN_AXS_SEE)) {
                              if (pChannel->GetType()&CHAN_TYPE_PRIVATE) {
                                   bout << pPrivate->GetOwner();
                              }
                              else {
                                   bout << pChannel->GetName();
                              }
                              bout << "\t";
                              bout << pChannel->GetType() << endl;
                              pUser=pChannel->GetFirstUser();
                              if (pUser != NULL) {
                                   bout << pUser->GetName();
                                   pUser=pChannel->GetNextUser();
                                   while (pUser != NULL) {
                                        bout << "\t" << pUser->GetName();
                                        pUser=pChannel->GetNextUser();
                                   }
                              }
                              bout << endl;
                         }
                         tlcAPI->chanSetPos(chanSavePos);
                         pChannel=tlcAPI->chanGetNext();
                    }
                    retval=ACTHDONE;
               }
          }
          else if (sameas("allusers",ses->urlargv(0))) {
               CTlcUser* pUser;
               if ((retval=ChkLogEncrypt()) != ACTHDONE) {
                    pUser=tlcAPI->usrGetFirst();
                    if (pUser != NULL) {
                         bout << pUser->GetName() << "\t";
                         bout << pUser->GetChannelName();
                         pUser=tlcAPI->usrGetNext();
                         while (pUser != NULL) {
                              bout << endl << pUser->GetName();
                              bout << "\t" << pUser->GetChannelName();
                              pUser=tlcAPI->usrGetNext();
                         }
                    }
                    bout << endl;
                    retval=ACTHDONE;
               }
          }
          else if (sameas("join",ses->urlargv(0))) {
               CTlcChannel* pNewChan;
               CTlcPrivateChannel* pPrivate;
               if ((retval=ChkLogEncrypt()) != ACTHDONE) {
                    if (GETINPUT("chan")) {
                         GBOOL joinpriv=FALSE;
                         switch (tlcAPI->chanCheckPrivate(m_strInp,&pNewChan)) {
                         case CHAN_PRIVATE_FOUND:
                              ASSERT(pNewChan != NULL);
                              pPrivate=dynamic_cast<CTlcPrivateChannel*>(pNewChan);
                              // check invite status
                              if (sameas(m_pUser->GetName(),pPrivate->GetOwner())
                                   || m_pUser->IsTypeOf(USR_OPERATOR)
                                   || m_pUser->CheckInvite(m_pUser)) {
                                   joinpriv=TRUE;
                              }
                              else {
                                   bout << "You aren't invited to that channel!" << endl;
                              }
                              break;
                         }
                         if (!joinpriv) {
                              if ((pNewChan=tlcAPI->chanCheckPub(m_strInp)) == NULL) {
                                   bout << "No such channel exists!" << endl;
                              }
                              else if (sameas(pNewChan->GetName(),m_pChannel->GetName())) {
                                   bout << "You are already in that channel!";
                                   bout << endl;
                              }
                              else if (m_pChannel != NULL
                               && m_pChannel->GetType()&CHAN_TYPE_FORUM
                               && !tlcAPI->m_bForSameChg && !tlcAPI->m_bSwitFor) {
                                   prfmsg(CANTEX2);
                                   bout << stp4cs(prfbuf) << endl;
                              }
                              else if (pNewChan->GetType()&CHAN_TYPE_FORUM
                               && !tlcAPI->m_bForSameChg && !tlcAPI->m_bSwitFor) {
                                   prfmsg(CANTJN2);
                                   bout << stp4cs(prfbuf) << endl;
                              }
                              else if (!pNewChan->CanAccess(m_pUser,CHAN_AXS_JOIN)) {
                                   bout << "You don't have access to join that channel!";
                                   bout << endl;
                              }
                              else {
                                   joinpriv=TRUE;
                              }
                         }
                         if (joinpriv) {
                              CTlcAHUser* pNewUser;
                              pNewChan->AddUser(m_pUser);
                              pNewUser=dynamic_cast<CTlcAHUser*>(tlcAPI->chanFindUser(pNewChan->GetName()
                                                                                     ,m_pUser->GetName()));
                              m_pChannel->RemoveUser(m_pUser);
                              m_pUser=pNewUser;
                              m_pUser->CmdResult(CMD_JOIN,TRUE,0);
                              bout << "/";
                         }
                    }
                    else {
                         bout << "/";
                    }
                    retval=ACTHDONE;
               }
          }
          else if (sameas("chanusers",ses->urlargv(0))) {
               CTlcUser* pUser;
               if ((retval=ChkLogEncrypt()) != ACTHDONE) {
                    GBOOL one=FALSE;
                    pUser=m_pChannel->GetFirstUser();
                    if (pUser != NULL) {
                         pUser=m_pChannel->GetNextUser();
                         while (pUser != NULL) {
                              if ((pUser->m_fFlags&USR_INCHAN)
                               && !(pUser->m_fFlags&USR_INVISB)) {
                                   bout << "\t" << pUser->GetName();
                                   one=TRUE;
                              }
                              pUser=m_pChannel->GetNextUser();
                         }
                    }
                    if (!one) {
                         bout << "/";
                    }
                    bout << endl;
                    retval=ACTHDONE;
               }
          }
          else if (sameas("ticker",ses->urlargv(0))) {
               if ((retval=ChkLogEncrypt()) != ACTHDONE) {
                    bout << pszTickerNoAnsi << "\t" << iTickerTime << endl;
                    retval=ACTHDONE;
               }
          }
          else if (sameas("actlist",ses->urlargv(0))) {
               if ((retval=ChkLogEncrypt()) != ACTHDONE) {
                    GBOOL one=FALSE;
                    if (curChannel != NULL) {
                         LPCHANINFO chanInfo;
                         chanInfo=curChannel->GetConfig();
                         CTlcAList* pList;
                         pList=tlcAPI->actGetByName(chanInfo->m_actList1);
                         if (pList != NULL) {
                              struct actlst* listcfg;
                              listcfg=pList->GetConfigPtr();
                              if (curUser->CheckAccess(listcfg->usekey)) {
                                   bout << chanInfo->m_actList1 << "\t";
                                   one=TRUE;
                              }
                         }
                         pList=tlcAPI->actGetByName(chanInfo->m_actList2);
                         if (pList != NULL) {
                              struct actlst* listcfg;
                              listcfg=pList->GetConfigPtr();
                              if (curUser->CheckAccess(listcfg->usekey)) {
                                   bout << chanInfo->m_actList2;
                                   one=TRUE;
                              }
                         }
                         if (!one) {
                              bout << "/";
                         }
                         bout << endl;
                    }
                    retval=ACTHDONE;
               }
          }
          else if (sameas("actwords",ses->urlargv(0))) {
               if ((retval=ChkLogEncrypt()) != ACTHDONE) {
                    GBOOL one=FALSE;
                    GETINPUT("list");
                    CTlcAList* pList;
                    if ((pList=tlcAPI->actGetByName(m_strInp)) != NULL) {
                         const CHAR* word=pList->wordGetFirst();
                         while (word != NULL) {
                              struct action* action;
                              action=pList->actionGetCurrentPtr();
                              if (curUser->CheckAccess(action->actkey)) {
                                   bout << action->name << "\t";
                                   bout << (action->isyell ? "Y" : "N") << "\t";
                                   bout << (isempty(action->complx) ? "N" : "Y");
                                   bout << "\t";
                                   one=TRUE;
                              }
                              word=pList->wordGetNext();
                         }
                         if (!one) {
                              bout << "/";
                         }
                         bout << endl;
                    }
                    retval=ACTHDONE;
               }
          }
          else if (sameas("getpals",ses->urlargv(0))) {
               if ((retval=ChkLogEncrypt()) != ACTHDONE) {
                    GBOOL one=FALSE;
                    PALDSK pdsk;
                    memset(&pdsk,0,sizeof(PALDSK));
                    stzcpy(pdsk.pszUserid,curUser->GetName(),UIDSIZ);
                    dfaSetBlk(dfaPal);
                    if (dfaAcqGT(&pdsk,&pdsk,0)
                     && sameas(pdsk.pszUserid,curUser->GetName())) {
                         do {
                              bout << pdsk.pszPal << "\t";
                              one=TRUE;
                         } while (dfaAcqNX(&pdsk));
                    }
                    if (!one) {
                         bout << "/";
                    }
                    bout << endl;
                    retval=ACTHDONE;
               }
          }
          else if (sameas("pal",ses->urlargv(0))) {
               if ((retval=ChkLogEncrypt()) != ACTHDONE) {
                    if (GETINPUT("user")) {
                         SHORT cnt=0;
                         PALDSK pdsk;
                         if (sameas(m_strInp,curUser->GetName())) {
                              bout << "You can't make yourself a Pal!" << endl;
                         }
                         else {
                              GBOOL one=FALSE;
                              memset(&pdsk,0,sizeof(PALDSK));
                              stzcpy(pdsk.pszUserid,curUser->GetName(),UIDSIZ);
                              stzcpy(pdsk.pszPal,m_strInp,TLCUIDSIZ);
                              dfaSetBlk(dfaPal);

                              if (dfaAcqEQ(NULL,&pdsk,0)) {  // Remove this guy
                                   dfaDelete();
                                   if (onsysn(curUser->GetName(),1)) {
                                        palWasUpdated(othusn);
                                   }
                              }
                              else {
                                   memset(pdsk.pszPal,0,TLCUIDSIZ);
                                   if (dfaAcqGT(&pdsk,&pdsk,0)) {
                                        do {
                                             if (!sameas(pdsk.pszUserid
                                                        ,m_pUser->GetName())) {
                                                  break;
                                             }
                                             cnt++;
                                        } while (dfaAcqNX(&pdsk));
                                   }
                                   if (cnt < pmax) {
                                        stzcpy(pdsk.pszUserid
                                              ,curUser->GetName()
                                              ,UIDSIZ);
                                        stzcpy(pdsk.pszPal,m_strInp,TLCUIDSIZ);
                                        if (!dfaQueryEQ(&pdsk,0)) {
                                             dfaInsert(&pdsk);
                                             if (onsysn(curUser->GetName(),1)) {
                                                  palWasUpdated(othusn);
                                             }
                                        }
                                   }
                                   else {
                                        bout << "You have too many pals, you need to remove";
                                        bout << " at least one before you can add another.";
                                        one=TRUE;
                                   }
                              }
                              if (!one) {
                                   bout << "/";
                              }
                              bout << endl;
                              dfaRstBlk();
                         }
                    }
                    retval=ACTHDONE;
               }
          }
          else if (sameas("banrlst",ses->urlargv(0))) {
               if ((retval=ChkLogEncrypt()) != ACTHDONE) {
                    GBOOL one=FALSE;
                    m_pUser->SetTime(time(NULL));
                    struct banrfil* bf;
                    bf=banrfiles;
                    if (bf != NULL) {
                         bout << banrval << "\t";
                         one=TRUE;
                    }
                    while (bf != NULL) {
                         bout << bf->name << "\t";
                         bf=bf->next;
                    }
                    if (!one) {
                         bout << "/";
                    }
                    bout << endl;
                    retval=ACTHDONE;
               }
          }
          else if (sameas("curtopic",ses->urlargv(0))) {
               if ((retval=ChkLogEncrypt()) != ACTHDONE) {
                    const CHAR* topic = curChannel->GetTopic();
                    if (topic != NULL && *topic != '\0') {
                         bout << topic;
                    }
                    else {
                         bout << "<none>";
                    }
                    retval=ACTHDONE;
               }
          }
          else if (sameas("chantopic",ses->urlargv(0))) {
               if ((retval=ChkLogEncrypt()) != ACTHDONE) {
                    GBOOL one=FALSE;
                    if (GETINPUT("name")) {
                         CTlcChannel* pChannel;
                         pChannel=tlcAPI->chanGetByName(m_strInp);
                         if (pChannel != NULL) {
                              const CHAR* strTopic=pChannel->GetTopic();
                              if (*strTopic == '\0') {
                                   bout << "<none>";
                              }
                              else {
                                   bout << strTopic;
                              }
                              one=TRUE;
                         }
                    }
                    if (!one) {
                         bout << "/";
                    }
                    bout << endl;
               }
               retval=ACTHDONE;
          }
          else if (sameas("dbopen",ses->urlargv(0))) {
               if ((retval=ChkLogEncrypt()) != ACTHDONE) {
                    curChannel->ToggleDb(curUser,TRUE);
                    bout << "/";
                    retval=ACTHDONE;
               }
          }
          else if (sameas("dbclose",ses->urlargv(0))) {
               if ((retval=ChkLogEncrypt()) != ACTHDONE) {
                    curChannel->ToggleDb(curUser,FALSE);
                    m_pUser->ClearDb();
                    bout << "/";
                    retval=ACTHDONE;
               }
          }
          else if (sameas("getboard",ses->urlargv(0))) {
               if ((retval=ChkLogEncrypt()) != ACTHDONE) {
                    if (m_pUser->GetDbData() != NULL) {
                         while (m_pUser->GetDbData() != NULL) {
                              bout << m_pUser->GetDbData() << endl;
                              m_pUser->PopDbData();
                         }
                    }
                    else {
                         bout << "/";
                    }
                    retval=ACTHDONE;
               }
          }
          else if (sameas("sendboard",ses->urlargv(0))) {
               if ((retval=ChkLogEncrypt()) != ACTHDONE) {
                    SendDbData();
                    bout << "/";
                    retval=ACTHDONE;
               }
          }
          else if (sameas("stopchat",ses->urlargv(0))) {
               if ((retval=ChkLogEncrypt()) != ACTHDONE) {
                    if (m_pUser->m_fFlags&USR_CHATTING) {
                         ExitChat(FALSE,m_pUser->GetName(),TRUE);
                    }
                    bout << "/";
                    retval=ACTHDONE;
               }
          }
          else if (sameas("logoff",ses->urlargv(0))) {
               if ((retval=ChkLogEncrypt()) != ACTHDONE) {
                    CHAR chanName[CHAN_MAX_SIZE];

                    stzcpy(chanName,tlcPrivateFromUser(m_pUser->GetName())
                          ,CHAN_MAX_SIZE);
                    if (m_pUser->m_fFlags&USR_CHATTING) {
                         ExitChat(FALSE,m_pUser->GetName(),TRUE);
                    }
                    m_pUser->SaveRecord();
                    transAH.RemoveUser(m_pUser);
                    RemoveInvite(m_pUser);
                    RemoveForget(m_pUser);
                    add2recent(m_pUser);

                    m_pChannel->RemoveUser(m_pUser,LEAVE_LOGOFF);
                    if (!onsysn(m_pszUserid,1)) {
                         tlcAPI->chanMoveAllUsers(chanName,dftchan
                                                 ,CHAN_SWITCH_USER_LOGOFF
                                                 ,SCMSG_USER_LOGOFF);
                         tlcAPI->chanRemoveByName(chanName);
                    }
                    tlcexit(m_pszUserid);
                    bout << LOGOFF << endl;
                    retval=ACTHDONE;
               }
          }
          else {
               ostrstream ost;
               ost << PPFIX << ses->urlsfx() << ends;
               ses->sndfile(ost.str());
               ost.rdbuf()->freeze(0);
               retval=ACTHDONE;
          }
     }
     else if (ses->urlargc() == 0) {
          retval=ACTHMORE;
          CHAR chanbuf[CHAN_MAX_SIZE];
          ses->param("channel",chanbuf,CHAN_MAX_SIZE);
          GETINPUT("type");

          CTlcAHUser User;
          CTlcUser* pUser;
          if ((pUser = tlcAPI->usrGetByName(m_pszUserid)) != NULL) {
               bout << ALREADYON << endl;
               rstmbk();
               return(ACTHDONE);
          }
          else {
               User.SetName(m_pszUserid);
               User.LoadRecord();
               if (m_strInp[0] != '\0') {
                    if (sameas("html",m_strInp) || sameas("html set",m_strInp)) {
                         if (sameas(m_strInp,"html set")) {
                              User.m_fFlags&=~USR_WEBTELJAVA;
                              User.m_fFlags|=USR_WEBTELHTML;
                              User.SaveRecord();
                         }
                         redirectToLite(chanbuf);
                         rstmbk();
                         return(ACTHDONE);
                    }
                    else if (sameas("java set",m_strInp))  {
                         User.m_fFlags|=USR_WEBTELJAVA;
                         User.m_fFlags&=~USR_WEBTELHTML;
                         User.SaveRecord();
                    }
               }
               else if (User.m_fFlags&USR_WEBTELJAVA) {
                    ;
               }
               else if (User.m_fFlags&USR_WEBTELHTML) {
                    redirectToLite(chanbuf);
                    rstmbk();
                    return(ACTHDONE);
               }
               else {
                    INT gblpref = tokopt(DFTWBTEL,"HTML","JAVA",NULL);
                    if(gblpref == 1) {
                         redirectToLite(chanbuf);
                         rstmbk();
                         return(ACTHDONE);
                    }
               }
          }
          if (!usr->hasKey(getmsg(JTLCKEY))) {
               return(ACTHFORBID);
          }
          if (dnf == NULL) {
               dnf = new dnfHandler(mainMap,bout);
          }
          switch( dnf->process() )
          {
               case ARCHIVETYPE:
                    {
                         CHAR      agentStr[ 1024 ];
                         GBOOL     useJar = FALSE;

                         if (ses->header("User-Agent",agentStr,sizeof(agentStr))) {
                              BrowserType type = getClientType( agentStr );
                              INT ver = getClientVer( agentStr );
                              if ((type == BROWSER_NETSCAPE) && (ver >= 4)) {
                                   useJar = TRUE;
                              }
                         }
                         if (useJar) {
                              bout << "jar";
                         }
                         else {
                              bout << "zip";
                         }
                    }
                    break;
               case INITCHAN:
                    {
                         if (chanbuf[0] != '\0') {
                              bout << chanbuf;
                         }
                    }
                    break;
               case DNFEND:
                    retval = ACTHDONE;
                    break;
          }
     }
     else {
          retval=ACTHNOTFND;
     }
     rstmbk();
     tlcAPI->OutputFinished();
     return(retval);
}


VOID
tlcSynthesis::ParseInput()
{
     if (!m_pChannel->CommandParse(m_strInp,m_pUser->GetName())) {
          if (!tlcAPI->Parse(m_strInp,m_pUser->GetName(),m_pChannel)) {
               if (!m_pChannel->ActionParse(m_strInp,m_pUser->GetName())) {
                    if (m_pUser->m_fFlags&USR_SQUELCH) {
                         m_pUser->CmdResult(CMD_SPEAK,FALSE,CMD_SPEAK_SQUEL);
                    }
                    else if (!m_pUser->IsTypeOf(USR_NORMAL)
                     && m_pUser->m_iTimesSpoken >= tlcAPI->m_npaymx) {
                         m_pUser->CmdResult(CMD_SPEAK,FALSE,CMD_SPEAK_LIMITED);
                    }
                    else {
                         strcpy(input,m_strInp);
                         CHAR* pfch=strdup(input);
                         (*setpfn)(stpans(pfch));
                         free(pfch);
                         parsin();
                         SHORT spd=m_pUser->IsTalkingTooFast();
                         if (spd != USR_SPEED_OK) {
                              clingo=0;
                              clrprf();
                              prfmsg(TOOFAST);
                              strcat(prfbuf,"\t");
                              strcat(prfbuf,SYSUID);
                              strcat(prfbuf,"\tN");
                              m_pUser->AddMsg(prfbuf);
                              clrprf();
                         }
                         else if (!chk4pfn()) {
                              m_pChannel->PublicSend(m_pUser->GetName(),NULL
                                                    ,m_strInp,RECV_TYPE_PUBLIC
                                                    ,0);
                              m_pUser->CmdResult(CMD_SPEAK,TRUE,0);
                         }
                         else {
                              clingo=0;
                              clrprf();
                              prfmsg(PFNWRD2);
                              strcat(prfbuf,"\t");
                              strcat(prfbuf,SYSUID);
                              strcat(prfbuf,"\tN");
                              m_pUser->AddMsg(prfbuf);
                              clrprf();
                         }
                    }
               }
          }
     }
}

VOID
tlcSynthesis::JoinDefault(
const CHAR *requestedChannel)
{
     if (requestedChannel != NULL
      && (m_pChannel=tlcAPI->chanGetByName(requestedChannel)) != NULL) {
          ;
     }
     else if (m_pUser->GetDefaultChan() == CHANDFT_MAIN) {
          if ((m_pChannel=tlcAPI->chanGetByName(dftchan)) == NULL) {
              m_pChannel=tlcAPI->chanGetByName(mainchan);
          }
          if (!m_pChannel->CanAccess(m_pUser,CHAN_AXS_JOIN)) {
              m_pChannel=tlcAPI->chanGetByName(tlcPrivateFromUser(m_pUser->GetName()));
          }
     }
     else {
          m_pChannel=tlcAPI->chanGetByName(tlcPrivateFromUser(m_pUser->GetName()));
     }
     ASSERT(m_pChannel != NULL);
     tlcenter(m_pUser->GetName());
     m_pUser->m_fFlags|=USR_INCHAN;
     if (m_pChannel->AddUser(m_pUser,TRUE)) {
          tlcAPI->usrDelete(m_pUser);  // delete the user with no channel info
          m_pUser=dynamic_cast<CTlcAHUser*>(tlcAPI->chanFindUser(m_pChannel->GetName()
                                                                ,m_pszUserid));
     }
}

ACTHCODE
tlcSynthesis::ChkLogEncrypt()
{
     ACTHCODE retval;
     CTlcUser* pUser=tlcAPI->usrGetByName(m_pszUserid);

     if (pUser == NULL) {
          bout << NEEDTOLOGIN << endl;
          retval=ACTHDONE;
     }
     else {
          curUser=pUser;

          if  (pUser->GetType() != USR_TYPE_AHTML) {
               bout << MULTLOGIN << endl;
               retval=ACTHDONE;
          }
          else {
               ses->param("enc",m_encryp,ENCSIZ);
               curUser=m_pUser=dynamic_cast<CTlcAHUser*>(pUser);
               curChannel=m_pChannel=tlcAPI->chanGetByName(m_pUser->GetChannelName());
               if (*m_encryp == '\0') {
                    bout << NEEDENCRYPT << endl;
                    retval=ACTHDONE;
               }
               else {
                    LONG recv=atol(m_encryp);
                    LONG init=m_pUser->GetInitialTime();

                    if ((recv^ENCRYPRECV) != init) {
                         bout << BADENCRYPT << endl;
                         retval=ACTHDONE;
                    }
                    else {
                         m_pUser->SetTime(time(NULL));
                         retval=ACTHMORE;
                    }
               }
          }
     }
     return(retval);
}

GBOOL
tlcSynthesis::RequestEntExit(
SHORT iType,
GBOOL change)
{
     SHORT fMsg;

     acthUserID *usr=ses->getUser();
     if (!m_pUser->CheckAccess(rawmsg(REQKEY))) {
          clingo=0;
          clrprf();
          prfmsg(REQACC);
          strcat(prfbuf,"\t");
          strcat(prfbuf,SYSUID);
          strcat(prfbuf,"\tN");
          m_pUser->AddMsg(prfbuf);
          clrprf();
          bout << "/" << endl;
          isbout=TRUE;
          return(FALSE);
     }
     if (m_pUser->CheckAccess(rawmsg(AUTKEY))) {
          if (iType == REQENT3 && sameas(m_strInp
                                        ,m_pUser->GetEntrance(MSG_CURRENT))) {
               return(TRUE);
          }
          if (iType == REQEXT3 && sameas(m_strInp
                                        ,m_pUser->GetExit(MSG_CURRENT))) {
               return(TRUE);
          }
          if (tlcAPI->m_bEMsgChg) {
               if (!usr->afford(static_cast<LONG>(tlcAPI->m_iEMsgChg))) {
                    bout << "You can't afford to change your ";
                    bout << (iType == REQENT3 ? "Entrance " : "Exit ");
                    bout << "Message!" << endl;
                    isbout=TRUE;
                    return(FALSE);
               }
               else {
                    if (tlcAPI->m_bLogEMsg && change) {
                         logcrd(m_pUser->GetName(),tlcAPI->m_iEMsgChg);
                    }
                    fMsg=MSG_CURRENT;
               }
          }
          else {
               fMsg=MSG_CURRENT;
          }
     }
     if (!change) {
          return(TRUE);
     }
     if (iType == REQENT3) {
          if (sameas(m_strInp,m_pUser->GetEntrance(MSG_CURRENT))) {
               return(TRUE);
          }
          m_pUser->SetEntrance(m_strInp,fMsg);
     }
     else {
          if (sameas(m_strInp,m_pUser->GetExit(MSG_CURRENT))) {
               return(TRUE);
          }
          m_pUser->SetExit(m_strInp,fMsg);
     }
     if (fMsg == MSG_CURRENT) {
          if (iType == REQENT3) {
               m_pUser->SetEntrance("",MSG_REQUESTED);
          }
          else {
               m_pUser->SetExit("",MSG_REQUESTED);
          }
          if (tlcAPI->m_bEMsgChg) {
               if (m_flag == FALSE) {
                    usr->charge(static_cast<LONG>(tlcAPI->m_iEMsgChg));
                    prfmsg(YOUUPD3,tlcAPI->m_iEMsgChg);
                    bout << stpans(prfbuf) << endl;
                    isbout=TRUE;
                    m_flag=TRUE;
                    clrprf();
               }
          }
     }
     else {
          if (iType == REQENT3
           && sameas(m_strInp,m_pUser->GetEntrance(MSG_REQUESTED))) {
                    return(TRUE);
          }
          if (iType == REQEXT3
           && sameas(m_strInp,m_pUser->GetExit(MSG_REQUESTED))) {
                    return(TRUE);
          }
          prfmsg(OKSET2);
          if (!m_pUser->ChangedMsg()) {
               chgnot(m_pUser->GetName(),EEMNOT);
               m_pUser->SetChangedMsg(TRUE);
          }
          bout << stpans(prfbuf) << endl;
          isbout=TRUE;
          clrprf();
     }
     return(TRUE);
}

VOID
tlcSynthesis::ClearEntExit(
SHORT iType)
{
     if (iType == REQENT3) {
          m_pUser->SetEntrance("",MSG_REQUESTED);
          m_pUser->SetEntrance("",MSG_CURRENT);
     }
     else {
          m_pUser->SetExit("",MSG_REQUESTED);
          m_pUser->SetExit("",MSG_CURRENT);
     }
}

VOID
tlcSynthesis::redirectToLite(
CHAR *chan)
{
     string redirBuf("/telelite?type=html");
     if (*chan != '\0') {
          redirBuf+="?channel=";
          redirBuf+=chan;
     }
     ses->redirect(redirBuf.c_str());
}

VOID
tlcSynthesis::SendDbData()
{
     if (ses->param("data",dbbuffer,MXDPKSIZ)) {
          CHAR* lastnew;
          if ((lastnew=strrchr(dbbuffer,'\n')) != 0) {
               lastnew++;
               *lastnew='\0';
               m_pChannel->SendTabbedDbData(dbbuffer);
          }
     }
}

VOID
add2recent(
CTlcUser* pUser)
{
     if (sysrec || !(pUser->IsTypeOf(USR_OPERATOR))) {
          movmem(recents,&recents[1],sizeof(struct recalls)*(nreccl-1));
          recents[0].logon=(static_cast<CTlcAHUser*>(pUser)->GetPackedTime() == 0
                  ? now() : static_cast<CTlcAHUser*>(pUser)->GetPackedTime());
          recents[0].logoff=now();
          stlcpy(recents[0].userid,pUser->GetName(),UIDSIZ);
     }
}

VOID
myusrson(VOID)
{
     CTlcUser* pUser;

     oldusrson();
     setmbk(msgTlc);
     if ((pUser=transAH.GetFirstUser(NULL)) != NULL) {
          do {
               if (!onsysn(pUser->GetName(),1)) {
                    prfmsg(ULSLINA2,"AH",pUser->GetName(),tlcmod.descrp);
               }
          }
          while ((pUser=transAH.GetNextUser(NULL)) != NULL);
          outprf(usrnum);
          prf("");
     }
     rstmbk();
}


