/***************************************************************************
 *                                                                         *
 *   AAEML.C                                                               *
 *                                                                         *
 *   Copyright (c) 1988-1997 Galacticomm, Inc.    All Rights Reserved.     *
 *                                                                         *
 *   This is the Worldgroup ASCII/ANSI electronic mail service handler.    *
 *   (was EMAIL.C)                                                         *
 *                                                                         *
 *                                                - J. Alvrus  8/2/94      *
 *                                                                         *
 ***************************************************************************/

#include "gcomm.h"
#include "majorbbs.h"
#include "gme.h"
#include "galmsg.h"
#include "emlfor.h"
#include "aaef.h"

#define FILREV "$Revision: 12 $"

GBOOL emllon(VOID);
GBOOL emlinp(VOID);
VOID  emlsts(VOID);
VOID  emlhup(VOID);
VOID  emlsht(VOID);

struct module emlmib={             /* E-mail module interface block        */
     "",                           /*   module name (from .MDF file)       */
     emllon,                       /*   logon routine                      */
     emlinp,                       /*   input routine                      */
     emlsts,                       /*   status handler                     */
     NULL,                         /*   injoth() handler                   */
     NULL,                         /*   logoff routine                     */
     emlhup,                       /*   hangup routine                     */
     NULL,                         /*   midnight clean up                  */
     NULL,                         /*   delete account                     */
     emlsht                        /*   shutdown routine                   */
};

INT emlstate;                      /* state code for E-mail module         */

VOID chk4new(SHORT rc);
GBOOL slonrdn(VOID);
VOID semainm(VOID);
VOID ckinbox(SHORT rc);
VOID ckoutbox(SHORT rc);
VOID sertfq(GBOOL newflg);
static VOID sgonum(VOID);
static GBOOL startat(GBOOL newflg,INT hlpmsg);
static VOID goscan(SHORT rc);
static VOID scan(VOID);
static VOID goscstt(VOID);
VOID sescan(VOID);
static VOID sthrfbp(VOID);
static VOID thrprnt(SHORT rc);
static VOID entrthr(VOID);
static VOID exithr(VOID);
static VOID nxtscn(SHORT rc);
static VOID prvscn(SHORT rc);
static VOID nocscn(SHORT rc);
static VOID nocscp(SHORT rc);
static VOID readit(VOID);
VOID emarkrd(SHORT rc);
VOID emrkdone(SHORT rc);
static VOID chkatt(VOID);
VOID edndone(SHORT rc);
static VOID gordstt(VOID);
VOID seread(VOID);
VOID jumpto(VOID);
VOID btdone(SHORT rc);
VOID btxdone(SHORT rc);
VOID btodone(SHORT rc);
GBOOL tooptok(VOID);
GBOOL froptok(VOID);
static VOID valrpl(USHORT forum);
VOID erdone(SHORT rc);
VOID emddone(SHORT rc);
VOID edldone(SHORT rc);
VOID swhofwd(VOID);
VOID startfwd(CHAR *to);
VOID efcdone(SHORT rc);
VOID efwdone(SHORT rc);
VOID srafabt(VOID);
VOID swhocpy(VOID);
VOID startcpy(CHAR *to);
VOID eccdone(SHORT rc);
VOID ecpdone(SHORT rc);
VOID seforop(VOID);
VOID sewhoto(VOID);
VOID wrtlst(VOID);
GBOOL wlstl(VOID);
VOID wlstd(SHORT rc);
VOID gspecfn(VOID);
VOID gspecfs(VOID);
VOID dspchlp(VOID);
VOID sspecfn(VOID);
VOID sentfwd(VOID);
VOID ssetprf(VOID);
VOID snemprf(VOID);
VOID sfmtprf(VOID);
VOID srmdprf(VOID);
VOID squoprf(VOID);
VOID scarprf(VOID);
VOID scmtprf(VOID);
VOID sl2edpmt(VOID);
GBOOL eslstr(VOID);
VOID eslstd(SHORT rc);
VOID sacclvk(VOID);
VOID slstchg(VOID);
VOID ssysent(VOID);
GBOOL syslstr(VOID);
VOID syslstd(SHORT rc);
VOID gqikpmt(VOID);
VOID sqikpmt(VOID);
VOID sqikedt(VOID);
VOID esndone(SHORT rc);
static VOID smodwht(VOID);
static VOID get4mod(SHORT rc);
static VOID moddone(SHORT rc);
static VOID sdelmsn(VOID);
static VOID deldone(SHORT rc);
GBOOL startcc(VOID);
GBOOL nextcc(VOID);
VOID ccsndr(VOID);
static VOID retmain(VOID);
GBOOL anyqik(struct qikdat *qiklst);
VOID showqik(struct qikdat *qiklst);
CHAR *esystv(VOID);

VOID
iniaaeml(VOID)                     /* initialize ASCII/ANSI E-mail module  */
{
     stlcpy(emlmib.descrp,gmdnam("galeml.mdf"),MNMSIZ);
     emlstate=register_module(&emlmib);
     register_textvar("EMAIL_SYSOP_UID",esystv);
}

GBOOL
emllon(VOID)                       /* E-mail logon handler                 */
{
     if (usrptr->flags&WSGCSU) {
          return(FALSE);
     }
     setmeup();
     switch (usrptr->substt) {
     case 0:
          ASSERT(peruflg[usrnum] == 0);
          bgncnc();
          cncall();
          btumil(usrnum,DFTIMX);
          peruflg[usrnum]=INEMAIL;
          if (!sameas(myqsptr()->userid,usaptr->userid)) {
               switch (inigmeu()) {
               case GMERST:
                    prfmsg(EMLRST);
                    outprf(usrnum);
                    break;
               }
          }
          if (qsptr->fwdee[0] != '\0') {
               prfmsg(BTWFWD,qsptr->fwdee);
               outprf(usrnum);
          }
          inigmerq(efwork);
          efvda->tmpmid=firstnew(usaptr->userid,EMLID);
          inormrd(efwork,usaptr->userid,EMLID,efvda->tmpmid);
          efvda->flags&=~RDFROM;
          getnear(GTLE,chk4new);
          return(!(efvda->flags&LONFIN));
     case CHK4NEW:
          return(FALSE);
     default:
          if (efvda->flags&LONFIN) {
               return(FALSE);
          }
          return(emlinp());
     }
}

VOID
chk4new(                           /* check for new mail at logon          */
SHORT rc)                          /*   return code from read function     */
{
     switch (rc) {
     case GMEOK:
          if (msg->msgid > efvda->tmpmid) {
               prfmsg(NEWMAIL);
               if (qsptr->flags&P4NEWM) {
                    efvda->flags|=LONIPG;
                    if (qsptr->flags&GORTIN) {
                         scan();
                    }
                    else {
                         efvda->curmid=efvda->tmpmid;
                         gostt(LONRDN);
                    }
                    if (efvda->cflags&DIDCYC) {
                         chkcyc();
                    }
                    else {
                         efvda->dftchr=getdft();
                         outprf(usrnum);
                    }
                    return;
               }
          }
          else {
               prfmsg(OLDMAIL);
          }
          break;
     case GMECRD:
     case GMENFND:
          prf("");
          break;
     default:
          prfmsg(READERR,rc);
          break;
     }
     clsgmerq(efwork);
     outprf(usrnum);
     clrprf();
     efvda->flags|=LONFIN;
     usrptr->substt=CHK4NEW;
     if (efvda->cflags&DIDCYC) {
          efvda->cflags&=~DIDCYC;
          btulok(usrnum,FALSE);
          btucli(usrnum);
          btuinj(usrnum,CRSTG);
     }
}

GBOOL
emlinp(VOID)                       /* E-mail line input handler            */
{
     setmeup();
     if (usrptr->flags&INJOIP) {
          switch (usrptr->substt) {
          case XMTING:
               if (usrptr->flags&ABOIP) {
                    xmtdone(TRUE);
                    if (efvda->cflags&CKDCYC) {
                         return(TRUE);
                    }
                    break;
               }
               return(TRUE);
          case LISTING:
               if (usrptr->flags&ABOIP) {
                    (*efvda->whndun)(TRUE);
                    chkcyc();
                    if (efvda->cflags&CKDCYC) {
                         return(TRUE);
                    }
                    break;
               }
               return(TRUE);
          case SENDING:
          case RPLING:
          case AUTOLOF:
          case ALOFNOW:
          case FWDING:
          case COPYING:
          case DELING:
          case MODING:
          case CRDPRNT:
          case CRDNEAR:
          case CREREAD:
          case CRDNEXT:
          case CRDPREV:
          case CMARKRD:
               return(TRUE);
          case EMAINM:
               gostt(EMAINS);
               break;
          case SPECFN:
          case LSPECFN:
               gspecfs();
               break;
          case LONRDN:
               prfmsg(NEWMAIL);
          default:
               gostt(usrptr->substt);
               break;
          }
          efvda->dftchr=getdft();
          outprf(usrnum);
          return(TRUE);
     }
     switch (usrptr->substt) {
     case XMTING:
          btuclo(usrnum);
          xmtdone(TRUE);
          if (!(efvda->cflags&CKDCYC)) {
               efvda->dftchr=getdft();
               outprf(usrnum);
          }
          return(TRUE);
     case LISTING:
          btuclo(usrnum);
          (*efvda->whndun)(TRUE);
          chkcyc();
          if (!(efvda->cflags&CKDCYC)) {
               efvda->dftchr=getdft();
               outprf(usrnum);
          }
          return(TRUE);
     case CRDNEAR:
     case CRDNEXT:
     case CRDPREV:
     case CREREAD:
     case CMARKRD:
     case DELING:
     case MODING:
     case CRDPRNT:
          return(TRUE);
     case AUTOLOF:
          slofwait();
     case ALOFNOW:
     case SENDING:
     case RPLING:
     case FWDING:
     case COPYING:
          return(TRUE);
     }
     if (efvda->cflags&DIDCYC) {
          rstcnc();
     }
     else if (pfnwrn()) {
          return(TRUE);
     }
     else {
          chkdft(efvda->dftchr);
          if (margc == 1 && sameas(margv[0],"x")) {
               switch (usrptr->substt) {
               case LONRDN:
                    clsgmerq(efwork);
                    return(FALSE);
               case EMAINM:
               case EMAINS:
                    return(FALSE);
               case WHO2CC:
                    clrxrf();
                    gostt(POSTWRT);
                    break;
               case POSTWRT:
               case NAMATT:
                    clsgmerq(efwork);
                    if (efvda->cclist != NULL) {
                         free(efvda->cclist);
                         efvda->cclist=NULL;
                    }
                    if ((msg->flags&FILATT) && !(msg->flags&FILIND)) {
                         unlink(filatt);
                    }
                    retmain();
                    break;
               case ERTFQN:
               case ERTFQL:
               case ERFQF:
               case EWRTTO:
               case ESCAN:
               case FTDSCN:
               case FTSCAN:
               case FDSCAN:
               case FSCAN:
               case SCNEND:
               case SCNENDX:
               case SCNBEG:
               case SCNBEGX:
               case THRFBP:
               case GONUM:
               case DLNOW:
               case ERDTO:
               case ERDFR:
               case ERDPAR:
               case EFREAD:
               case EFOREAD:
               case FTREAD:
               case USEQUO:
               case WHOFWD:
               case RAFABT:
               case WHOCPY:
               case CMTPMT:
               case FOPRDA:
               case FOPRDU:
               case FOPRDX:
                    clsgmerq(efwork);
                    retmain();
                    break;
               case MODWHT:
               case DELMSN:
               case SPECFN:
               case SPECFS:
               case LSPECFN:
               case LSPECFS:
                    retmain();
                    break;
               case SYSENT:
                    clsgmerq(efwork);
               case ACCLVK:
               case LSTCHG:
               case L2EDPMT:
               case ENTFWD:
               case CHGFWD:
               case SETPRF:
                    condex();
                    gspecfs();
                    break;
               case NEMPRF:
               case FMTPRF:
               case RMDPRF:
               case QUOPRF:
               case CARPRF:
               case CMTPRF:
                    gostt(SETPRF);
                    break;
               case QIKPMT:
               case QIKEDT:
                    savqik(qikbuf);
                    condex();
                    gspecfs();
                    break;
               default:
#ifdef DEBUG
                         catastro("Update your X list! (state=%d)",
                                  usrptr->substt);
#endif
                    clsgmerq(efwork);
                    return(FALSE);
               }
               efvda->dftchr=getdft();
               outprf(usrnum);
               return(!(efvda->flags&LONFIN));
          }
     }
     do {
          bgncnc();
          switch (usrptr->substt) {
          case 0:
               btumil(usrnum,DFTIMX);
               cncchr();
               peruflg[usrnum]&=~(INEDIT|INFTF|INFSD|INEDHLP);
               peruflg[usrnum]|=INEMAIL;
               gostt(EMAINM);
               break;
          case LONRDN:
               if (!slonrdn()) {
                    return(FALSE);
               }
               break;
          case EMAINM:
          case EMAINS:
               semainm();
               break;
          case ERTFQN:
          case ERTFQL:
               sertfq(TRUE);
               break;
          case ERFQF:
               sertfq(FALSE);
               break;
          case GONUM:
               sgonum();
               break;
          case ESCAN:
          case SCNEND:
          case SCNENDX:
          case SCNBEG:
          case SCNBEGX:
          case FTDSCN:
          case FTSCAN:
          case FDSCAN:
          case FSCAN:
               sescan();
               break;
          case THRFBP:
               sthrfbp();
               break;
          case DLNOW:
               sdlnow(edndone);
               break;
          case ERDTO:
          case ERDFR:
          case ERDPAR:
          case EFREAD:
          case EFOREAD:
          case FTREAD:
               seread();
               break;
          case USEQUO:
               susequo();
               break;
          case WHOFWD:
               swhofwd();
               break;
          case RAFABT:
               srafabt();
               break;
          case WHOCPY:
               swhocpy();
               break;
          case CMTPMT:
               scmtpmt();
               break;
          case FOPRDA:
          case FOPRDU:
          case FOPRDX:
               seforop();
               break;
          case EWRTTO:
               sewhoto();
               break;
          case POSTWRT:
               spostwrt();
               break;
          case NAMATT:
               snamatt();
               break;
          case WHO2CC:
               swhotocc();
               break;
          case MODWHT:
               smodwht();
               break;
          case DELMSN:
               sdelmsn();
               break;
          case SPECFN:
          case SPECFS:
          case LSPECFN:
          case LSPECFS:
               sspecfn();
               break;
          case ENTFWD:
          case CHGFWD:
               sentfwd();
               break;
          case SETPRF:
               ssetprf();
               break;
          case NEMPRF:
               snemprf();
               break;
          case FMTPRF:
               sfmtprf();
               break;
          case RMDPRF:
               srmdprf();
               break;
          case QUOPRF:
               squoprf();
               break;
          case CARPRF:
               scarprf();
               break;
          case CMTPRF:
               scmtprf();
               break;
          case L2EDPMT:
               sl2edpmt();
               break;
          case ACCLVK:
               sacclvk();
               break;
          case LSTCHG:
               slstchg();
               break;
          case SYSENT:
               ssysent();
               break;
          case QIKPMT:
               sqikpmt();
               break;
          case QIKEDT:
               sqikedt();
               break;
          default:
               catastro("Invalid state in ASCII/ANSI E-mail (state=%d)",
                        usrptr->substt);
          }
     } while (!endcnc());
     efvda->dftchr=getdft();
     outprf(usrnum);
     return(!(efvda->flags&LONFIN));
}

VOID
emlsts(VOID)                       /* E-mail status handler                */
{
     if (status == CYCLE) {
          setmeup();
          efvda->cflags|=DIDCYC;
          switch (usrptr->substt) {
          case LISTING:
               lister();
               break;
          case SENDING:
               sender();
               break;
          case RPLING:
               replyr();
               break;
          case AUTOLOF:
               clofwait();
          case ALOFNOW:
               break;
          case DELING:
               cdelm();
               break;
          case MODING:
               cmodr();
               break;
          case CRDPRNT:
               cgetprnt();
               break;
          case CRDNEAR:
               cgetnear();
               break;
          case CREREAD:
               creget();
               break;
          case CRDNEXT:
               cygetnext();
               break;
          case CRDPREV:
               cgetprev();
               break;
          case XMTING:
               cxmtxt();
               break;
          case CMARKRD:
               cmarkoff();
               break;
          case FWDING:
               cfwdr();
               break;
          case COPYING:
               ccopyr();
               break;
          default:
               efvda->cflags&=~DIDCYC;
               dfsthn();
               break;
          }
     }
     else {
          dfsthn();
     }
}

VOID
emlhup(VOID)                       /* E-mail hang up handler               */
{
     setmeup();
     if (usrptr->state == emlstate) {
          switch (usrptr->substt) {
          case LONRDN:
          case ERTFQN:
          case ERTFQL:
          case ERFQF:
          case GONUM:
          case ESCAN:
          case SCNEND:
          case SCNENDX:
          case SCNBEG:
          case SCNBEGX:
          case FTDSCN:
          case FTSCAN:
          case FDSCAN:
          case FSCAN:
          case THRFBP:
          case DLNOW:
          case ERDTO:
          case ERDFR:
          case ERDPAR:
          case EFREAD:
          case EFOREAD:
          case FTREAD:
          case USEQUO:
          case WHOFWD:
          case RAFABT:
          case WHOCPY:
          case CMTPMT:
          case FOPRDA:
          case FOPRDU:
          case FOPRDX:
          case EWRTTO:
          case DELING:
          case MODING:
          case CRDPRNT:
          case CRDNEAR:
          case CRDNEXT:
          case CRDPREV:
          case XMTING:
          case CMARKRD:
          case FWDING:
          case COPYING:
          case SYSENT:
               clsgmerq(efwork);
               break;
          case LISTING:
               if (gmerqopn(efwork)) {
                    clsgmerq(efwork);
               }
               break;
          case POSTWRT:
          case NAMATT:
          case WHO2CC:
          case SENDING:
          case RPLING:
               clsgmerq(efwork);
               if (efvda->cclist != NULL) {
                    free(efvda->cclist);
                    efvda->cclist=NULL;
               }
               if ((msg->flags&FILATT) && !(msg->flags&FILIND)) {
                    unlink(filatt);
               }
               break;
          case QIKPMT:
          case QIKEDT:
               savqik(qikbuf);
               break;
          case CHK4NEW:
          case EMAINM:
          case EMAINS:
          case AUTOLOF:
          case ALOFNOW:
          case MODWHT:
          case DELMSN:
          case SPECFN:
          case SPECFS:
          case LSPECFN:
          case LSPECFS:
          case L2EDPMT:
          case ACCLVK:
          case LSTCHG:
          case ENTFWD:
          case CHGFWD:
          case SETPRF:
          case NEMPRF:
          case FMTPRF:
          case RMDPRF:
          case QUOPRF:
          case CARPRF:
          case CMTPRF:
          case 0:
               break;
          default:
#ifdef DEBUG
                    catastro("Update E-mail hangup states! (state=%d)",
                              usrptr->substt);
#endif
               break;
          }
     }
     else if (peruflg[usrnum]&(INEDIT|INFTF)) {
          clsgmerq(efwork);
          if (efvda->cclist != NULL) {
               free(efvda->cclist);
               efvda->cclist=NULL;
          }
     }
     if (usrptr->flags&WSGCSU) {
          peruflg[usrnum]&=~(INEDIT|INFTF);
     }
     else {
          if (sameas(qsptr->userid,usaptr->userid)) {
               clsgmeu();
          }
          peruflg[usrnum]=0;
     }
}

VOID
emlsht(VOID)                       /* E-mail shutdown handler              */
{
     clsmsg(efmb);
}

GBOOL                              /*   does user want to read mail now?   */
slonrdn(VOID)                      /* state: read new mail at logon        */
{
     switch (cncyesno()) {
     case 'Y':
          scan();
          break;
     case 'N':
          clsgmerq(efwork);
          cncall();
          return(FALSE);
     default:
          cncall();
          prfmsg(YORN);
          gostt(usrptr->substt);
          break;
     }
     return(TRUE);
}

VOID
semainm(VOID)                      /* state: main E-mail menu              */
{
     switch (cncchr()) {
     case '?':
          cncall();
          if (usrptr->substt == EMAINM) {
               prfmsg(EINFO,emschg,eatchg,epkchg,rrrchg,prichg,emllif);
          }
          gostt(EMAINM);
          break;
     case 'R':
          inigmerq(efwork);
          efvda->tmpmid=firstnew(usaptr->userid,EMLID);
          inormrd(efwork,usaptr->userid,EMLID,efvda->tmpmid);
          efvda->flags&=~RDFROM;
          efvda->cflags&=~NOCUR;
          getnear(GTLE,ckinbox);
          break;
     case 'W':
          efvda->flags&=~CCLST;
          efvda->numcc=0;
          efvda->cclstsz=0U;
          ASSERT(efvda->cclist == NULL);
          setmem(msg,sizeof(struct message),0);
          msg->forum=EMLID;
          stlcpy(msg->from,usaptr->userid,MAXADR);
          inigmerq(efwork);
          switch (wrtany()) {
          case VALACC:
               prfmsg(NWRTACC);
               break;
          case VALCRD:
               prfmsg(NWRTCRD);
               break;
          }
          gostt(EWRTTO);
          break;
     case 'M':
          prfmsg(MODWRN);
          gostt(MODWHT);
          break;
     case 'E':
          gostt(DELMSN);
          break;
     case 'F':
          inigmerq(efwork);
          inormrd(efwork,usaptr->userid,EMLID,FIRSTM);
          seqctx(efwork,ESQFRU);
          efvda->flags|=RDFROM;
          efvda->cflags&=~NOCUR;
          getnext(ckoutbox);
          break;
     case 'S':
          gspecfn();
          break;
     default:
          errhlp(CNOTIL,EMAINS);
          break;
     }
}

VOID
ckinbox(                           /* check for mail in user's in box      */
SHORT rc)                          /*   GME read code                      */
{
     switch (rc) {
     case GMEOK:
          if (msg->msgid > efvda->tmpmid) {
               gostt(ERTFQN);
          }
          else {
               gostt(ERTFQL);
          }
          efvda->curmid=efvda->tmpmid;
          break;
     default:
          clsgmerq(efwork);
          cycall();
          switch (rc) {
          case GMENFND:
               prfmsg(NOMSGT);
               break;
          case GMECRD:
               prfmsg(ENRDCRD);
               howbuy();
               break;
          default:
               prfmsg(READERR,rc);
               break;
          }
          outprf(usrnum);
          retmain();
          break;
     }
}

VOID
ckoutbox(                          /* check for mail from user             */
SHORT rc)                          /*   GME read code                      */
{
     switch (rc) {
     case GMEOK:
          efvda->curmid=msg->msgid;
          gostt(ERFQF);
          break;
     default:
          clsgmerq(efwork);
          cycall();
          if (rc == GMENFND) {
               prfmsg(NOMSGF);
          }
          else {
               prfmsg(READERR,rc);
          }
          outprf(usrnum);
          retmain();
          break;
     }
}

VOID
sertfq(                            /* state: which message to start with   */
GBOOL newflg)                      /*   is default "new message"?          */
{
     if (!startat(newflg,efvda->flags&RDFROM ? ERFHLP : ERTHLP)) {
          prfmsg(NONEWE);
          outprf(usrnum);
          retmain();
     }
}

static VOID
sgonum(VOID)                       /* state: which message to go to        */
{
     if (!startat(FALSE,GNMHLP)) {
          errhlp(NOCURM,usrptr->substt);
     }
}

static GBOOL                       /*   returns FALSE if can't start scan  */
startat(                           /* start scanning at what message?      */
GBOOL newflg,                      /*   is current message "new"           */
INT hlpmsg)                        /*   help message to display            */
{
     switch (morcnc()) {
     case '.':
          if (newflg && msg->msgid <= efvda->tmpmid) {
               efvda->curmid=0L;
               clsgmerq(efwork);
               cncall();
               return(FALSE);
          }
          if (efvda->cflags&NOCUR) {
               return(FALSE);
          }
          cncchr();
          scan();
          break;
     case 'F':
          cncchr();
          exithr();
          msgctx(efwork,FIRSTM);
          getnext(goscan);
          break;
     case 'L':
          cncchr();
          exithr();
          msgctx(efwork,LASTM);
          getprev(goscan);
          break;
     case '?':
          errhlp(hlpmsg,usrptr->substt);
          break;
     default:
          if (isdigit(morcnc())) {
               exithr();
               efvda->tmpmid=cnclon();
               if (efvda->tmpmid == msg->msgid) {
                    scan();
               }
               else {
                    jumpto();
               }
          }
          else {
               errhlp(EMLHUH,usrptr->substt);
          }
          break;
     }
     return(TRUE);
}

VOID
goscan(                            /* start reading after finding message  */
SHORT rc)                          /*   GME read code                      */
{
     switch (rc) {
     case GMEOK:
          if ((efvda->flags&JUMPED) && msg->msgid != efvda->tmpmid) {
               prfmsg(MISMSG,l2as(efvda->tmpmid));
          }
          efvda->flags&=~JUMPED;
          scan();
          break;
     default:
          clsgmerq(efwork);
          cycall();
          switch (rc) {
          case GMENFND:
               prfmsg(NOMSGT);
               break;
          case GMECRD:
               prfmsg(ENRDCRD);
               howbuy();
               break;
          default:
               prfmsg(READERR,rc);
               break;
          }
          outprf(usrnum);
          retmain();
          break;
     }
}

static VOID
scan(VOID)                         /* scan E-mail messages                 */
{
     efvda->curmid=msg->msgid;
     efvda->cflags&=~NOCUR;
     if (isripu() || (qsptr->flags&CMBHDR)) {
          if (cb4hdr) {
               prf("\x0C");
          }
          sumams(SUMMSG,msg);
          outprf(usrnum);
          readit();
     }
     else {
          sumams(SUMMSG,msg);
          if (morcnc() != 'P') {
               outprf(usrnum);
          }
          goscstt();
     }
}

VOID
goscstt(VOID)                      /* go to pre-read (scan) state          */
{
     if (msg->forum == EMLID) {
          gostt(ESCAN);
     }
     else {
          if (efvda->flags&THRING) {
               if (dnldok(msg->forum)) {
                    gostt(FTDSCN);
               }
               else {
                    gostt(FTSCAN);
               }
          }
          else {
               if (dnldok(msg->forum)) {
                    gostt(FDSCAN);
               }
               else {
                    gostt(FSCAN);
               }
          }
     }
}

static VOID
nxtscn(                            /* read after finding next message      */
SHORT rc)                          /*   GME read code                      */
{
     switch (rc) {
     case GMEOK:
          scan();
          break;
     case GMENFND:
          cycall();
          if (efvda->flags&THRING) {
               prfmsg(THREND);
               goscstt();
          }
          else {
               gostt(efvda->cflags&NOCUR ? SCNENDX : SCNEND);
          }
          break;
     default:
          clsgmerq(efwork);
          cycall();
          if (rc == GMECRD) {
               prfmsg(ENRDCRD);
               howbuy();
          }
          else {
               prfmsg(READERR,rc);
          }
          outprf(usrnum);
          retmain();
          break;
     }
}

static VOID
prvscn(                            /* read after finding previous message  */
SHORT rc)                          /*   GME read code                      */
{
     switch (rc) {
     case GMEOK:
          scan();
          break;
     case GMENFND:
          cycall();
          if (efvda->flags&THRING) {
               prfmsg(THRBGN);
               goscstt();
          }
          else {
               gostt(efvda->cflags&NOCUR ? SCNBEGX : SCNBEG);
          }
          break;
     default:
          clsgmerq(efwork);
          cycall();
          if (rc == GMECRD) {
               prfmsg(ENRDCRD);
               howbuy();
          }
          else {
               prfmsg(READERR,rc);
          }
          outprf(usrnum);
          retmain();
          break;
     }
}

static VOID
nocscn(                            /* find next msg after current deleted  */
SHORT rc)                          /*   GME read code                      */
{
     switch (rc) {
     case GMEOK:
          if (msg->msgid == efvda->curmid) {
               cycall();
               gostt(SCNEND);
          }
          else if (msg->msgid < efvda->curmid) {
               cycall();
               efvda->cflags|=NOCUR;
               msgctx(efwork,efvda->curmid);
               gostt(SCNENDX);
          }
          else {
               scan();
          }
          break;
     default:
          clsgmerq(efwork);
          cycall();
          switch (rc) {
          case GMECRD:
               prfmsg(ENRDCRD);
               howbuy();
               break;
          case GMENFND:
               prfmsg(SCNOMO,(efvda->flags&RDFROM ? "from" : "to"));
               break;
          default:
               prfmsg(READERR,rc);
               break;
          }
          outprf(usrnum);
          retmain();
          break;
     }
}

static VOID
nocscp(                            /* read after find prev msg (no current)*/
SHORT rc)                          /*   GME read code                      */
{
     switch (rc) {
     case GMEOK:
          if (msg->msgid == efvda->curmid) {
               cycall();
               gostt(SCNBEG);
          }
          else if (msg->msgid > efvda->curmid) {
               cycall();
               efvda->cflags|=NOCUR;
               msgctx(efwork,efvda->curmid);
               gostt(SCNBEGX);
          }
          else {
               scan();
          }
          break;
     default:
          clsgmerq(efwork);
          cycall();
          switch (rc) {
          case GMECRD:
               prfmsg(ENRDCRD);
               howbuy();
               break;
          case GMENFND:
               prfmsg(SCNOMO,(efvda->flags&RDFROM ? "from" : "to"));
               break;
          default:
               prfmsg(READERR,rc);
               break;
          }
          outprf(usrnum);
          retmain();
          break;
     }
}

VOID
sescan(VOID)                       /* state: scanning E-mail               */
{
     CHAR c;

     switch (c=cncchr()) {
     case 'N':
          if (efvda->flags&THRING) {
               exithr();
               prfmsg(EXITHR);
               outprf(usrnum);
               efvda->tmpmid=efvda->curmid;
               getnear(GTLE,nocscn);
          }
          else {
               getnext(nxtscn);
          }
          break;
     case 'P':
          if (efvda->flags&THRING) {
               exithr();
               prfmsg(EXITHR);
               outprf(usrnum);
               efvda->tmpmid=efvda->curmid;
               getnear(LTGE,nocscp);
          }
          else {
               getprev(prvscn);
          }
          break;
     case '#':
          gostt(GONUM);
          break;
     case 'R':
          if (!(efvda->cflags&NOCUR)) {
               readit();
          }
          else {
               errhlp(EMLHUH,usrptr->substt);
          }
          break;
     default:
          if (msg->forum == EMLID) {
               errhlp(EMLHUH,usrptr->substt);
          }
          else {
               switch (c) {
               case 'T':
                    gostt(THRFBP);
                    break;
               case 'L':
                    if (efvda->flags&THRING) {
                         exithr();
                         prfmsg(EXITHR);
                         outprf(usrnum);
                         efvda->tmpmid=efvda->curmid;
                         efvda->flags|=JUMPED;
                         getnear(GELT,goscan);
                    }
                    else {
                         errhlp(EMLHUH,usrptr->substt);
                    }
                    break;
               case 'D':
                    if (dnldok(msg->forum)) {
                         efdnload(edndone);
                    }
                    else {
                         errhlp(EMLHUH,usrptr->substt);
                    }
                    break;
               case '?':
                    errhlp(FSCHLP,usrptr->substt);
                    break;
               default:
                    errhlp(EMLHUH,usrptr->substt);
                    break;
               }
          }
          break;
     }
}

static VOID
sthrfbp(VOID)                      /* state: thread fwd/backwd/parent      */
{
     switch (cncchr()) {
     case 'F':
          entrthr();
          getnext(nxtscn);
          break;
     case 'B':
          entrthr();
          getprev(prvscn);
          break;
     case 'P':
          entrthr();
          getprnt(thrprnt);
          break;
     case '?':
          errhlp(FBPHLP,usrptr->substt);
          break;
     default:
          errhlp(EMLHUH,usrptr->substt);
          break;
     }
}

static VOID
thrprnt(                           /* read after finding parent message    */
SHORT rc)                          /*   GME read code                      */
{
     switch (rc) {
     case GMEOK:
          scan();
          break;
     case GMENFND:
          cycall();
          prfmsg(NOPRNT);
          gordstt();
          break;
     default:
          clsgmerq(efwork);
          cycall();
          if (rc == GMECRD) {
               prfmsg(FNRDCRD);
               howbuy();
          }
          else {
               prfmsg(READERR,rc);
          }
          outprf(usrnum);
          retmain();
          break;
     }
}

static VOID
entrthr(VOID)                      /* start threading                      */
{
     if (efvda->prethr == 0L) {
          forctx(efwork,msg->forum,FSQTHR);
          efvda->prethr=efvda->curmid;
          efvda->flags|=THRING;
     }
}

static VOID
exithr(VOID)                       /* restore stuff after threading        */
{
     if (efvda->prethr != 0L) {
          forctx(efwork,EMLID,ESQTOU);
          efvda->curmid=efvda->prethr;
          efvda->prethr=0L;
          msgctx(efwork,efvda->curmid);
          efvda->flags&=~THRING;
     }
}

static VOID
readit(VOID)                       /* read current message (etc.)          */
{
     xmtext(emarkrd);
}

VOID
emarkrd(                           /* start up mark-read process           */
SHORT rc)                          /*   (not used, for compatibility)      */
{
     (VOID)rc;
     markoff(emrkdone);
}

VOID
emrkdone(                          /* finished marking msg, continue read  */
SHORT rc)                          /*   result code from GME               */
{
     switch (rc) {
     case GMEAFWD:
          prfmsg(RRRGEN);
          outprf(usrnum);
          rrgnot(gmexinf());
          break;
     case GMERRG:
          prfmsg(RRRGEN);
          outprf(usrnum);
          if (rrgnot(msg->from)) {
               prfmsg(SRRRD,msg->from);
               outprf(usrnum);
          }
          break;
     case GMEOK:
          break;
     default:
          clsgmerq(efwork);
          cycall();
          prfmsg(MARKERR,rc);
          outprf(usrnum);
          retmain();
          return;
     }
     clrprf();
     chkatt();
}

static VOID
chkatt(VOID)                       /* handle file attachment (if any)      */
{
     const struct fordef *tmpdef;

     if (msg->flags&FILATT) {
          if (fnd1st(&effb,dlname(msg),0)) {
               efvda->attsiz=effb.ff_fsize;
               if (msg->forum == EMLID) {
                    ASSERT(msg->flags&FILAPV);
                    if (tstcrd(edachg+edkchg*(effb.ff_fsize/1024))) {
                         gostt(DLNOW);
                    }
                    else {
                         prfmsg(ATTCRD);
                         howbuy();
                         gordstt();
                    }
               }
               else if (dnldok(msg->forum)) {
                    tmpdef=getdefp(msg->forum);
                    if (tstcrd(tmpdef->chgadl
                              +tmpdef->chgdpk*(effb.ff_fsize/1024))) {
                         if (!(msg->flags&FILAPV)) {
                              prfmsg(ATTNAP);
                         }
                         gostt(DLNOW);
                    }
                    else {
                         prfmsg(ATTCRD);
                         howbuy();
                         gordstt();
                    }
               }
               else if (msg->flags&FILAPV) {
                    prfmsg(FBNODL);
                    gordstt();
               }
               else {
                    prfmsg(ATTNAP);
                    gordstt();
               }
          }
          else {
               prfmsg(ATTNF,l2as(msg->msgid));
               gordstt();
          }
     }
     else {
          gordstt();
     }
}

VOID
edndone(                           /* finished with E-mail download        */
SHORT rc)                          /*   (not used, for compatibility)      */
{
     (VOID)rc;
     gordstt();
}

static VOID
gordstt(VOID)                      /* display appropriate post-read prompt */
{
     if (msg->forum == EMLID) {
          if (efvda->flags&RDFROM) {
               gostt(ERDFR);
          }
          else {
               gostt(ERDTO);
          }
     }
     else {
          if (efvda->flags&THRING) {
               gostt(FTREAD);
          }
          else {
               if (foracc(msg->forum) >= OPAXES) {
                    gostt(EFOREAD);
               }
               else {
                    gostt(EFREAD);
               }
          }
     }
}

VOID
seread(VOID)                       /* state: E-mail post-read message      */
{
     switch (cncchr()) {
     case 'R':
          if (msg->forum != EMLID || tooptok()) {
               valrpl(msg->forum);
          }
          else {
               errhlp(EMLHUH,usrptr->substt);
          }
          break;
     case 'M':
          if (msg->forum == EMLID && froptok()) {
               if (msg->flags&NOMOD) {
                    errhlp(NMODMS,usrptr->substt);
               }
               else if ((msg->flags&ISMPTR) && !(msg->flags&ISTCPY)) {
                    errhlp(NMODHDR,usrptr->substt);
               }
               else if (chkcfl(efwork)) {
                    errhlp(USING,usrptr->substt);
               }
               else {
                    startmod(emddone);
               }
          }
          else {
               errhlp(EMLHUH,usrptr->substt);
          }
          break;
     case 'E':
          if (msg->forum == EMLID) {
               deletem(edldone);
          }
          else {
            valrpl(EMLID);
          }
          break;
     case 'F':
          if (msg->forum != EMLID && foracc(msg->forum) >= OPAXES) {
               gfoprdst();
          }
          else if (msg->forum == EMLID && tooptok()) {
               if (chkcfl(efwork)) {
                    errhlp(USING,usrptr->substt);
               }
               else {
                    gostt(WHOFWD);
               }
          }
          else {
               errhlp(EMLHUH,usrptr->substt);
          }
          break;
     case 'C':
          if (msg->forum == EMLID) {
               gostt(WHOCPY);
          }
          else {
               deletem(edldone);
          }
          break;
     case 'B':
          if (msg->forum == EMLID && tooptok()) {
               getprnt(btdone);
          }
          else {
               errhlp(EMLHUH,usrptr->substt);
          }
          break;
     case 'T':
          if (msg->forum == EMLID) {
               errhlp(EMLHUH,usrptr->substt);
          }
          else {
               gostt(THRFBP);
          }
          break;
     case 'L':
          if (efvda->flags&THRING) {
               exithr();
               prfmsg(EXITHR);
               outprf(usrnum);
               efvda->tmpmid=efvda->curmid;
               efvda->flags|=JUMPED;
               getnear(GELT,goscan);
          }
          else {
               errhlp(EMLHUH,usrptr->substt);
          }
          break;
     case 'N':
          if (efvda->flags&THRING) {
               exithr();
               prfmsg(EXITHR);
               outprf(usrnum);
               efvda->tmpmid=efvda->curmid;
               getnear(GTLE,nocscn);
          }
          else {
               getnext(nxtscn);
          }
          break;
     case 'P':
          if (efvda->flags&THRING) {
               exithr();
               prfmsg(EXITHR);
               outprf(usrnum);
               efvda->tmpmid=efvda->curmid;
               getnear(LTGE,nocscp);
          }
          else {
               getprev(prvscn);
          }
          break;
     case '#':
          gostt(GONUM);
          break;
     case '?':
          if (msg->forum != EMLID) {
               errhlp(FRDHLP,usrptr->substt);
          }
          else if (tooptok()) {
               errhlp(ERDTHLP,usrptr->substt);
          }
          else {
               errhlp(ERDFHLP,usrptr->substt);
          }
          break;
     default:
          errhlp(EMLHUH,usrptr->substt);
          break;
     }
}

VOID
jumpto(VOID)                       /* "jump" to message                    */
{
     efvda->flags|=JUMPED;
     msgctx(efwork,efvda->tmpmid);
     getnear(LEGT,goscan);
}

VOID
btdone(                            /* backtrack read-parent operation done */
SHORT rc)                          /*   result from read operation         */
{
     switch (rc) {
     case GMEOK:
          efvda->cflags&=~NOCUR;
          if (cb4hdr) {
               prf("\x0C");
          }
          sumams(SUMMSG,msg);
          outprf(usrnum);
          xmtext(btxdone);
          break;
     case GMECRD:
     case GMENFND:
          cycall();
          prfmsg(NOPRNT);
          if (rc == GMECRD) {
               howbuy();
          }
          gordstt();
          break;
     default:
          clsgmerq(efwork);
          cycall();
          prfmsg(READERR,rc);
          outprf(usrnum);
          retmain();
          break;
     }
}

VOID
btxdone(                           /* done transmitting backtrack message  */
SHORT rc)                          /*   (not used, for compatibility)      */
{
     (VOID)rc;
     msgctx(efwork,efvda->curmid);
     reget(btodone);
}

VOID
btodone(                           /* done reget original after backtrack  */
SHORT rc)                          /*   read result code                   */
{
     switch (rc) {
     case GMEOK:
          gostt(ERDPAR);
          break;
     default:
          clsgmerq(efwork);
          cycall();
          prfmsg(READERR,rc);
          outprf(usrnum);
          retmain();
          break;
     }
}

GBOOL
tooptok(VOID)                      /* reading-E-mail-to-user options OK    */
{
     return(!(efvda->flags&RDFROM));
}

GBOOL
froptok(VOID)                      /* reading-E-mail-from-user options OK  */
{
     return((efvda->flags&RDFROM) != 0);
}

static VOID
valrpl(                            /* validate reply                       */
USHORT forum)                      /*   to this forum                      */
{
     switch (valadr(efwork,usaptr->userid,msg->from,forum)) {
     case VALYES:
          if (islocal(msg->from) && !sameas(msg->from,(CHAR *)gmeEmlSysUID())
           && ((struct usracc *)accbb->data)->credat > msg->crdate) {
               errhlp(UIDGON,usrptr->substt);
          }
          else {
               msg->forum=forum;
               msg->flags=0L;
               startrpl(erdone);
          }
          break;
     case VALNO:
          if (islocal(msg->from)) {
               errhlp(UIDGON,usrptr->substt);
          }
          else {
               errhlp(RNOTAVL,usrptr->substt);
          }
          break;
     case VALACC:
          errhlp(NOWACC,usrptr->substt);
          break;
     case VALCRD:
          cncall();
          prfmsg(NOWCRD);
          howbuy();
          gostt(usrptr->substt);
          break;
     default:
          ASSERT(FALSE);
     }
}

VOID
erdone(                            /* done replying to E-mail message      */
SHORT rc)                          /*   was edit aborted?                  */
{
     if (!rc) {
          inigmerq(efwork);
     }
     if (efvda->flags&THRING) {
          prfmsg(EXITHR);
          exithr();
     }
     inormrd(efwork,usaptr->userid,EMLID,efvda->curmid);
     getnear(GTLE,nocscn);
}

VOID
emddone(                           /* done modifying E-mail message        */
SHORT rc)                          /*   GME result code                    */
{
     switch (rc) {
     case GMEAGAIN:                /* user aborted edit                    */
          break;
     case GMEOK:
          prfmsg(SENTOK,l2as(efvda->curmid));
          outprf(usrnum);
          break;
     case GMEUSE:
          prfmsg(USING);
          outprf(usrnum);
          break;
     default:
          prfmsg(MODERR,rc);
          outprf(usrnum);
          break;
     }
     getnext(nxtscn);
}

VOID
edldone(                           /* done deleting E-mail message to      */
SHORT rc)                          /*   GME result code                    */
{
     switch (rc) {
     case GMEOK:
          prfmsg(OKGONE,l2as(efvda->curmid));
          outprf(usrnum);
          break;
     case GMENDEL:
          cycall();
          prfmsg(NDELMS);
          break;
     case GMEUSE:
          prfmsg(USING);
          outprf(usrnum);
          break;
     default:
          cycall();
          prfmsg(DELERR,rc);
          break;
     }
     forctx(efwork,EMLID,efvda->flags&RDFROM ? ESQFRU : ESQTOU);
     getnear(GTLE,nocscn);
}

VOID
swhofwd(VOID)                      /* state: to whom to forward message    */
{
     CHAR tmpadr[MAXADR];

     efvda->flags&=~RAFIPG;
     if (margc > 1 && sameas(margv[margc-1],"r")) {
          margn[margc-2][0]='\0';
          efvda->flags|=RAFIPG;
     }
     stlcpy(tmpadr,cncall(),MAXADR);
     if (sameas(tmpadr,"?")) {
          clrxrf();
          cfhlp();
          gostt(usrptr->substt);
          return;
     }
     if (sameas(tmpadr,"/?")) {
          clrxrf();
          listfor(usrptr->substt);
          return;
     }
     if (isdlst(tmpadr)) {
          clrxrf();
          errhlp(NCFLST,usrptr->substt);
          return;
     }
     if (islocal(tmpadr)) {
          switch (hdluid(tmpadr)) {
          case UIDFND:
               stlcpy(tmpadr,uidxrf.userid,MAXADR);
               break;
          case UIDPMT:
               gostt(usrptr->substt);
               return;
          case UIDCAL:
               return;
          default:
               ASSERT(FALSE);
          }
     }
     clrxrf();
     startfwd(tmpadr);
}

VOID
startfwd(                          /* start forwarding process (if able)   */
CHAR *to)                          /*   address to forward to              */
{
     if (isforum(to)) {
          msg->flags&=~PRIMSG;
     }
     switch (vfwdadr(efwork,usaptr->userid,to,EMLID)) {
     case VALYES:
          break;
     case VALNO:
          errhlp(CFNSUCH,usrptr->substt);
          return;
     case VALACC:
          errhlp(CFNOAC,usrptr->substt);
          return;
     case VALCRD:
          cncall();
          prfmsg(CFNCRD);
          howbuy();
          gostt(usrptr->substt);
          return;
     default:
          ASSERT(FALSE);
     }
     if (msg->flags&FILATT) {
          switch (vfwdatt(efwork,usaptr->userid,to,EMLID)) {
          case VALYES:
               break;
          case VALNO:
          case VALACC:
               if (isforum(to)) {
                    errhlp(CFNUPL,usrptr->substt);
               }
               else {
                    errhlp(CFNOAC,usrptr->substt);
               }
               return;
          case VALCRD:
               cncall();
               prfmsg(CFNCRD);
               howbuy();
               gostt(usrptr->substt);
               return;
          default:
               ASSERT(FALSE);
          }
     }
     if (msg->flags&PRIMSG) {
          switch (vfwdpri(efwork,usaptr->userid,to,EMLID)) {
          case VALYES:
               break;
          case VALNO:
          case VALACC:
               msg->flags&=~PRIMSG;
               break;
          case VALCRD:
               cncall();
               prfmsg(CFNCRD);
               howbuy();
               gostt(usrptr->substt);
               return;
          default:
               ASSERT(FALSE);
          }
     }
     ASSERT(!(msg->flags&RECREQ));
     if (efvda->flags&RAFIPG) {
          efvda->tmpfid=msg->forum;
          efvda->tmpmid=msg->thrid;
          stlcpy(filatt,msg->history,HSTSIZ);
          prfmsg(RPLAFW);
          outprf(usrnum);
          clrprf();
     }
     msg->forum=EMLID;
     stlcpy(msg->to,to,MAXADR);
     comment(efcdone);
}

VOID
efcdone(                           /* E-mail done adding comments when fwd */
SHORT rc)                          /*   TRUE if user aborted edit          */
{
     usrptr->state=emlstate;
     if (rc) {
          forctx(efwork,EMLID,efvda->flags&RDFROM ? ESQFRU : ESQTOU);
          getnear(GTLE,nocscn);
     }
     else {
          fwdit(efwdone);
     }
}

VOID
efwdone(                           /* E-mail done forwarding               */
SHORT rc)                          /*   result code from forward           */
{
     switch (rc) {
     case GMEAFWD:
     case GMEOK:
          fnotify(rc);
          break;
     case GMEUSE:
          prfmsg(USING);
          outprf(usrnum);
          break;
     case GMEACC:
          prfmsg(CFNOAC);
          outprf(usrnum);
          break;
     case GMECRD:
          prfmsg(CFNCRD);
          howbuy();
          outprf(usrnum);
          break;
     default:
          prfmsg(FWDERR,rc);
          outprf(usrnum);
          break;
     }
     forctx(efwork,EMLID,efvda->flags&RDFROM ? ESQFRU : ESQTOU);
     clrprf();
     if (efvda->flags&RAFIPG) {
          efvda->flags&=~RAFIPG;
          msg->forum=efvda->tmpfid;
          msg->thrid=efvda->tmpmid;
          stlcpy(msg->history,filatt,HSTSIZ);
          usrptr->substt=RAFABT;
       valrpl(msg->forum);
     }
     else {
          getnear(GTLE,nocscn);
     }
}

VOID
srafabt(VOID)                      /* state: reply-after-forward aborted   */
{
     cncall();
     getnear(GTLE,nocscn);
}

VOID
swhocpy(VOID)                      /* state: to whom to copy message       */
{
     CHAR tmpadr[MAXADR];

     stlcpy(tmpadr,cncall(),MAXADR);
     if (sameas(tmpadr,"?")) {
          clrxrf();
          cfhlp();
          gostt(usrptr->substt);
          return;
     }
     if (sameas(tmpadr,"/?")) {
          clrxrf();
          listfor(usrptr->substt);
          return;
     }
     if (isdlst(tmpadr)) {
          clrxrf();
          errhlp(NCFLST,usrptr->substt);
          return;
     }
     if (islocal(tmpadr)) {
          switch (hdluid(tmpadr)) {
          case UIDFND:
               stlcpy(tmpadr,uidxrf.userid,MAXADR);
               break;
          case UIDPMT:
               gostt(usrptr->substt);
               return;
          case UIDCAL:
               return;
          default:
               ASSERT(FALSE);
          }
     }
     clrxrf();
     startcpy(tmpadr);
}

VOID
startcpy(                          /* start copying process (if able)      */
CHAR *to)                          /*   address to forward to              */
{
     if (isforum(to)) {
          msg->flags&=~PRIMSG;
     }
     switch (valadr(efwork,usaptr->userid,to,EMLID)) {
     case VALYES:
          break;
     case VALNO:
          errhlp(CFNSUCH,usrptr->substt);
          return;
     case VALACC:
          errhlp(CFNOAC,usrptr->substt);
          return;
     case VALCRD:
          cncall();
          prfmsg(CFNCRD);
          howbuy();
          gostt(usrptr->substt);
          return;
     default:
          ASSERT(FALSE);
     }
     if (msg->flags&FILATT) {
          switch (valatt(efwork,usaptr->userid,to,EMLID)) {
          case VALYES:
               break;
          case VALNO:
          case VALACC:
               if (isforum(to)) {
                    errhlp(CFNUPL,usrptr->substt);
               }
               else {
                    errhlp(CFNOAC,usrptr->substt);
               }
               return;
          case VALCRD:
               cncall();
               prfmsg(CFNCRD);
               howbuy();
               gostt(usrptr->substt);
               return;
          default:
               ASSERT(FALSE);
          }
     }
     if (msg->flags&PRIMSG) {
          switch (valpri(efwork,usaptr->userid,to,EMLID)) {
          case VALYES:
               break;
          case VALNO:
          case VALACC:
               msg->flags&=~PRIMSG;
               break;
          case VALCRD:
               cncall();
               prfmsg(CFNCRD);
               howbuy();
               gostt(usrptr->substt);
               return;
          default:
               ASSERT(FALSE);
          }
     }
     if (msg->flags&RECREQ) {
          ASSERT(froptok() && !tooptok());
          switch (valrrr(efwork,usaptr->userid,to,EMLID)) {
          case VALYES:
               break;
          case VALNO:
          case VALACC:
               msg->flags&=~RECREQ;
               break;
          case VALCRD:
               cncall();
               prfmsg(CFNCRD);
               howbuy();
               gostt(usrptr->substt);
               return;
          default:
               ASSERT(FALSE);
          }
     }
     efvda->tmpmid=msg->msgid;
     msg->forum=EMLID;
     stlcpy(msg->to,to,MAXADR);
     comment(eccdone);
}

VOID
eccdone(                           /* E-mail done adding comments when cpy */
SHORT rc)                          /*   TRUE if user aborted edit          */
{
     usrptr->state=emlstate;
     if (rc) {
          getnear(GTLE,nocscn);
     }
     else {
          copyit(ecpdone);
     }
}

VOID
ecpdone(                           /* E-mail done copying                  */
SHORT rc)                          /*   result code from copy              */
{
     switch (rc) {
     case GMEAFWD:
     case GMEOK:
          cnotify(rc);
          break;
     case GMEACC:
          prfmsg(CFNOAC);
          outprf(usrnum);
          break;
     case GMECRD:
          prfmsg(CFNCRD);
          howbuy();
          outprf(usrnum);
          break;
     default:
          prfmsg(COPYERR,rc);
          outprf(usrnum);
          break;
     }
     clrprf();
     getnear(GTLE,nocscn);
}

VOID
seforop(VOID)                      /* state: forum-op post-read options    */
{
     switch (cncchr()) {
     case 'A':
          if ((msg->flags&FILATT) && !(msg->flags&FILAPV)) {
               if (aprvmsg(efwork,msg,msgtxt,TRUE) == GMEOK) {
                    prfmsg(APVCNF);
               }
               gordstt();
          }
          else {
               errhlp(EMLHUH,usrptr->substt);
          }
          break;
     case 'F':
          if (chkcfl(efwork)) {
               errhlp(USING,usrptr->substt);
          }
          else {
               forctx(efwork,msg->forum,FSQFOR);
               gostt(WHOFWD);
          }
          break;
     case 'C':
          gostt(WHOCPY);
          break;
     case 'T':
          if (msg->flags&EXEMPT) {
               errhlp(EMLHUH,usrptr->substt);
          }
          else {
               if (exmtmsg(efwork,msg,msgtxt,TRUE) == GMEOK) {
                    prfmsg(XMPCNF);
               }
               gordstt();
          }
          break;
     case 'U':
          if (msg->flags&EXEMPT) {
               if (exmtmsg(efwork,msg,msgtxt,FALSE) == GMEOK) {
                    prfmsg(UXMCNF);
               }
               gordstt();
          }
          else {
               errhlp(EMLHUH,usrptr->substt);
          }
          break;
     case 'E':
          forctx(efwork,msg->forum,FSQFOR);
          deletem(edldone);
          break;
     case 'M':
          if (chkcfl(efwork)) {
               errhlp(USING,usrptr->substt);
          }
          else {
               startmod(emddone);
          }
          break;
     case 'N':
          getnext(nxtscn);
          break;
     case 'P':
          getprev(prvscn);
          break;
     case '#':
          gostt(GONUM);
          break;
     case '?':
          errhlp(FOPRDH,usrptr->substt);
          break;
     default:
          errhlp(EMLHUH,usrptr->substt);
          break;
     }
}

VOID
sewhoto(VOID)                      /* state: to whom to write E-mail       */
{
     stlcpy(msg->to,cncall(),MAXADR);
     if (sameas(msg->to,"?")) {
          clrxrf();
          wrthlp();
          gostt(EWRTTO);
          return;
     }
     if (sameas(msg->to,"/?")) {
          clrxrf();
          listfor(usrptr->substt);
          return;
     }
     if (sameas(msg->to,"@?")) {
          clrxrf();
          wrtlst();
          return;
     }
     if (sameas(msg->to,".")) {
          strcpy(msg->to,gmeEmlSysUID());
     }
     else if (islocal(msg->to)) {
          switch (hdluid(msg->to)) {
          case UIDFND:
               stlcpy(msg->to,uidxrf.userid,MAXADR);
               break;
          case UIDPMT:
               gostt(EWRTTO);
               return;
          case UIDCAL:
               return;
          default:
               ASSERT(FALSE);
          }
     }
     clrxrf();
     switch (valadr(efwork,msg->from,msg->to,EMLID)) {
     case VALYES:
          startwrt(esndone);
          break;
     case VALNO:
          errhlp(NOSUCH,EWRTTO);
          break;
     case VALACC:
          errhlp(NOWACC,EWRTTO);
          break;
     case VALCRD:
          cncall();
          prfmsg(NOWCRD);
          howbuy();
          gostt(usrptr->substt);
          break;
     default:
          ASSERT(FALSE);
     }
}

VOID
wrtlst(VOID)                       /* list dist lists user can write to    */
{
     efvda->savstt=usrptr->substt;
     prfmsg(ESLAVL);
     if (haskey(qikkey)) {
          prfmsg(WELST,"!QUICK");
     }
     if (haskey(massky)) {
          prfmsg(WELST,"!MASS");
     }
     outprf(usrnum);
     strcpy(efvda->tmpadr,"@");
     startlst(wlstl,wlstd);
}

GBOOL
wlstl(VOID)                        /* show a dist list user can write to   */
{
     SHORT tmpchg;
     CHAR tmpkey[KEYSIZ];

     switch (nxtslst(efvda->tmpadr,tmpkey,&tmpchg)) {
     case GMEOK:
          if (haskey(emlkey) && haskey(tmpkey)) {
               prfmsg(WELST,efvda->tmpadr);
          }
          else {
               clrprf();
          }
          break;
     case GMENFND:
          return(FALSE);
     }
     return(TRUE);
}

VOID
wlstd(                             /* done listing lists user can write to */
SHORT rc)                          /*   (not used, for compatibility)      */
{
     (VOID)rc;
     prfmsg(WELTLR);
     gostt(efvda->savstt);
}

VOID
esndone(                           /* done writing an E-mail message       */
SHORT rc)                          /*   was edit aborted?                  */
{
     if (rc) {
          clsgmerq(efwork);
     }
     retmain();
}

static VOID
smodwht(VOID)                      /* state: what message to modify?       */
{
     if (isdigit(morcnc())) {
          inigmerq(efwork);
          efvda->tmpmid=cnclon();
          cncall();
          if (efvda->tmpmid > 0L) {
               inormrd(efwork,usaptr->userid,EMLID,efvda->tmpmid);
               seqctx(efwork,ESQFRU);
               if (chkcfl(efwork)) {
                    clsgmerq(efwork);
                    prfmsg(USING);
                    outprf(usrnum);
                    retmain();
               }
               else {
                    reget(get4mod);
               }
          }
          else {
               clsgmerq(efwork);
               prfmsg(UDONTO,l2as(efvda->tmpmid));
               outprf(usrnum);
               retmain();
          }
     }
     else {
          errhlp(EMLHUH,usrptr->substt);
     }
}

static VOID
get4mod(                           /* main-menu get message to modify      */
SHORT rc)                          /*   GME result code                    */
{
     cycall();
     switch (rc) {
     case GMEOK:
          if (msg->flags&NOMOD) {
               prfmsg(NMODMS);
          }
          else if ((msg->flags&ISMPTR) && !(msg->flags&ISTCPY)) {
               prfmsg(NMODHDR);
          }
          else {
               efvda->curmid=msg->msgid;
               startmod(moddone);
               return;
          }
          break;
     case GMENFND:
          prfmsg(UDONTO,l2as(efvda->tmpmid));
          break;
     default:
          prfmsg(READERR,rc);
          break;
     }
     outprf(usrnum);
     clsgmerq(efwork);
     retmain();
}

static VOID
moddone(                           /* main-menu modify finished            */
SHORT rc)                          /*   GME result code                    */
{
     switch (rc) {
     case GMEAGAIN:                /* user aborted edit                    */
          prf("");
          break;
     case GMEOK:
          prfmsg(SENTOK,l2as(efvda->curmid));
          break;
     case GMEUSE:
          prfmsg(USING);
          break;
     default:
          prfmsg(MODERR,rc);
          break;
     }
     outprf(usrnum);
     clsgmerq(efwork);
     retmain();
}

static VOID
sdelmsn(VOID)                      /* state: what message to delete?       */
{
     if (isdigit(morcnc())) {
          inigmerq(efwork);
          efvda->curmid=cnclon();
          cncall();
          if (efvda->curmid > 0L) {
               inormrd(efwork,usaptr->userid,EMLID,efvda->curmid);
               deletem(deldone);
          }
          else {
               clsgmerq(efwork);
               prfmsg(UCANTD,l2as(efvda->curmid));
               outprf(usrnum);
               retmain();
          }
     }
     else {
          errhlp(EMLHUH,usrptr->substt);
     }
}

static VOID
deldone(                           /* main-menu delete finished            */
SHORT rc)                          /*   GME result code                    */
{
     switch (rc) {
     case GMEOK:
          prfmsg(OKGONE,l2as(efvda->curmid));
          break;
     case GMENDEL:
          prfmsg(NDELMS);
          break;
     case GMENFND:
          prfmsg(UCANTD,l2as(efvda->curmid));
          break;
     case GMEUSE:
          prfmsg(USING);
          break;
     default:
          prfmsg(DELERR,rc);
          break;
     }
     outprf(usrnum);
     clsgmerq(efwork);
     retmain();
}

VOID
gspecfn(VOID)                      /* go to: special functions menu        */
{
     if (haskey(qikkey) || haskey(edstky)) {
          gostt(LSPECFN);
     }
     else {
          gostt(SPECFN);
     }
}

VOID
gspecfs(VOID)                      /* go to: special functions short menu  */
{
     if (haskey(qikkey) || haskey(edstky)) {
          gostt(LSPECFS);
     }
     else {
          gostt(SPECFS);
     }
}

VOID
dspchlp(VOID)                      /* display: help on special functions   */
{
     if (haskey(qikkey) || haskey(edstky)) {
          prfmsg(LSPCHLP);
     }
     else {
          prfmsg(SPCHLP);
     }
}

VOID
sspecfn(VOID)                      /* state: special functions menu        */
{
     switch (cncchr()) {
     case 'A':
          if (*qsptr->fwdee == '\0') {
               gostt(ENTFWD);
          }
          else {
               prfmsg(CFWEXP,qsptr->fwdee);
               gostt(CHGFWD);
          }
          break;
     case 'S':
          gostt(SETPRF);
          break;
     case '?':
          cncall();
          if (usrptr->substt == SPECFN || usrptr->substt == LSPECFN) {
               dspchlp();
          }
          gspecfn();
          break;
     case 'C':
          if (haskey(edstky)) {
               gostt(L2EDPMT);
               break;
          }
          else if (haskey(qikkey)) {
               gqikpmt();
               break;
          }
     default:
          errhlp(CNOTIL,usrptr->substt);
          break;
     }
}

VOID
sentfwd(VOID)                 /* state: enter auto-forwardee               */
{
     stlcpy(msg->to,cncall(),MAXADR);
     if (*qsptr->fwdee != '\0'
      && sameas(msg->to,".")) {
          clrxrf();
          *msg->to='\0';
          prfmsg(FWDOFF);
          setafwd(msg->to);
          condex();
          gspecfs();
          return;
     }
     else if (sameas(msg->to,"?")) {
          clrxrf();
          if (*qsptr->fwdee != '\0') {
               prfmsg(CFWEXP,qsptr->fwdee);
          }
          prfmsg(EFWEXP);
          gostt(usrptr->substt);
          return;
     }
     else if (islocal(msg->to)) {
          switch (hdluid(msg->to)) {
          case UIDFND:
               stlcpy(msg->to,uidxrf.userid,MAXADR);
               break;
          case UIDPMT:
               gostt(usrptr->substt);
               return;
          case UIDCAL:
               return;
          default:
               ASSERT(FALSE);
          }
     }
     clrxrf();
     switch (setafwd(msg->to)) {
     case VALYES:
          prfmsg(FWDON,msg->to);
          condex();
          gspecfs();
          break;
     case VALNO:
          errhlp(NOAFWD,usrptr->substt);
          break;
     case VALACC:
          errhlp(NOWACC,usrptr->substt);
          break;
     default:
          ASSERT(FALSE);
     }
}

VOID
dsetprf(                           /* display: set preferences menu        */
INT pmt)                           /*   which menu to show (normal or help)*/
{
     prfmsg(pmt,
            anpstr(qsptr->flags,P4NEWM,GORTIN),
            ynstr(qsptr->flags,FORUM2),
            rmodstr(qsptr->flags,CMBHDR),
            anpstr(qsptr->flags,MSGQUO,ALWQUO),
            ynstr(qsptr->flags,CLARPL),
            anpstr(qsptr->flags,CFWCMT,ALWCMT));
}

VOID
ssetprf(VOID)                      /* state: set preferences menu          */
{
     switch (cncchr()) {
     case 'N':
          gostt(NEMPRF);
          break;
     case 'F':
          gostt(FMTPRF);
          break;
     case 'R':
          gostt(RMDPRF);
          break;
     case 'Q':
          gostt(QUOPRF);
          break;
     case 'C':
          gostt(CARPRF);
          break;
     case 'A':
          gostt(CMTPRF);
          break;
     case '?':
          cncall();
          errhlp(PRFHLP,usrptr->substt);
          return;
     default:
          errhlp(CNOTIL,SETPRF);
          return;
     }
     qsptr->flags|=USRSET;
}

VOID
snemprf(VOID)                      /* state: set read new E-mail pref      */
{
     switch (cncchr()) {
     case 'A':
          qsptr->flags|=(P4NEWM+GORTIN);
          gostt(SETPRF);
          break;
     case 'N':
          qsptr->flags&=~(P4NEWM+GORTIN);
          gostt(SETPRF);
          break;
     case 'P':
          qsptr->flags&=~GORTIN;
          qsptr->flags|=P4NEWM;
          gostt(SETPRF);
          break;
     case '?':
          errhlp(NEMHLP,NEMPRF);
          break;
     default:
          errhlp(CNOTIL,NEMPRF);
          break;
     }
}

VOID
sfmtprf(VOID)                      /* state: set forum mail in E-mail pref */
{
     switch (cncyesno()) {
     case 'Y':
          qsptr->flags|=FORUM2;
          gostt(SETPRF);
          break;
     case 'N':
          qsptr->flags&=~FORUM2;
          gostt(SETPRF);
          break;
     case '?':
          errhlp(FMTHLP,FMTPRF);
          break;
     default:
          errhlp(YORN,FMTPRF);
          break;
     }
}

VOID
srmdprf(VOID)                      /* state: set read mode preference      */
{
     switch (cncchr()) {
     case 'F':
          qsptr->flags|=CMBHDR;
          gostt(SETPRF);
          break;
     case 'B':
          qsptr->flags&=~CMBHDR;
          gostt(SETPRF);
          break;
     case '?':
          errhlp(RMDHLP,RMDPRF);
          break;
     default:
          errhlp(CNOTIL,RMDPRF);
          break;
     }
}

VOID
squoprf(VOID)                      /* state: set quoting preference        */
{
     switch (cncchr()) {
     case 'A':
          qsptr->flags|=(MSGQUO+ALWQUO);
          gostt(SETPRF);
          break;
     case 'N':
          qsptr->flags&=~(MSGQUO+ALWQUO);
          gostt(SETPRF);
          break;
     case 'P':
          qsptr->flags&=~ALWQUO;
          qsptr->flags|=MSGQUO;
          gostt(SETPRF);
          break;
     case '?':
          errhlp(QUOHLP,QUOPRF);
          break;
     default:
          errhlp(CNOTIL,QUOPRF);
          break;
     }
}

VOID
scarprf(VOID)                      /* state: set clear after reply pref    */
{
     switch (cncyesno()) {
     case 'Y':
          qsptr->flags|=CLARPL;
          gostt(SETPRF);
          break;
     case 'N':
          qsptr->flags&=~CLARPL;
          gostt(SETPRF);
          break;
     case '?':
          errhlp(CARHLP,CARPRF);
          break;
     default:
          errhlp(YORN,CARPRF);
          break;
     }
}

VOID
scmtprf(VOID)                      /* state: set copy/fwd comment pref     */
{
     switch (cncchr()) {
     case 'A':
          qsptr->flags|=(CFWCMT+ALWCMT);
          gostt(SETPRF);
          break;
     case 'N':
          qsptr->flags&=~(CFWCMT+ALWCMT);
          gostt(SETPRF);
          break;
     case 'P':
          qsptr->flags&=~ALWCMT;
          qsptr->flags|=CFWCMT;
          gostt(SETPRF);
          break;
     case '?':
          errhlp(CMTHLP,CMTPRF);
          break;
     default:
          errhlp(CNOTIL,CMTPRF);
          break;
     }
}

VOID
sl2edpmt(VOID)                     /* state: sysop dist list to edit       */
{
     SHORT rc;

     if (morcnc() == '?') {
          cncall();
          inigmerq(efwork);
          strcpy(efvda->tmpadr,"?");
          prfmsg(ESLHLP);
          startlst(eslstr,eslstd);
     }
     else if (morcnc() == '@') {
          stlcpy(efvda->tmpadr,strupr(cncwrd()),DLNMSZ);
          if (!valslnm(efvda->tmpadr)) {
               errhlp(BADLNM,usrptr->substt);
          }
          else if (dlstxst(efvda->tmpadr)) {
               inigmerq(efwork);
               switch (rc=edtslst(efwork,efvda->tmpadr)) {
               case GMEOK:
                    gostt(SYSENT);
                    break;
               case GMEUSE:
                    errhlp(LSTINU,usrptr->substt);
                    break;
               default:
                    prfmsg(EDLERR,rc);
                    condex();
                    gspecfs();
                    break;
               }
          }
          else {
               if (valslnm(efvda->tmpadr)) {
                    gostt(ACCLVK);
               }
               else {
                    errhlp(BADFLE,usrptr->substt);
               }
          }
     }
     else if (sameas(cncwrd(),"!QUICK")) {
          gqikpmt();
     }
     else {
          errhlp(BADLNM,usrptr->substt);
     }
}

GBOOL                              /*   returns FALSE if no more lists     */
eslstr(VOID)                       /* show next sysop list for lister      */
{
     SHORT tmpchg;
     CHAR tmpkey[KEYSIZ];

     switch (nxtslst(efvda->tmpadr,tmpkey,&tmpchg)) {
     case GMEOK:
          prfmsg(DLSTLIN,efvda->tmpadr,tmpkey,tmpchg);
          break;
     case GMENFND:
          return(FALSE);
     }
     return(TRUE);
}

VOID
eslstd(                            /* done listing sysop lists             */
SHORT rc)                          /*   (not used, for compatibility)      */
{
     (VOID)rc;
     prfmsg(DLSTTLR);
     clsgmerq(efwork);
     gostt(L2EDPMT);
}

VOID
sacclvk(VOID)                      /* state: what key for new sysop list   */
{
     CHAR tmpkey[KEYSIZ];

     stlcpy(tmpkey,strupr(cncwrd()),KEYSIZ);
     if (sameas(tmpkey,".")) {
          *tmpkey='\0';
     }
     else if (!keynam(tmpkey)) {
          errhlp(BADKYN,usrptr->substt);
          return;
     }
     stlcpy(&efvda->tmpadr[DLNMSZ],tmpkey,KEYSIZ);
     gostt(LSTCHG);
}

VOID
slstchg(VOID)                      /* state: what charge for new sysop list*/
{
     SHORT tmpchg;

     if (!isdigit(morcnc()) || (tmpchg=cncint()) > MAXLCH || tmpchg < MINLCH) {
          prfmsg(NUMRNG,MINLCH,MAXLCH);
          gostt(usrptr->substt);
     }
     else {
          inigmerq(efwork);
          switch (newslst(efwork,efvda->tmpadr,&efvda->tmpadr[DLNMSZ],tmpchg)) {
          case GMEOK:
               gostt(SYSENT);
               break;
          default:
               prfmsg(NOCRLST);
               condex();
               gspecfs();
               break;
          }
     }
}

VOID
ssysent(VOID)                      /* state: enter address for sysop list  */
{
     SHORT rc;

     if (morcnc() == '?') {
          cncall();
          if (rstlstp(efwork) == GMEOK) {
               prfmsg(SYSHDR,efvda->tmpadr);
               startlst(syslstr,syslstd);
          }
          else {
               gostt(usrptr->substt);
          }
     }
     else {
          switch (rc=addslst(efwork,cncall())) {
          case GMEOK:
               errhlp(OKAPND,usrptr->substt);
               break;
          default:
               clsgmerq(efwork);
               prfmsg(EDLERR,rc);
               condex();
               gspecfs();
               break;
          }
     }
}

GBOOL
syslstr(VOID)                      /* show next address in sysop list      */
{
     CHAR tmpadr[MAXADR];

     if (nxtsys(efwork,tmpadr)) {
          prfmsg(SYSADR,tmpadr);
          return(TRUE);
     }
     return(FALSE);
}

VOID
syslstd(                           /* done showing addresses in sysop list */
SHORT rc)                          /*   (not used, for compatibility)      */
{
     (VOID)rc;
     gostt(SYSENT);
}

VOID
gqikpmt(VOID)                      /* go to: editing !QUICK list           */
{
     getqik(qikbuf,usaptr->userid);
     if (anyqik(qikbuf)) {
          showqik(qikbuf);
     }
     else {
          prfmsg(QIKHLP);
     }
     gostt(QIKPMT);
}

VOID
sqikpmt(VOID)                      /* state: editing !QUICK list           */
{
     if (morcnc() == '?') {
          cncall();
          if (anyqik(qikbuf)) {
               showqik(qikbuf);
          }
          else {
               prfmsg(QIKHLP);
          }
          gostt(QIKPMT);
     }
     else if ((efvda->count=cncint()-1) < 0 || efvda->count >= MAXQIK) {
          cncall();
          prfmsg(INVNUM,MAXQIK);
          gostt(QIKPMT);
     }
     else {
          gostt(QIKEDT);
     }
}

VOID
sqikedt(VOID)                      /* state: enter address for slot #      */
{
     if (morcnc() == '?') {
          cncall();
          if (anyqik(qikbuf)) {
               showqik(qikbuf);
          }
          else {
               prfmsg(QIKHLP);
          }
          gostt(QIKPMT);
     }
     else if (morcnc() == '.') {
          cncchr();
          delqik(efvda->count,qikbuf);
          gostt(QIKPMT);
     }
     else {
          insqik(efvda->count,cncall(),qikbuf);
          gostt(QIKPMT);
     }
}

static VOID
retmain(VOID)                      /* return to main menu (safe for login) */
{
     efvda->curmid=0L;
     efvda->prethr=0L;
     efvda->flags&=~THRING;
     if (efvda->flags&LONIPG) {
          cycall();
          prfmsg(LONDUN);
          usrptr->substt=EMAINS;
          efvda->flags|=LONFIN;
          if (efvda->cflags&DIDCYC) {
               btuinj(usrnum,CRSTG);
          }
     }
     else {
          btulok(usrnum,FALSE);
          condex();
          gostt(EMAINS);
     }
}

GBOOL
anyqik(                            /* any entries in user's !QUICK list?   */
struct qikdat *qiklst)             /*   list to display                    */
{
     SHORT i;

     for (i=0 ; i < MAXQIK ; ++i) {
          if (qiklst->idx[i] != NOIDX) {
               return(TRUE);
          }
     }
     return(FALSE);
}

VOID
showqik(                           /* displaying a personal dist list      */
struct qikdat *qiklst)             /*   list to display                    */
{
     SHORT slot,lstidx;

     ASSERT(qiklst != NULL);
     prfmsg(QIKHDR);
     for (slot=0 ; slot < MAXQIK ; ++slot) {
          lstidx=qiklst->idx[slot];
          if (lstidx != NOIDX) {
               prfmsg(QIKENT,slot+1,&qiklst->list[lstidx]);
          }
     }
}

CHAR *
esystv(void)                     /* current Forum text variable          */
{
     return((CHAR *)gmeEmlSysUID());
}
