
/*
 *  MBCMD.C - 1/31/88 - Command parser and dispatch.
 */

#include "mb.h"

docmd()
{
  typedef struct
  {
    char  n1, n2;    /* The two command letters        */
    byte  args;      /* Number of arguments required   */
    word  mode;      /* Bitmask of allowed port modes  */
    int   (*fp)();   /* Pointer to function return int */
  } CMDDEF;

  register CMDDEF *cp;
  register int status;

/*
 *  The functions that do the commands.
 */
#ifndef MCH_AMIGA
  extern int lock();
  extern int all_fwd();
#endif
  extern int klmsg();
  extern int lstmsg();
  extern int rdmsg();
  extern int sndmlt();
  extern int sndmsg();
  extern int fwdcmd();
  extern int done();
#ifdef MCH_AMIGA
  extern int donefunc();
#endif
  extern int help();
  extern int klmsgm();
  extern int mkrem();
  extern int mksys();
  extern int makmlt();
  extern int makmsg();
  extern int dupmsg();
  extern int filmsg();
  extern int setunt();
  extern int edmsg();
  extern int edtfc();
  extern int copfil();
  extern int renfil();
  extern int kilfil();
  extern int uloadl();
  extern int uloadr();
  extern int dloads();
  extern int dloadi();
  extern int dloadl();
  extern int dloadr();
  extern int bye();
  extern int lterm();
  extern int settime();
  extern int chguser();
  extern int chgparam();
  extern int utalk();
  extern int rdmsgm();
  extern int duser();
  extern int dwuser();
  extern int edport();
  extern int eduser();
  extern int edusera();
  extern int puser();
  extern int sfwd();
  extern int newfwd();
  extern int prthrd();
#ifndef MCH_AMIGA
  extern int connuser();
  extern int ctncv();
  extern int mtncv();
  extern int utncv();
#endif
  extern int prtdir();
  extern int prtver();
#if nncmd
  extern int donet();
#endif
  extern int dosys();
#ifdef MCH_AMIGA
   extern int flipdebug();
   extern int prtfwd();
#endif

/*
 *  Command char 1, char 2, # args, modes allowed, function
 */

static CMDDEF cmds[] =
{
  '!', ' ', 2, local,          dosys,
  '!', ' ', 3, local,          dosys,
  '!', ' ', 4, local,          dosys,
  '!', ' ', 5, local,          dosys,

  '@', ' ', 1, remote,         mksys,
  '@', ' ', 1, sysop,          mkrem,

  '?', ' ', 1, all,            help,
  '?', ' ', 2, all,            help,
#ifndef MCH_AMIGA
  'A', ' ', 1, ops,            all_fwd,
  'A', 'I', 1, ops,            all_fwd,
  'A', 'H', 1, ops,            lock,
#endif
  'B', ' ', 1, all,            bye,

#ifndef MCH_AMIGA
  'C', ' ', 3, ops,            settime,
  'C', ' ', 2, all,            connuser,
#endif
  'C', 'M', 3, ops,            dupmsg,
  'C', 'M', 5, ops,            dupmsg,
  'C', 'M', 7, ops,            dupmsg,
#ifndef MCH_AMIGA
  'C', '*', 1, remote,         utncv,
  'C', '*', 2, remote,         ctncv,
  'C', '*', 4, remote,         ctncv,
#endif

#ifdef MCH_AMIGA
  'D', 'B', 1, ops,            flipdebug,
#endif

  'D', 'L', 1, ops,            duser,
  'D', 'L', 2, ops,            duser,
  'D', 'M', 1, ops,            duser,
  'D', 'M', 2, ops,            duser,
  'D', 'S', 1, ops,            duser,
  'D', 'S', 2, ops,            duser,
  'D', 'U', 1, ops,            duser,
  'D', 'U', 2, ops,            duser,
  'D', 'W', 1, ops,            dwuser,
  'D', 'W', 2, ops,            dwuser,
  'D', 'X', 1, ops,            duser,
  'D', 'X', 2, ops,            duser,
  'D', '*', 2, local,          dloadl,
  'D', '*', 2, remote,         dloadr,
  'D', '*', 2, sysop,          dloads,

  'E', ' ', 2, ops,            edmsg,
  'E', 'P', 2, ops,            edport,
  'E', 'S', 1, ops,            chgparam,
  'E', 'T', 2, all,            edtfc,
  'E', 'U', 1, ops,            edusera,
  'E', 'U', 2, ops,            eduser,

  'F', '>', 1, remote,         fwdcmd,
  'F', '*', 3, ops,            filmsg,
  'F', '*', 4, ops,            filmsg,

  'G', 'M', 1, ops,            setunt,
  'G', 'R', 1, ops,            setunt,
  'G', 'R', 2, ops,            setunt,
  'G', 'U', 1, ops,            setunt,

  'H', ' ', 1, all,            help,
  'H', ' ', 2, all,            help,

  'I', ' ', 1, all,            dloadi,

  'J', '*', 1, all,            prthrd,

  'K', ' ', 2, all,            klmsg,
  'K', 'F', 1, ops,            klmsgm,
  'K', 'F', 2, ops,            klmsgm,
  'K', 'M', 1, all,            klmsgm,
  'K', 'O', 1, ops,            klmsgm,
  'K', 'O', 2, ops,            klmsgm,
  'K', 'T', 2, all,            klmsg,
  'K', 'Y', 1, ops,            klmsgm,
  'K', 'Y', 2, ops,            klmsgm,

  'L', '*', 1, all,            lstmsg,
  'L', '*', 2, all,            lstmsg,
  'L', '*', 3, all,            lstmsg,

  'M', 'M', 3, ops,            makmlt,
  'M', 'M', 4, ops,            makmlt,
  'M', '*', 3, ops,            makmsg,
  'M', '*', 4, ops,            makmsg,
  'M', '*', 5, ops,            makmsg,
  'M', '*', 6, ops,            makmsg,
  'M', '*', 7, ops,            makmsg,
  'M', '*', 8, ops,            makmsg,
#ifndef MCH_AMIGA
  'M', '*', 1, remote,         mtncv,
#endif

  'N', ' ', 2, all,            chguser,
  'N', ' ', 3, ops,            renfil,
  'N', 'E', 1, all,            chguser,
  'N', 'H', 2, all,            chguser,
#if nncmd
  'N', 'N', 5, ops,            donet,
#endif
  'N', 'Z', 2, all,            chguser,

  'P', ' ', 2, all,            puser,

#ifndef MCH_AMIGA
  'Q', ' ', 1, local,          done,
#else
  'Q', ' ', 1, local,          donefunc,
#endif

  'R', ' ', 2, all,            rdmsg,
  'R', 'H', 2, all,            rdmsg,
  'R', 'M', 1, all,            rdmsgm,

  'S', 'M', 2, ops,            sndmlt,
  'S', 'M', 3, ops,            sndmlt,
  'S', '*', 2, all,            sndmsg,
  'S', '*', 3, all,            sndmsg,
  'S', '*', 4, all,            sndmsg,
  'S', '*', 5, all,            sndmsg,
  'S', '*', 6, all,            sndmsg,
  'S', '*', 7, all,            sndmsg,

  'T', ' ', 1, remote,         utalk,
  'T', '*', 1, local,          lterm,
  'T', '*', 2, local,          lterm,

  'U', '*', 2, ops,            uloadl,
  'U', '*', 2, remote,         uloadr,

  'V', ' ', 1, all,            prtver,
  'V', ' ', 3, ops,            copfil,

  'W', '*', 1, all,            prtdir,
  'W', '*', 2, all,            prtdir,

  'X', ' ', 1, ops,            sfwd,
  'X', ' ', 2, ops,            sfwd,
  'X', 'I', 1, ops,            sfwd,
  'X', 'I', 2, ops,            sfwd,

  'Y', 'F', 1, ops,            newfwd,
  'Y', 'F', 2, ops,            newfwd,

  'Z', '*', 2, ops,            kilfil,

  '\0', ' ', 0, 0, 0, 0
};

  port->cmdcnt++;

  if (strlen(port->fld[0]) < 3)
    for (cp = cmds; cp->n1; cp++)
    if (port->mode & cp->mode)
    if (port->opt1 is cp->n1)
    if ((port->opt2 is cp->n2) or (cp->n2 is '*'))
    if (port->flds is cp->args) { status = (*cp->fp)(); return; }

  if ((port->opt1 is '[') and (port->cmdcnt is 1)) { isbid(); return;}

  port->msg = mwhat;
  port->errors++;
}

/*
 *  User wants to log out.
 *  Set the flag so they will be logged out.
 */

bye()
{
  pt_flag = 0;
  port->mode = logout;
}

/*
 *  User done being remote sysop.
 *  Make them normal user again.
 */

mkrem()
{
  port->flags clrbit p_clrsys;
  port->mode = remote;
  if (!port->tmode)
  {
     cmdtnc();
     onetnc("cr on\n");
     onetnc("cp of\n");
     onetnc("se $0d\n");
     convtnc();
  }
}

/*
 *  User wants to be remote sysop.
 *  Let them, if they are allowed to.
 */

mksys()
{
  if (!(port->priv & p_sysop) or !(port->user->options & u_sysop)or!(pass()))
    { port->msg = mwhat; return; }

  port->flags setbit p_clrsys;
  port->mode = sysop;
  if (!port->tmode)
  {
     cmdtnc();
     onetnc("cr of\n");
     onetnc("cp on\n");
     onetnc("se $7f\n");
     convtnc();
  }
}

/* the next null ifdef is only used to signal a change in the code */
#ifdef MCH_AMIGA
#endif
#ifndef NEWPASS
pass()
{
  int count,psn,lpsn;
  char temp[4], pword[5];
  for (count = 0, lpsn = 0; count < 4; count++)
    {
      while ((psn=(rand()/512))== lpsn);
      sprintf (temp, "%3u", psn+1);
      outstr(temp);
      pword[count] = *(keylst+psn);
      lpsn = psn;
    }
    outstr("\n");
    getdat();
    if (matchn(port->line, pword, 4)) return true;
    return false;
 }
#endif

/*
 *  Lock up the current window for no more than 180 seconds.
 */
#ifndef MCH_AMIGA
lock()
{
  long l;
  if (!(s_flag & s_dv)) return;
  outstr("\nWindow locked");
  while (true)
  {
    getcomd(); if (port->opt2 isnt 'H') break;
    switchw();
  }
  outstr("-unLOCKED\n");
  return;
}
#endif
