/***************************************************************************
 *                                                                         *
 *   REMSYS.C                                                              *
 *                                                                         *
 *   Copyright (c) 1987-1997 Galacticomm, Inc.    All Rights Reserved.     *
 *                                                                         *
 *   This is the Worldgroup Remote Sysop module.  In addition this module  *
 *   handles the creation and editing for the "Class" accounting system.   *
 *                                                                         *
 *                               - S. Brinker & R. Skurnick 3/29/91        *
 *                                                                         *
 *                               (based upon Functions and Utilities by    *
 *                                A. Von Gauss, R. Skurnick, & S. Brinker) *
 *                                                                         *
 *   added support for C/S Remote System Console                           *
 *                                                - Joe Delekto  1/10/96   *
 ***************************************************************************/

#include "gcomm.h"
#include "majorbbs.h"
#include "galrsy.h"
#include "remote.h"
#include "filexfer.h"
#include "gcsasys.h"

#define FILREV "$Revision: 17 $"

static VOID rsop35(VOID);
static VOID rsop71i1(VOID);
static VOID rsop71j2(VOID);
static VOID rsop71j3(VOID);
static VOID rsop71j4(VOID);
static VOID rsop71ja(VOID);
static VOID rsop71jv(VOID);
static VOID rsop71je(VOID);
static INT tshrem(INT tshcod);
static INT fuprnw(INT fupcode);
static INT fuprem(INT fupcod);
static VOID prfjdje(VOID);
static VOID remall(struct usracc *uacptr,INT onoff);
static VOID hdlbit(INT tbit);
static VOID flgmsg(INT tbit,INT sflag);
static VOID dspdir(VOID);
static INT ask4uid(INT on);
static INT chksfil(INT shut);
static VOID getfil(VOID);
static VOID lstuon(VOID);
static VOID sporf(VOID);
static VOID bgnaud(INT start);
static VOID getaud(VOID);
static VOID bgnads(VOID);
static VOID scnacc(VOID);
static VOID chkstg(CHAR *stg);
static VOID chkint(INT numb);
static VOID prfaxlin(struct usracc *uacptr,INT msg,INT b1,INT b2,INT b3,INT b4);
static INT axs4op(struct usracc *uacptr,INT op);
static VOID togaxs(struct usracc *uacptr,INT op);
static INT isvalop(CHAR *opstg);
static VOID chkkey(INT remove);
static VOID impkey(INT remove);
static CHAR *setdft(CHAR c);
static VOID dspkys(CHAR *keyr,INT ring);
static INT canedt(VOID);
static INT ok2poll(VOID);
static INT dnlmnu(INT on);
static VOID usercopy(CHAR *fromid,CHAR *toid);

INT rmsyst;

struct module remotesys={     /* module interface block               */
     "",                      /*    description for main menu         */
     NULL,                    /*    user logon supplemental routine   */
     account,                 /*    input routine if selected         */
     acsthn,                  /*    status-input routine if selected  */
     NULL,                    /*    "injoth" routine for this module  */
     NULL,                    /*    user logoff supplemental routine  */
     zaprsy,                  /*    hangup (lost carrier) routine     */
     NULL,                    /*    midnight cleanup routine          */
     NULL,                    /*    delete-account routine            */
     clsrsy                   /*    finish-up (sys shutdown) routine  */
};

IMPORT_VARIABLE(DFAFILE*) clsbb; /* Btrieve file block ptr for class data     */

HMCVFILE rsymb;               /* remote Sysop message file block handle    */

struct acclass *rclsptr;      /* single occurence of class element         */

#define EMUCHT      'C'       /* control-key used to toggle sysop chat     */
#define EMUZAP      'Z'       /* control-key used to zap emulated channel  */
#define EMUEXT      27        /* control-key used to exit emulation        */

INT rsykil=-1;                /* remote sysop event kill counter           */

static INT op;                /* global "op" number                        */

IMPORT_VARIABLE(INT) detflg;  /* shwusr(): called frm here, DETAIL cmd     */
IMPORT_VARIABLE(INT) errcod;  /* error code used for system shutdown       */

struct valop {
     CHAR *opname;
     INT msgstt;
     INT op;
} valops[]={
     {"SENDALL", RSOP11,11},
     {"SEND",    RSOP12,12},
     {"LOGON",   RSOP13,13},
     {"DETAIL",  RSOP22,22},
     {"AUDIT",   RSOP23,23},
     {"USERS",   RSOP24,24},
     {"SEARCH",  RSOP25Z,25},
     {"HANGUP",  RSOP31,31},
     {"SUSPEND", RSOP32,32},
     {"PROTECT",  RSOP33,33},
     {"DELETE",  RSOP34,34},
     {"SHUTDOWN",RSOP35,35},
     {"CLEANUP", RSOP36,36},
     {"SYSTATS", RSOP412,41},
     {"MODSTATS",RSOP422,42},
     {"DEMSTATS",RSOP43,43},
     {"CLSSTATS",RSOP442,44},
     {"EMULATE", RSOP51,51},
     {"MONITOR", RSOP52,52},
     {"INPUT",   RSOP53,53},
     {"CHANGE",  RSOP54,54},
#ifdef UNIX
     {"CAT",     RSOP61,61},
     {"CP",      RSOP62,62},
     {"MV",      RSOP63,63},
     {"LS",      RSOP64,64},
     {"MKDIR",   RSOP65,65},
     {"RMDIR",   RSOP66,66},
     {"RM",      RSOP67,67},
#else
     {"TYPE",    RSOP61,61},
     {"COPY",    RSOP62,62},
     {"RENAME",  RSOP63,63},
     {"DIR",     RSOP64,64},
     {"MD",      RSOP65,65},
     {"RD",      RSOP66,66},
     {"DEL",     RSOP67,67},
#endif
     {"ACCOUNT", RSOP71M0,71},
     {"TRANSFER",RSOP731,73},
     {"SYSOP",   RSOP99,99}
};

static INT xflags[]={IDLEXP,DAYEXP,NOCRED,HASCRD,DBTLMT};
static INT kilmins[]={1,2,5,10,0,-1,0};
static INT fflags[]={FSTMTH,MONDAY,NUMDAY,HITLMT};
static INT glthrv[5][3]={{0,1,0},{0,0,1},{1,0,0},{0,1,1},{1,1,0}};

VOID EXPORT
init__galrsy(VOID)                 /* initialize remote sysop module       */
{
     stzcpy(remotesys.descrp,gmdnam("galrsy.mdf"),MNMSIZ);
     rmsyst=register_module(&remotesys);
     rsymb=opnmsg("galrsy.mcv");                  /* allocate enough vda to*/
     dclvda(max(RINGSZ,sizeof(struct rsysop)));   /* import keyrings w/ tmp*/
     rclsptr=(struct acclass *)alcmem(sizeof(struct acclass));
     ntfysopr=ntfysop;
     inicsrsy();
}

VOID EXPORT
initwc__galrsy(VOID)
{
     init__galrsy();
}

static VOID
rsop35(VOID)                       /* remote shutdown                      */
{
     INT unum;

     op=cncint();
     if (op >= 1 && op <= 7) {
          if (op == 5) {
               kilipg=0;
               errcod=1;
               rsmode=NORMRS;
               unum=usrnum;
               prepff();
               kilctr=-1;
               curusr(unum);
               rsprom(RSSMNU);
          }
          else {
               rsyptr->rkilctr=kilmins[op-1];
               rsprom(RSOP35A);
          }
     }
     else {
          cncall();
          prfmsg(INVOPT);
          rsprom(RSOP35);
     }
}

static VOID
rsop71i1(VOID)                     /* editing a class                      */
{
     switch(cncchr()) {
     case 'N':
          rsprom(RSOP71H);
          break;
     case 'E':
          dfaSetBlk(clsbb);
          dfaGetEQ(rclsptr,rsyptr->cltptr->clname,0);
          rsyptr->flags|=EDTCLS;
          rsprom(RSOP71J1);
          break;
     case 'K':
          rsyptr->text[0]=RINGID;
          rsyptr->text[1]='\0';
          strcat(rsyptr->text,rsyptr->cltptr->clname);
          rsyptr->flags|=EDTKYR;
          prfmsg(ROP71JL1);
          rsprom(RSOP71JM);
          break;
     case 'D':
          rsprom(RSOP71I2);
          break;
     default:
          cncall();
          rsprom(RSOP71I1);
     }
}

static VOID
rsop71j2(VOID)
{
     if (sameto("Unl",nxtcmd)) {
          cncwrd();
          rclsptr->limday=-1;
          rclsptr->flags|=KCKOFF;
          if (rsyptr->flags&EDTCLS) {
               rclsptr->msgs[0][0]=rclsptr->nxtcls[0][0]='\0';
          }
          rclsptr->flags&=~CLSCHG;
          rsprom(ROP71J7A);
     }
     else if (isdigit(*nxtcmd) && (op=cncint()) >= 0 && op <= 1440) {
          rclsptr->limday=op;
          rsprom(RSOP71J3);
     }
     else {
          prfmsg(INVAMT);
          rsprom(RSOP71J2);
          cncall();
     }
}

static VOID
rsop71j3(VOID)
{
     if ((op=cncint()) > 0 && op < 3) {
          rclsptr->flags&=~(KCKOFF|CLSCHG);
          rclsptr->flags|=(op == 1 ? KCKOFF : CLSCHG);
          if (op == 1) {
               rclsptr->nxtcls[0][0]='\0';
               rclsptr->msgs[0][0]='\0';
               rsprom(ROP71J7A);
          }
          else {
               rsprom(RSOP71J4);
          }
     }
     else {
          prfmsg(INVAMT);
          rsprom(RSOP71J3);
          cncall();
     }
}

static VOID
rsop71j4(VOID)                     /* switching class if out of time today */
{
     if (morcnc() == '?') {
          cncall();
          dspcll();
          rsprom(RSOP71J4);
          return;
     }
     strcpy(rsyptr->text,cncall());
     if (namacls(rsyptr->text)) {
          strcpy(rclsptr->nxtcls[0],rsyptr->text);
          if (sameas(rsyptr->text,"DELETE_ACCOUNT")) {
               rclsptr->msgs[0][0]='\0';
               rsprom(ROP71J7A);
          }
          else if (fndcls(rsyptr->text) == NULL) {
               prfmsg(DELWRN,strupr(rsyptr->text));
               rsprom(RSOP71J5);
          }
          else {
               rsprom(RSOP71J5);
          }
     }
     else {
          prfmsg(INVKYR);
          rsprom(RSOP71J4);
     }
}

static VOID
rsop71ja(VOID)
{
     if ((op=cncint()) > 0 && op <= 5) {
          rclsptr->flags&=~(FSTMTH|MONDAY|NUMDAY|HITLMT);
          rclsptr->flags|=REPDBT;
          if (op != 3) {
               rclsptr->fgvday=0;
          }
          if (op < 5) {
               rclsptr->flags|=fflags[op-1];
               if (op == 3) {
                    rsprom(RSOP71JB);
               }
               else {
                    prfjdje();
               }
          }
          else {
               rclsptr->flags&=~REPDBT;
               prfjdje();
          }
     }
     else {
          prfmsg(INVAMT);
          rsprom(RSOP71JA);
     }
}

static VOID
rsop71jv(VOID)
{
     if (cncyesno() == 'Y') {
          if (rsyptr->flags&CRTCLS) {
               if (crtclass(rclsptr)) {
                    prfmsg(CLSCRT);
               }
               else {
                    dlkeys(rsyptr->text);
                    prfmsg(CLSNOG);
               }
          }
          else {
               movmem(rclsptr,rsyptr->cltptr,
                  sizeof(struct clstab)-sizeof(struct clstab *));
               dfaSetBlk(clsbb);
               dfaGetEQ(NULL,rclsptr->clname,0);
               dfaUpdate(rclsptr);
               prfmsg(CLSEDT);
          }
     }
     else {
          if (rsyptr->flags&CRTCLS) {
               dlkeys(rsyptr->text);
          }
     }
     rsyptr->flags&=~(CRTCLS|EDTCLS);
     rsprom(RSOP71H);
     cncall();
}

static VOID
rsop71je(VOID)
{
     op=morcnc();
     if (!isdigit(op) || (rsyptr->chan=op=cncint()) < 0
         || ((rclsptr->flags&CRDXMT) && op > 2)
         || ((rclsptr->dbtlmt == 0L && op > 4) || op > 5)) {
          cncall();
          prfmsg(INVAMT);
          rsprom(RSOP71JE);
          return;
     }
     else if (op == 0) {
          rsyptr->text[0]=RINGID;
          rsyptr->text[1]='\0';
          strcat(rsyptr->text,rclsptr->clname);
          if (rsyptr->flags&CRTCLS) {
               nkyrec(rsyptr->text);
          }
          prfmsg(RSOP71JL);
          rsprom(RSOP71JM);
          return;
     }
     else if (op == 3 && (rclsptr->flags&HASCRD)) {
          rsyptr->genctr=4;
          strcpy(rsyptr->sfname,"when users run out of credits");
          strcpy(rsyptr->dfname,"when users are posted credits");
     }
     else if (op == 3 && (rclsptr->flags&DBTLMT)) {
          rsyptr->genctr=5;
          strcpy(rsyptr->sfname,"when users run out of credits");
          strcpy(rsyptr->dfname,"when users reach their debt limit");
     }
     else if (op == 4 && (rclsptr->flags&NOCRED)) {
          rsyptr->genctr=3;
          strcpy(rsyptr->sfname,"when users are posted credits");
          strcpy(rsyptr->dfname,"when users run out of credits");
     }
     else if (op == 4 && (rclsptr->flags&DBTLMT)) {
          rsyptr->genctr=5;
          strcpy(rsyptr->sfname,"when users are posted credits");
          strcpy(rsyptr->dfname,"when users reach their debt limit");
     }
     else if (op == 5 && (rclsptr->flags&NOCRED)) {
          rsyptr->genctr=3;
          strcpy(rsyptr->sfname,"when users reach their debt limit");
          strcpy(rsyptr->dfname,"when users run out of credits");
     }
     else if (op == 5 && (rclsptr->flags&HASCRD)) {
          rsyptr->genctr=4;
          strcpy(rsyptr->sfname,"when users reach their debt limit");
          strcpy(rsyptr->dfname,"when users are posted credits");
     }
     else {
          rclsptr->flags|=xflags[op-1];
          rsprom(op == 1 ? RSOP71JG : op == 2 ?  RSOP71JH : RSOP71JI);
          return;
     }
     rsprom(RSOP71JK);
}

static INT
tshrem(INT tshcod)     /* Handle tagspecs for your remote sysop application */
{                    /* implicit inputs: ftgptr,usrnum,usrptr,usaptr,vdaptr */
                                  /* return value meaning depends on tshcod */
                             /* implicit input/output in many cases: tshmsg */
                                     /* expect caller to do outprf() if any */
     INT rc=0;
     FILE *fp;

     setmbk(rsymb);
     switch(tshcod) {
     case TSHDSC:                            /* Describe tagspec in English */
          sprintf(tshmsg,"file(s) \"%s\" for remote sysop use",
                         ftgptr->tagspc);
          break;
     case TSHVIS:                                  /* Visible to this user? */
          if (ftgptr->flags&FTGWLD) {
               rc=1;
          }
          else {
               strcpy(tshmsg,rsyptr->text);
               strcat(tshmsg,ftgptr->tagspc);
               if (sameas(ftgptr->tagspc,"wgsmenu2.dat")) {
                    strcpy(tshmsg,"");
                    rc=1;
               }
               else if ((fp=fopen(tshmsg,FOPRB)) != NULL) {
                    fread(tshmsg,1,TSHLEN,fp);
                    fclose(fp);
                    rc=1;
               }
          }
          break;
     case TSHSCN:             /* Scan of multi-file wildcard tagspec begins */
          strcpy(tshmsg,rsyptr->text);
          strcat(tshmsg,ftgptr->tagspc);
          if (fnd1st(&ftuptr->fb,tshmsg,0)) {
               strcpy(tshmsg,ftuptr->fb.ff_name);
               rc=1;
          }
          else {
               strcpy(tshmsg,"");                  /* clean up after myself */
          }
          break;
     case TSHNXT:                             /* Next file in wildcard scan */
          if (fndnxt(&ftuptr->fb)) {
               strcpy(tshmsg,ftuptr->fb.ff_name);
               rc=1;
          }
          break;
     case TSHBEG:              /* Begin download, check permission, reserve */
          if (sameas(ftgptr->tagspc,"wgsmenu2.dat")) {
               if (!dnlmnu(1)) {
                    sprintf(tshmsg,"Someone else is already downloading %s!",
                            fnmcse("wgsmenu2.dat"));
                    return(0);
               }
          }
          strcpy(tshmsg,rsyptr->text);
          strcat(tshmsg,ftgptr->tagspc);
          strcpy(ftfscb->fname,ftgptr->tagspc);
          rc=1;
          break;
     case TSHEND:             /* End complete download of a file, unreserve */
          break;
     case TSHSKP:                     /* Skip incomplete download of a file */
          break;
     case TSHFIN:                            /* Finish file tranfer session */
          dnlmnu(0);
          usrptr->state=rmsyst;
          rsprom(RSOP731);
          rc=1;
          break;
     case TSHHUP:                /* Finish session because user logging off */
          dnlmnu(0);
          break;
     }
     return(rc);
}

static INT
fuprnw(INT fupcode)              /* upload handler for replacing wgsmenu2.dat*/
{
     IMPORT_VARIABLE(DFAFILE*) mnubb;

     switch(fupcode) {
     case FUPBEG:
          if (ftfscb->fname[0] != '\0'
           && !sameas(ftfscb->fname,"wgsmenu2.dat")) {
               strcpy(ftfbuf,
                "The 'U' option is only for uploading WGSMENU2.DAT");
            return(0);
          }
          strcpy(ftfbuf,"newmenu.$$$");
          stzcpy(rsyptr->sfname,ftfbuf,FNDSIZE);
          return(1);
     case FUPEND:
          dfaClose(mnubb);
          unlink("wgsmenu2.dat");
          rename("newmenu.$$$","wgsmenu2.dat");
          mnubb=dfaOpen("wgsmenu2.dat",sizeof(struct mnupag),NULL);
          shocst("NEW WGSMENU2.DAT UPLOADED","Uploading user: %s",
                 uacoff(usrnum)->userid);
          ftfbuf[0]='\0';
          return(0);
     case FUPSKP:
          unlink("newmenu.$$$");
          return(0);
     }
     return(fuprem(fupcode));
}

static INT
fuprem(INT fupcod)              /* Handle uploads for the remote sysop      */
{                          /* implicit inputs:  usrnum,usrptr,usaptr,vdaptr */
                                  /* return value meaning depends on fupcod */
                             /* implicit input/output in many cases: fupmsg */
                                     /* expect caller to do outprf() if any */
     INT rc=0;

     setmbk(rsymb);
     switch(fupcod) {
     case FUPBEG:                /* Begin upload, check permission, reserve */
          strcpy(ftfbuf,rsyptr->text);
          if (rsyptr->text[100] != '\0') {
               strcat(ftfbuf,&rsyptr->text[100]);
          }
          else {
               strcat(ftfbuf,ftfscb->fname);
          }
          stzcpy(rsyptr->sfname,ftfbuf,FNDSIZE);
          rc=1;
          break;
     case FUPEND:               /* End complete upload of a file, unreserve */
          strcpy(ftfbuf,ftfscb->fname);
          rsyptr->sfname[0]='\0';
          break;
     case FUPSKP:                       /* Skip incomplete upload of a file */
          unlink(ftfscb->fname);
          rsyptr->sfname[0]='\0';
          break;
     case FUPFIN:                             /* Finish file upload session */
          usrptr->state=rmsyst;
          rsprom(RSOP731);
          rc=1;
          break;
     case FUPHUP:                /* Finish session because user logging off */
          break;
     }
     return(rc);
}

GBOOL
account(VOID)                      /* remote Sysop "account" handler       */
{
     CHAR *ptr;
     INT i,msg;
     LONG l;

     setmbk(rsymb);
     chkdft(rsyptr->dftinp);
     if ((ptr=setdft(input[0])) != NULL) {
          strcpy(input,ptr);
          inplen=strlen(input);
     }
     if (margc == 0 || usrptr->flags&INJOIP) {
          acczero();
     }
     else if (margc == 1 && sameas(margv[0],"x")) {
          clrxrf();
          if (!acconex()) {
               return(FALSE);
          }
     }
     else {
          do {
               bgncnc();
               switch (usrptr->substt) {
               case 0:
                    cncchr();
                    rsprom(RSMENU);
                    usrptr->substt=RSSMNU;
                    break;
               case RSMENU:
               case RSSMNU:
                    if (morcnc() == '?') {
                         cncall();
                         rsprom(RSMENU);
                    }
                    else if ((msg=isvalop(cncwrd())) == 0) {
                         cncwrd();
                         prfmsg(INVOPT);
                         rsprom(RSMENU);
                    }
                    else if (!axs4op(usaptr,op)) {
                         cncall();
                         prfmsg(op == 99 ? INVOPT : NARSOP);
                         rsprom(RSSMNU);
                    }
                    else {
                         rsprom(msg);
                    }
                    break;
               case RSOP12:
                    if (ask4uid(1)) {
                         cncall();
                         op=0;
                         op|=(ED_CLRTXT|ED_CLRTOP);
                         bgnedt(MTXSIZ,rsyptr->text,0,NULL,dwedt12,op);
                         return(TRUE);
                    }
                    break;
               case RSOP22:
                    if (ask4uid(0)) {
                         if (onsysn(rsyptr->acc.userid,1)) {
                              movmem(othuap,&rsyptr->acc,sizeof(struct usracc));
                         }
                         detflg=1;
                         shwusr(&rsyptr->acc);
                         prfmsg(DETPT3,l2as(rsyptr->acc.totcreds),
                                       l2as(rsyptr->acc.totcreds-
                                            rsyptr->acc.totpaid),
                                       l2as(rsyptr->acc.totpaid));
                         rsprom(RSSMNU);
                    }
                    break;
               case RSOP23:
                    switch (op=cncchr()) {
                    case 'B':
                         bgnaud(1);
                         break;
                    case 'E':
                         bgnaud(0);
                         break;
                    default:
                         prfmsg(INVOPT);
                         prfmsg(RSOP23);
                    }
                    cncall();
                    break;
               case RSOP23A:
                    prf("");
                    break;
               case RSOP25Z:
                    if ((op=cncint()) < 1 || op > 16) {
                         cncall();
                         prfmsg(INVOPT);
                         rsprom(RSOP25Z);
                    }
                    else {
                         if (op == 15 || op == 16) {
                              rsprom(RSOP25B1);
                         }
                         else {
                              rsprom(RSOP25A);
                         }
                         rsyptr->chan=op;
                    }
                    break;
               case RSOP25A:
                    strcpy(rsyptr->text,cncall());
                    if (rsyptr->chan == 9 ||
                       (rsyptr->chan >= 12 && rsyptr->chan <= 14)) {
                         rsprom(RSOP25C);
                    }
                    else {
                         bgnads();
                    }
                    break;
               case RSOP25B1:
                    strcpy(rsyptr->text,cncall());
                    if (dcdate(rsyptr->text) == GCINVALIDDOT) {
                         prfmsg(INVDAT1);
                         rsprom(RSOP25B1);
                    }
                    else {
                         rsprom(RSOP25C);
                    }
                    break;
               case RSOP25C:
                    if ((rsyptr->genctr=cncint()) < 1 || rsyptr->genctr > 5) {
                         prfmsg(INVOPT);
                         rsprom(RSOP25C);
                    }
                    else {
                         bgnads();
                    }
                    break;
               case RSOP25D:
                    prf("");
                    break;
               case RSOP31:
                    if (ask4uid(1)) {
                         btuinj(rsyptr->chan,RING);
                         prfmsg(USRZAP);
                         rsprom(RSSMNU);
                    }
                    break;
               case RSOP32:
                    if (ask4uid(0)) {
                         if (((rsyptr->acc.flags&HASMST)
                            || sameas(rsyptr->acc.userid,"Sysop"))
                            && !(rsyptr->acc.flags&SUSPEN)) {
                              prfmsg(NO2SYS);
                              rsprom(RSOP32);
                         }
                         else {
                              rsyptr->chan=(rsyptr->acc.flags&SUSPEN) ? 1 : 0;
                              rsprom(RSOP32A);
                         }
                    }
                    break;
               case RSOP32A:
                    hdlbit(SUSPEN);
                    break;
               case RSOP33:
                    if (ask4uid(0)) {
                         rsyptr->chan=(rsyptr->acc.flags&UNDAXS) ? 1 : 0;
                         rsprom(RSOP33A);
                    }
                    break;
               case RSOP33A:
                    hdlbit(UNDAXS);
                    break;
               case RSOP34:
                    if (ask4uid(0)) {
                         if (!(rsyptr->acc.flags&UNDAXS)) {
                              if (sameas(rsyptr->acc.userid,usaptr->userid)) {
                                   rblwof(USRNDL);
                                   break;
                              }
                              if (delacct(rsyptr->acc.userid) >= 0) {
                                   rblwof(USRDEL2);
                                   break;
                              }
                         }
                         prfmsg(USRNDL);
                         rsprom(RSSMNU);
                    }
                    break;
               case RSOP35:
                    rsop35();
                    break;
               case RSOP35A:
                    if (cncyesno() == 'Y') {
                         kilsrc=usrnum;
                         errcod=8;
                         kilctr=rsyptr->rkilctr;
                         fupkil();
                         setmbk(rsymb);
                    }
                    cncall();
                    rsprom(RSSMNU);
                    break;
               case RSOP36:
                    if ((rsyptr->chan=cncint()) < 1 || rsyptr->chan > 5) {
                         cncall();
                         prfmsg(INVOPT);
                         rsprom(RSOP36);
                    }
                    else {
                         rsprom(RSOP36A);
                    }
                    break;
               case RSOP36A:
                    if ((rsykil=cncint()) < 1 || rsykil > 10) {
                         cncall();
                         prfmsg(BERESN);
                         rsprom(RSOP36A);
                    }
                    else {
                         rsykil++;
                         errcod=(rsyptr->chan == 1 ? 0 : rsyptr->chan+9);
                         rsyptr->chan=usrnum;
                         rsmode=rsetop;
                         prepff();
                         curusr(rsyptr->chan);
                         prfmsg(SET4EV);
                         outprf(usrnum);
                         rsyevt();
                         rsprom(RSSMNU);
                    }
                    break;
               case RSOP51:
                    if (ask4uid(2)) {
                         if (emuinu()) {
                              rblwof(EMUINU);
                         }
                         else if (othusn == usrnum) {
                              rblwof(EMUYOU);
                         }
                         else if (othusn == nterms-1) {
                              rblwof(EMULCL);
                         }
                         else {
                              btutrg(usrnum,1);
                              rmtsys=usrnum;
                              usrptr->flags|=NOINJO;
                              emuchn(rsyptr->chan);
                              prfmsg(usrptr->substt=RSOP51A);
                              btuscr(usrnum,0);
                              prf("\r\n\n");
                         }
                    }
                    break;
               case RSOP51A:                 /* Emulation just ignore      */
               case RSOP52A:                 /* Monitor stuff just ignore  */
                    break;
               case RSOP54:
                    if (ask4uid(2)) {
                         if (usroff(rsyptr->chan)->usrcls != VACANT) {
                              prfmsg(ACTCHN);
                              prfmsg(RSOP54);
                         }
                         else {
                              rsprom(RSOP54A);
                         }
                    }
                    break;
               case RSOP54A:
                    switch (cncchr()) {
                    case 'R':
                         op=NORMRS;
                         break;
                    case 'B':
                         op=BUSYRS;
                         break;
                    case 'N':
                         op=NANSRS;
                         break;
                    default:
                         cncall();
                         prfmsg(INVOPT);
                         prfmsg(RSOP54A);
                         break;
                    }
                    rsmodes[rsyptr->chan]=op;
                    kilchn(rsyptr->chan);
                    prfmsg(CHNCHG);
                    rsprom(RSSMNU);
                    break;
               case RSOP61:
                    if (chksfil(0)) {
                         clrprf();
                         usrptr->flags|=NOINJO;
                         usrptr->substt=RSOP61A;
                    }
                    break;
               case RSOP61A:
                    break;
               case RSOP62:
                    rsop62();
                    break;
               case RSOP62A:
                    rsop62a();
                    break;
               case RSOP62B:
                    break;
               case RSOP63:
                    cncall();
                    parsin();
                    if (margc == 2) {
                         if (fnamchk(margv[0]) || fnamchk(margv[1])) {
                              prfmsg(FILINU);
                         }
                         else {
                              prfmsg(rename(margv[0],margv[1]) == 0
                                ? RSOP63A : RSOP63B,margv[0],margv[1]);
                         }
                    }
                    else {
                         prfmsg(RSOP63C);
                    }
                    rsprom(RSSMNU);
                    break;
               case RSOP64:
                    getfil();
                    if (fnd1st(&rsyptr->dirblk,rsyptr->sfname,FAMDIR)) {
                         prf("\r");
                         dspdir();
                         usrptr->substt=RSOP64A;
                    }
                    else {
                         prfmsg(RSOP64B);
                         rsprom(RSSMNU);
                    }
                    break;
               case RSOP64A:
                    prf("");
                    break;
               case RSOP65:
                    strcpy(rsyptr->text,cncall());
                    prfmsg(MKDIR(rsyptr->text) == 0 ? RSOP65A : RSOP65B,
                           rsyptr->text);
                    rsprom(RSSMNU);
                    break;
               case RSOP66:
                    strcpy(rsyptr->text,cncall());
                    prfmsg(rmdir(rsyptr->text) == 0 ? RSOP66A : RSOP66B,
                           rsyptr->text);
                    rsprom(RSSMNU);
                    break;
               case RSOP67:
                    if (chksfil(1)) {
                         prfmsg(unlink(rsyptr->sfname) == 0 ? RSOP67A
                    : RSOP67B,rsyptr->sfname);
                         rsprom(RSSMNU);
                    }
                    break;
               case RSOP71M0:
                    rsop71();
                    break;
               case RSOP71A:
                    if (ask4uid(0)) {
                         rsprom(RSOP71AA);
                    }
                    break;
               case RSOP71AA:
                    cpykey(rsyptr->text,cncnum(),8);
                    if (atol(rsyptr->text) == 0L) {
                         rsprom(RSOP71AA);
                    }
                    else {
                         rsprom(RSOP71AB);
                    }
                    break;
               case RSOP71AB:
                    sporf();
                    break;
               case RSOP71AC:
                    sisokq();
                    break;
               case RSOP71B:
                    if (morcnc() == '?') {
                         cncall();
                         dspcll();
                         rsprom(RSOP71B);
                    }
                    else {
                         dspkys(cncall(),1);
                         rsprom(RSOP71M0);
                    }
                    break;
               case RSOP71C:
                    if (ask4uid(0)) {
                         if (sameas(rsyptr->acc.prmcls,rsyptr->acc.curcls)) {
                              prfmsg(RSOP71C2,rsyptr->acc.userid,
                                     rsyptr->acc.prmcls);
                         }
                         else {
                              prfmsg(RSOP71C3,rsyptr->acc.userid,
                                     rsyptr->acc.curcls,rsyptr->acc.prmcls);
                         }
                         rsprom(RSOP71C1);
                    }
                    break;
               case RSOP71C1:
                    if (morcnc() == '?') {
                         cncall();
                         dspcll();
                         rsprom(RSOP71C1);
                    }
                    else {
                         strcpy(rsyptr->text,strupr(cncall()));
                         if (!namacls(rsyptr->text)) {
                              prfmsg(INVKYR);
                              rsprom(RSOP71C1);
                              break;
                         }
                         else if (fndcls(rsyptr->text) == NULL) {
                              prfmsg(NOSKYR);
                              rsprom(RSOP71C1);
                              break;
                         }
                         if ((rsyptr->cltptr=fndcls(rsyptr->text)) != NULL
                             && (rsyptr->cltptr->flags&DAYEXP)) {
                              rsprom(RSOP71C4);
                         }
                         else if (!(rsyptr->cltptr->flags&HASCRD
                              && rsyptr->cltptr->flags&NOCRED)) {
                              swtcls(&rsyptr->acc,1,rsyptr->text,3,0);
                              prfmsg(OKSWCH,rsyptr->acc.userid,rsyptr->text);
                              rsprom(RSOP71M0);
                         }
                         else {
                              rsyptr->cltptr=NULL;
                              prfmsg(NOSKYR);
                              rsprom(RSOP71C1);
                         }
                    }
                    break;
               case RSOP71C4:
                    i=0;
                    if (morcnc() == '.' || ((i=cncint()) > 0 && i < 32000)) {
                         if (i == 0) {
                              cncchr();
                         }
                         swtcls(&rsyptr->acc,1,rsyptr->text,3,i);
                         prfmsg(OKSWCH,rsyptr->acc.userid,rsyptr->text);
                         rsprom(RSOP71M0);
                    }
                    else {
                         cncall();
                         prfmsg(INVAMT);
                         rsprom(RSOP71C4);
                    }
                    break;
               case RSOP71D:
                    if (ask4uid(0)) {
                         strcpy(rsyptr->text,rsyptr->acc.userid);
                         prfmsg(ROP71JL1);
                         rsprom(RSOP71JM);
                    }
                    break;
               case RSOP71U:
                    if (ask4uid(0)) {
                         strcpy(rsyptr->text,rsyptr->acc.userid);
                         rsprom(RSOP71U1);
                    }
                    break;
               case RSOP71U1:
                    usercopy(rsyptr->text,cncall());
                    rsprom(RSOP71M0);
                    break;
               case RSOP71H:
                    if (morcnc() == '?') {
                         cncall();
                         dspcll();
                         rsprom(RSOP71H);
                    }
                    else {
                         strcpy(rsyptr->text,cncall());
                         if (!namacls(rsyptr->text)) {
                              prfmsg(INVKYR);
                              rsprom(RSOP71H);
                              break;
                         }
                         if (!canedt()) {
                              prfmsg(CNTEDT);
                              rsprom(RSOP71H);
                         }
                         else if ((rsyptr->cltptr=fndcls(rsyptr->text)) != NULL
                                  && !(rsyptr->cltptr->flags&HASCRD
                                       && rsyptr->cltptr->flags&NOCRED)) {
                              rsprom(RSOP71I1);
                         }
                         else {
                              if (rsyptr->cltptr != NULL) {
                                   dltcls(rsyptr->cltptr);
                                   rsyptr->cltptr=NULL;
                              }
                              rsyptr->flags|=CRTCLS;
                              setmem(rclsptr,sizeof(struct acclass),0);
                              strcpy(rclsptr->clname,rsyptr->text);
                              rsprom(RSOP71I);
                         }
                    }
                    break;
               case RSOP71I:
                    if (cncyesno() == 'Y') {
                         rsprom(RSOP71J1);
                    }
                    else {
                         rsyptr->flags&=~CRTCLS;
                         rsprom(RSOP71H);
                    }
                    cncall();
                    break;
               case RSOP71I1:
                    rsop71i1();
                    break;
               case RSOP71I2:
                    if (cncyesno() == 'Y') {
                         dltcls(rsyptr->cltptr);
                         prfmsg(OKDLTD);
                    }
                    rsprom(RSOP71H);
                    break;
               case RSOP71J1:
                    if (sameto("Unl",nxtcmd)) {
                         cncwrd();
                         rclsptr->limcal=-1;
                         rsprom(RSOP71J2);
                    }
                    else if (isdigit(*nxtcmd) && (op=cncint()) >= 0 &&
                             op <= 1440) {
                         rclsptr->limcal=op;
                         rsprom(RSOP71J2);
                    }
                    else {
                         prfmsg(INVAMT);
                         rsprom(RSOP71J1);
                         cncall();
                    }
                    break;
               case RSOP71J2:
                    rsop71j2();
                    break;
               case RSOP71J3:
                    rsop71j3();
                    break;
               case RSOP71J4:
                    rsop71j4();
                    break;
               case RSOP71J5:
                    if (cncyesno() == 'Y') {
                         prfmsg(RSOP71J6);
                         outprf(usrnum);
                         bgnedt(XMSGSZ,rclsptr->msgs[0],0,NULL,dwedtj5,0);
                         return(TRUE);
                    }
                    else {
                         cncall();
                         rclsptr->msgs[0][0]='\0';
                         prfmsg(RSOP71J7);
                         rsprom(ROP71J7A);
                    }
                    break;
               case ROP71J7A:
                    if (cncyesno() == 'Y') {
                         rclsptr->flags|=CRDXMT;
                         rclsptr->dbtlmt=0L;
                         prfjdje();
                    }
                    else {
                         rclsptr->flags&=~CRDXMT;
                         cncall();
                         rsprom(RSOP71J8);
                    }
                    break;
               case RSOP71J8:
                    if (cncyesno() == 'Y') {
                         rsprom(RSOP71J9);
                    }
                    else {
                         cncall();
                         rclsptr->dbtlmt=0L;
                         prfjdje();
                    }
                    break;
               case RSOP71J9:
                    if (sameto("Unl",nxtcmd)) {
                         cncwrd();
                         rclsptr->dbtlmt=-1L;
                         rsprom(RSOP71JA);
                    }
                    else if (isdigit(*nxtcmd) && (l=cnclon()) > 0L &&
                             l <= 9999999L) {
                         rclsptr->dbtlmt=l;
                         rsprom(RSOP71JA);
                    }
                    else {
                         prfmsg(INVAMT);
                         rsprom(usrptr->substt);
                    }
                    break;
               case RSOP71JA:
                    rsop71ja();
                    break;
               case RSOP71JB:
                    if ((op=cncint()) > 0 && op < 32000) {
                         rclsptr->fgvday=op;
                         prfjdje();
                    }
                    else {
                         prfmsg(INVAMT);
                         rsprom(RSOP71JB);
                    }
                    break;
               case RSOP71JE:
                    rsop71je();
                    break;
               case RSOP71JG:
                    if ((op=cncint()) > 0 && op < 32000) {
                         rclsptr->idlday=op;
                         rsprom(RSOP71JI);
                    }
                    else {
                         prfmsg(INVAMT);
                         rsprom(RSOP71JG);
                    }
                    break;
               case RSOP71JH:
                    if ((op=cncint()) > 0 && op < 32000) {
                         rclsptr->dftday=op;
                         rsprom(RSOP71JI);
                    }
                    else {
                         prfmsg(INVAMT);
                         rsprom(RSOP71JH);
                    }
                    break;
               case RSOP71JI:
                    if (morcnc() == '?') {
                         cncall();
                         dspcll();
                         rsprom(RSOP71JI);
                         break;
                    }
                    strcpy(rsyptr->text,cncall());
                    if (namacls(rsyptr->text)) {
                         strcpy(rclsptr->nxtcls[rsyptr->chan > 2 ? 3 :
                                rsyptr->chan],rsyptr->text);
                         if (sameas(rsyptr->text,"DELETE_ACCOUNT")) {
                              if (rsyptr->chan > 2) {
                                   rclsptr->msgs[1][0]='\0';
                              }
                              rsprom(RSOP71JE);
                         }
                         else if (fndcls(rsyptr->text) == NULL) {
                              prfmsg(DELWRN,strupr(rsyptr->text));
                              rsprom(rsyptr->chan <= 2 ? RSOP71JE : RSOP71JJ);
                         }
                         else {
                              rsprom(rsyptr->chan <= 2 ? RSOP71JE : RSOP71JJ);
                         }
                    }
                    else {
                         prfmsg(INVKYR);
                         rsprom(RSOP71JI);
                    }
                    break;
               case RSOP71JJ:
                    if (cncyesno() == 'Y') {
                         prfmsg(ROP71JJ1);
                         outprf(usrnum);
                         bgnedt(XMSGSZ,rclsptr->msgs[1],0,NULL,dwedtjj,0);
                         return(TRUE);
                    }
                    else {
                         cncall();
                         rclsptr->msgs[1][0]='\0';
                         prfmsg(MSGDFT);
                         rsprom(RSOP71JE);
                    }
                    break;
               case RSOP71JK:
                    if (cncyesno() == 'Y') {
                         rclsptr->flags&=~xflags[rsyptr->genctr-1];
                         rclsptr->flags|=xflags[(op=rsyptr->chan)-1];
                         rsprom(op == 1 ? RSOP71JG : op == 2 ?  RSOP71JH : RSOP71JI);
                    }
                    else {
                         cncall();
                         rsprom(RSOP71JE);
                    }
                    break;
               case RSOP71JM:
                    if (morcnc() == '?') {
                         cncchr();
                         rsprom(RSOP71JN);
                    }
                    else if (morcnc() == '.' && *(nxtcmd+1) == '\0') {
                         rsprom((rsyptr->flags&(EDTCLS|CRTCLS)) ? RSOP71JV :
                                RSOP71M0);
                         cncall();
                    }
                    else if (morcnc() == '-') {
                         cncchr();
                         chkkey(1);
                    }
                    else {
                         chkkey(0);
                    }
                    break;
               case RSOP71JN:
                    if (sameto("CLASSES",nxtcmd)) {
                         cncwrd();
                         dspcll();
                         rsprom(RSOP71JM);
                    }
                    else if (sameto("CLEAR",nxtcmd)) {
                         cncwrd();
                         nkyrec(rsyptr->text);
                         prfmsg(OKCLRD);
                         rsprom(RSOP71JM);
                    }
                    else if (sameto("SOFAR",nxtcmd)) {
                         cncwrd();
                         if (rsyptr->text[0] == RINGID) {
                              dspkys(rsyptr->text+1,1);
                         }
                         else {
                              dspkys(rsyptr->text,0);
                         }
                         rsprom(RSOP71JM);
                    }
                    else if (sameto("LIST",nxtcmd)) {
                         cncwrd();
                         rsprom(RSOP71JQ);
                    }
                    else if (sameto("ADD",nxtcmd)) {
                         cncwrd();
                         rsprom(RSOP71JS);
                    }
                    else if (sameto("REMOVE",nxtcmd)) {
                         cncwrd();
                         rsprom(RSOP71JT);
                    }
                    else {
                         cncall();
                         rsprom(RSOP71JN);
                    }
                    break;
               case RSOP71JQ:
                    if (morcnc() == '?') {
                         cncall();
                         dspcll();
                         rsprom(RSOP71JQ);
                         break;
                    }
                    dspkys(cncall(),1);
                    rsprom(RSOP71JM);
                    break;
               case RSOP71JS:
                    if (morcnc() == '?') {
                         cncall();
                         dspcll();
                         rsprom(RSOP71JS);
                         break;
                    }
                    impkey(0);
                    break;
               case RSOP71JT:
                    if (morcnc() == '?') {
                         cncall();
                         dspcll();
                         rsprom(RSOP71JT);
                         break;
                    }
                    impkey(1);
                    break;
               case RSOP71JV:
                    rsop71jv();
                    break;
               case RSOP71JW:
                    if (cncyesno() == 'Y') {
                         if (rsyptr->text[0] == RINGID && (rsyptr->flags&CRTCLS)) {
                              dlkeys(rsyptr->text);
                         }
                         rsyptr->flags&=~(CRTCLS|EDTCLS);
                         rsprom(RSOP71H);
                    }
                    else {
                         rsprom((INT)(rsyptr->fpos));
                    }
                    cncall();
                    break;
               case RSOP731:
                    switch (cncchr()) {
                    case 'U':
                         rsprom(RSOP73A);
                         break;
                    case 'D':
                         rsprom(RSOP73C);
                         break;
                    case 'M':
#ifdef UNIX
                         cncall();
                         prfmsg(INV4OS);
                         rsprom(RSOP731);
#else
                         morcnc();
                         fileup("wgsmenu2.dat",cncall(),fuprnw);
#endif
                         break;
                    default:
                         cncall();
                         prfmsg(INVOPT);
                         rsprom(RSOP731);
                    }
                    break;
               case RSOP73A:
                    if (morcnc() == '.') {
                         cncchr();
                         strcpy(rsyptr->text,"");
                    }
                    else {
                         strcpy(rsyptr->text,cncall());
                         if (rsyptr->text[strlen(rsyptr->text)-1] != SL) {
                              strcat(rsyptr->text,SLS);
                         }
                    }
                    rsprom(RSOP73B);
                    break;
               case RSOP73B:
                    if (morcnc() == '.') {
                         cncchr();
                    }
                    ptr=cncwrd();
                    strcpy(&rsyptr->text[100],ptr);
                    morcnc();
                    fileup(ptr,cncall(),fuprem);
                    break;
               case RSOP73C:
                    if (ftgnew()) {
                         ptr=cncall();
                         ftgptr->flags=(strchr(ptr,'*') != NULL
                                     || strchr(ptr,'?') != NULL) ? FTGWLD : 0;
                         fileparts(GCPART_FNAM,ptr,ftgptr->tagspc,TSLENG);
                         fileparts(GCPART_PATH,ptr,rsyptr->text,MTXSIZ);
                         ftgptr->tshndl=tshrem;
                    }
                    morcnc();
                    ftgsbm(cncall());
                    break;
               case RSOP99:
                    if (ask4uid(0)) {
                         if (sameas(rsyptr->acc.userid,"Sysop")) {
                              prfmsg(SYSNOT);
                              rsprom(RSOP99);
                         }
                         else {
                              rsprom(RSOP99B);
                         }
                    }
                    break;
               case RSOP99B:
                    if (sameas(nxtcmd,"ON")) {
                         remall(&rsyptr->acc,1);
                         cncall();
                    }
                    else if (sameas(nxtcmd,"OFF")) {
                         remall(&rsyptr->acc,0);
                         cncall();
                    }
                    else if (morcnc() == '?') {
                         cncchr();
                         rsprom(RSOP99B);
                         break;
                    }
                    else if (isvalop(cncwrd())) {
                         if (op == 99) {
                              rsyptr->acc.flags^=HASMST;
                         }
                         togaxs(&rsyptr->acc,op);
                    }
                    else {
                         cncall();
                         prfmsg(INVOPT);
                    }
                    prfmsg(RSOP99B);
                    break;
               default:
                    catastro("REMSYS STATE %d ERROR",usrptr->substt);
               }
          } while (!endcnc());
     }
     if (usrptr->state != rmsyst
      || (usrptr->substt != RSOP11
          && usrptr->substt != RSOP13)) {
          outprf(usrnum);
     }
     return(TRUE);
}

static VOID
prfjdje()
{
     rclsptr->flags&=~(DBTLMT|NOCRED|HASCRD|DAYEXP|IDLEXP);
     prfmsg(RSOP71JD);
     rsprom(RSOP71JE);
}

static VOID
remall(uacptr,onoff)               /* turn on/off all options for a user   */
struct usracc *uacptr;             /* this includes HASMST flag too!       */
INT onoff;
{
     INT i;

     for (i=0 ; i < AXSSIZ ; i++) {
          uacptr->access[i]=(onoff ? ~0 : 0);
     }
     if (onoff) {
          uacptr->flags|=HASMST;
     }
     else {
          uacptr->flags&=~HASMST;
     }
}

static VOID
hdlbit(                            /* handle changing a usracc bit flag    */
INT tbit)                          /* bit to be changed                    */
{
     INT ison,flag,unum;

     if (cncyesno() == 'Y') {
          if ((rsyptr->acc.flags&HASMST) && tbit == SUSPEN
           && !(rsyptr->acc.flags&SUSPEN)) {
               rblwof(NO2SYS);
               return;
          }
          if ((ison=onbbs(rsyptr->acc.userid,1)) == 1) {
               movmem(uacoff(uisusn),&rsyptr->acc,sizeof(struct usracc));
          }
          flag=(rsyptr->acc.flags&tbit) ? 1 : 0;
          if (rsyptr->chan != flag) {
               rblwof(FLGALC);
               return;
          }
          if (tbit == SUSPEN && !(rsyptr->acc.flags&tbit) && ison) {
               unum=usrnum;
               curusr(uisusn);
               if (usrptr->usrcls > SUPIPG) {
                    loscar();
               }
               else {
                    rstchn();
               }
               curusr(unum);
          }
          if (rsyptr->chan) {
               rsyptr->acc.flags&=~tbit;
          }
          else {
               rsyptr->acc.flags|=tbit;
          }
          dfaSetBlk(accbb);
          dfaGetEQ(NULL,rsyptr->acc.userid,0);
          dfaUpdate(&rsyptr->acc);
          flgmsg(tbit,rsyptr->chan);
          if (ison) {
               if (rsyptr->chan) {
                    uacoff(uisusn)->flags&=~tbit;
               }
               else {
                    uacoff(uisusn)->flags|=tbit;
               }
          }
     }
     rsprom(RSSMNU);
}

static VOID
flgmsg(                       /* display results of flag bit change        */
INT tbit,                     /* which bit was changed                     */
INT sflag)                    /* what the new position is                  */
{
     INT word;
     static CHAR wrds[][12]={ "PROTECTED","UNPROTECTED","SUSPENDED","UNSUSPENDED"};

     word=(tbit == SUSPEN)*2+sflag;
     shocst(spr("USER ACCOUNT %s",wrds[word]),"%s %s %s",usaptr->userid,
            wrds[word],rsyptr->acc.userid);
     setmbk(rsymb);
     prfmsg(FLGCHG,rsyptr->acc.userid,wrds[word]);
}

VOID
rcpydat(VOID)                 /* copy some data for file copy              */
{
     ULONG tmandt;
     INT i=0,siz;
     CHAR fname[FNDSIZE];

     setmbk(rsymb);
     do {
          siz=fread(rsyptr->text,1,128,rsyptr->sfp);
          if (siz > 0) {
               fwrite(rsyptr->text,1,siz,rsyptr->dfp);
          }
          i++;
     } while (i < 8 && siz > 0);
     if (i < 8) {
          tmandt=getFileGMT(rsyptr->sfname);
          strcpy(fname,rsyptr->dfname);
          clsfils();
          setFileGMT(fname,tmandt);
          prfmsg(CPYDUN);
          stop_polling(usrnum);
          rsprom(RSSMNU);
     }
     else {
          prf(".");
     }
     outprf(usrnum);
}

VOID
dspsts(VOID)                  /* display overall statistics                */
{
     cncall();
     prfmsg(RSOP412);
     prfmsg(RSOP41A2,l2as(sv.dwnlds),l2as(sv.uplds),l2as(sv2.totcalls));
     prfmsg(RSOP41B2,l2as(sv.msgtot),sv.emlopn,sv.sigopn);
     prfmsg(RSOP41C2,l2as(sv2.paidpst+sv2.freepst),l2as(sv2.freepst),
         l2as(sv2.x25mbs),l2as(sv2.x25kps));
     rsprom(RSSMNU);
}

VOID
dspmdu(VOID)                  /* display module use statistics             */
{
     INT i;

     cncall();
     prfmsg(RSOP422);
     for (i=0 ; i < nmods ; i++) {
          prf("%-25.25s |%7.7s|%9.9s|\r",module[i]->descrp,
              l2as((mdstats[i].seconds+1800L)/3600L),l2as(mdstats[i].creds));
     }
     rsprom(RSSMNU);
}

VOID
dspsaa(VOID)                  /* display system demographics               */
{
     INT x,y;
     UINT totcnt,runtot;
     UINT total[NAGEBK];

     cncall();
     setmem(total,sizeof(UINT)*NAGEBK,0);
     prfmsg(RSOP43);
     for (x=0,runtot=0 ; x < NACMTY ; x++) {
          prf("%20.20s |",sysstg[x]);
          for (y=0,totcnt=0 ; y < NAGEBK ; y++) {
               totcnt+=sv2.matrix[x][y];
               total[y]+=sv2.matrix[x][y];
               prf("%5u|",sv2.matrix[x][y]);
          }
          runtot+=totcnt;
          prf("%5u|\r",totcnt);
     }
     prfmsg(RSOP43A);
     for (y=0 ; y < NAGEBK ; y++) {
          prf("%5u|",total[y]);
     }
     prf("%5u|\r",runtot);
     prfmsg(RSOP43B2,(sv2.numact-sv2.numfem),sv2.numfem,sv2.numcor,sv2.numans);
     rsprom(RSSMNU);
}

VOID
dspcus(VOID)                  /* Display all the class statistics          */
{
     LONG val;

     cncall();
     prfmsg(RSOP442);
     for (clsptr=clshead ; clsptr != NULL; clsptr=clsptr->next) {
          if (!(clsptr->flags&HASCRD && clsptr->flags&NOCRED)) {
               val=((clsptr->seconds)*24+dtrack/2)/dtrack;
               val=(val/(clsptr->users > 0 ? clsptr->users : 1)+30L)/60L;
               prf("%-16.16s |%7.7s|%7.7s|%7u|%16.16s|\r",clsptr->clname,
                   l2as((clsptr->seconds+1800L)/3600L),
                   l2as(((clsptr->seconds+1800L)/3600L*24+dtrack/2)/dtrack),
                   clsptr->users,
                   l2as(val));
          }
     }
     rsprom(RSSMNU);
}

static VOID
dspdir(VOID)                  /* display a directory entry                 */
{
     INT hr;

     hr=dthour(rsyptr->dirblk.ff_ftime)%12;
     if (hr == 0) {
          hr=12;
     }
     prf("%-32.32s %8.8s  %8.8s  %s\r",rsyptr->dirblk.ff_name,
         (rsyptr->dirblk.ff_attrib&FAMDIR) ? "<DIR>"
      : (CHAR *)l2as(rsyptr->dirblk.ff_fsize),
         ncdate(rsyptr->dirblk.ff_fdate),spr("%2d:%02d%s",hr,
         dtmin(rsyptr->dirblk.ff_ftime),((dthour(rsyptr->dirblk.ff_ftime)/12) ?
         "p" : "a")));
     btuinj(usrnum,CYCLE);
}

VOID
acsthn(VOID)                  /* status handler for remote Sysop stuff     */
{
     setmbk(rsymb);
     if (status == CYCLE) {
          if (btuoba(usrnum) >= outbsz-256) {
               switch (usrptr->substt) {
            case RSOP64A:
                    if (fndnxt(&rsyptr->dirblk)) {
                         dspdir();
                    }
                    else {
                         rsprom(RSSMNU);
                    }
                    break;
               case RSOP61A:
                    if (rdfile()) {
                         return;
                    }
                    usrptr->flags&=~NOINJO;
                    setmem(rsyptr->sfname,FNDSIZE,0);
                    setmem(rsyptr->dfname,FNDSIZE,0);
                    rsprom(RSSMNU);
                    break;
               default:
                    prf("");
               }
          }
          else {
               prf("");
               btuinj(usrnum,CYCLE);
          }
          outprf(usrnum);
     }
     else if (status == INBLK) {
          emuinp(0);
     }
     else {
          dfsthn();
     }
}

VOID
emuinp(                       /* emulation input handler                   */
INT hangup)                   /* should a hangup be performed              */
{
     CHAR c;

     if (usrnum == rmtsys) {
          btuict(usrnum,&c);
          if ((c == (EMUEXT&0x1F)) || hangup) {
               clremu(rmtsys);
          }
          else {
               curusr(chnemd);
               if (c == (EMUCHT&0x1F)) {
                    if (usrptr->flags&OPCHAT) {
                         lvchat();
                    }
                    else if (usrptr->usrcls > SUPIPG) {
                         entcht();
                    }
               }
               else if (c == (EMUZAP&0x1F)) {
                    if ((usrptr->flags&NOHDWE) || (usrptr->usrcls != VACANT)) {
                         btuinj(usrnum,RING);
                         clremu(rmtsys);
                    }
               }
               else {
                    btumks(c);
               }
          }
     }
}

VOID
clremu(                       /* clear emulation when done                 */
INT unum)                     /* user number to deal with                  */
{
     btutrg(unum,0);
     btuscr(unum,'\n');
     rmtsys=-1;
     usroff(unum)->flags&=~NOINJO;
     if (usroff(chnemd)->flags&OPCHAT) {
          lvchat();
     }
     curusr(unum);
     setmbk(rsymb);
     prfmsg(RSOP51B);
     outprf(usrnum);
     usrptr->substt=RSSMNU;
     injacr();
}

static INT
ask4uid(                      /* does uid exist (and is he on?)            */
INT on)                       /* 1=uid must be logged on. 2=any hex is ok  */
{
     INT i;

     if (on) {
          if (morcnc() == '?') {
               cncall();
               lstuon();
               rsprom(usrptr->substt);
          }
          else {
               if (strlen(nxtcmd) < 3 && (i=cnchex()) != -1) {
                    if ((othusn=usridx(i)) < 0) {
                         cncall();
                         prfmsg(INVCHN);
                         rsprom(usrptr->substt);
                         return(0);
                    }
                    if (usroff(othusn)->usrcls != VACANT) {
                         movmem(uacoff(othusn),&rsyptr->acc,sizeof(struct usracc));
                         rsyptr->chan=othusn;
                         return(1);
                    }
                    if (on == 2 && othusn != -1) {
                         rsyptr->chan=othusn;
                         return(1);
                    }
                    cncall();
                    prfmsg(CHNACT);
                    rsprom(usrptr->substt);
                    return(0);
               }
               else if (onsysn(cncuid(),1)) {
                    movmem(othuap,&rsyptr->acc,sizeof(struct usracc));
                    rsyptr->chan=othusn;
                    return(1);
               }
               cncall();
               prfmsg(NUIDON);
               rsprom(usrptr->substt);
          }
     }
     else {
          switch (hdluid(cncall())) {
          case UIDPMT:
               rsprom(usrptr->substt);
               break;
          case UIDFND:
               dfaSetBlk(accbb);
               if (dfaAcqEQ(&rsyptr->acc,uidxrf.userid,0)) {
                    dfaRstBlk();
                    return(1);
               }
               dfaRstBlk();
               break;
          }
     }
     return(0);
}

VOID
updaxs(VOID)                  /* update access (leaving editing state)     */
{
     INT b4flags;

     if (onsysn(rsyptr->acc.userid,1)) {
          movmem(rsyptr->acc.access,uacoff(othusn)->access,sizeof(INT)*AXSSIZ);
          b4flags=uacoff(othusn)->flags;
          if (rsyptr->acc.flags&HASMST) {
               uacoff(othusn)->flags|=HASMST;
          }
          else {
               uacoff(othusn)->flags&=~HASMST;
          }
          if (b4flags != uacoff(othusn)->flags) {
               axschg(uacoff(othusn)->userid);
          }
          movmem(uacoff(othusn),&rsyptr->acc,sizeof(struct usracc));
     }
     dfaSetBlk(accbb);
     if (dfaAcqEQ(NULL,rsyptr->acc.userid,0)) {
          dfaUpdate(&rsyptr->acc);
          prfmsg(EDTSUC);
     }
     else {
          prfmsg(EDTFAI);
     }
     rsprom(RSSMNU);
}

VOID
bgnmon(                       /* begin monitoring status                   */
INT msg,                      /* message number to be displayed to channel */
ULONG wch)                  /* bit to be turned on                       */
{
     cncall();
     prfmsg(msg);
     usrptr->substt=RSOP52A;
     usrptr->flags|=(NOINJO+wch);
     btuech(usrnum,0);
}

VOID
rblwof(                       /* blow off process and return to main       */
INT msg)                      /* message number to be displayed to channel */
{
     cncall();
     prfmsg(msg);
     rsprom(RSSMNU);
}

static INT
chksfil(                      /* check for existance of source file        */
INT shut)                     /* 0=leave file open, 1=shut the file        */
{
     strcpy(rsyptr->sfname,cncall());
     if (fnamchk(rsyptr->sfname)) {
          prfmsg(FILINU);
          prfmsg(usrptr->substt);
          return(0);
     }
     if ((shut && (rsyptr->sfp=fopen(rsyptr->sfname,FOPRB)) == NULL)
         || (!shut && !opfile(rsyptr->sfname))) {
          prfmsg(BADFIL,rsyptr->sfname);
          setmem(rsyptr->sfname,FNDSIZE,0);
          prfmsg(usrptr->substt);
          return(0);
     }
     if (shut) {
          fclose(rsyptr->sfp);
          rsyptr->sfp=NULL;
     }
     return(1);
}

static VOID
getfil(VOID)                  /* get first file name for a directory list  */
{
     strcpy(rsyptr->sfname,cncall());
     switch(*(rsyptr->sfname+(strlen(rsyptr->sfname)-1))) {
     case SL:
     case ':':
       strcat(rsyptr->sfname,STAR);
          break;
     default:
          if (fnd1st(&rsyptr->dirblk,rsyptr->sfname,FAMDIR)) {
               if (rsyptr->dirblk.ff_attrib&FAMDIR) {
                    if (fnd1st(&rsyptr->dirblk,
                      spr("%s"SLS STAR,rsyptr->sfname),FAMDIR)) {
                strcat(rsyptr->sfname,SLS STAR);
                    }
               }
          }
     }
}

static VOID
lstuon(VOID)                  /* list current users on-line                */
{
     INT i,pos=0;
     struct user *uptr;
     struct usracc *aptr;

     prf("\rUsers Online:\r");
     for (i=0 ; i < nterms ; i++) {
       uptr=usroff(i);
          aptr=uacoff(i);
          if (uptr->usrcls != VACANT && aptr->userid[0] != '\0') {
               prf("%-9s   ",aptr->userid);
               if (++pos == 4) {
                    prf("\r");
                    pos=0;
               }
          }
     }
     prf("\r");
}

static VOID
sporf(VOID)                   /* check to see if credits are paid or free  */
{
     rsyptr->chan=0;
     switch (cncchr()) {
     case 'P':
          rsyptr->chan=1;
     case 'F':
          rsprom(RSOP71AC);
          break;
     default:
          cncall();
          rsprom(usrptr->substt);
     }
}

VOID
sisokq(VOID)                  /* verify if posting credits is OK           */
{
     switch (cncyesno()) {
     case 'N':
          cncall();
          rsprom(RSOP71M0);
          break;
     case 'Y':
          switch (addcrd(rsyptr->acc.userid,rsyptr->text,rsyptr->chan)) {
          case -1:
               prfmsg(MYSDEL,rsyptr->acc.userid);
          case 0:
               break;
          case 1:
               if (othusn == usrnum) {
                    prf("You got it.\r");
               }
               else {
                    prfmsg(saycrd(rsyptr->text,rsyptr->chan) ? NOTIF : CANTNO,
                            rsyptr->acc.userid);
               }
               break;
          }
          rsprom(RSOP71M0);
          break;
     default:
          cncall();
          rsprom(usrptr->substt);
          break;
     }
}

VOID
dsponl(VOID)                  /* display users online status               */
{
     INT i;

     cncall();
     prfmsg(RSOP24);
     for (i=0 ; i < nterms ; i++) {
          othuap=uacoff(i);
          othusp=usroff(i);
          switch (incusr(i,TRUE,TRUE)) {
          case UIDNGD:
          case VACANT:
               break;
          case ONLINE:
               prf("%02x     (log-on in progress)\r",channel[i]);
               break;
          case BBSPRV:
               prf("%02x %-29s            %-6d %-20.20s\r",
                    channel[i],
                    othuap->userid,
                    ((othusp->minut4+2)>>2),
                    module[othusp->state]->descrp);
               break;
          case SUPIPG:
               prf("%02x     (sign-up in progress)\r",channel[i]);
               break;
          case SUPLON:
          case SUPLOF:
          case ACTUSR:
               prf("%02x %-29s %-10s %-6d %-20.20s\r",
                    channel[i],
                    othuap->userid,
                    l2as(othuap->creds),
                    ((othusp->minut4+2)>>2),
                    module[othusp->state]->descrp);
               break;
          }
     }
     rsprom(RSSMNU);
}

static VOID
bgnaud(                       /* begin scanning through Audit Trail        */
INT start)                    /* 0=start at beginning 1=start at end       */
{
     usrptr->flags|=NOINJO;
     rsyptr->chan=start;
     if (start) {
          rsyptr->fpos=0;
     }
     else {
          rsyptr->fpos=(LONG)audfNumRecs(hAuditTrail)-1;
     }
     rsprom(RSOP23A);
     begin_polling(usrnum,getaud);
}

static VOID
getaud(VOID)                  /* get next audit trail record for cycling   */
{
     INT success;
     struct audOldStyle buf;

     if (!ok2poll()) {
          return;
     }
     audfReadOldStyle(hAuditTrail,(ULONG)rsyptr->fpos,&buf,sizeof(buf));
     prf("\n%14.14s %-32.32s %-21.21s\n",buf.stamp,buf.brief,buf.channel);
     prf("      %-64s",buf.detail);
     if (rsyptr->chan) {
          success=((ULONG)rsyptr->fpos < audfNumRecs(hAuditTrail)-1);
          if (success) {
               rsyptr->fpos=(LONG)((ULONG)rsyptr->fpos+1);
          }
     }
     else {
          success=(rsyptr->fpos > 0);
          if (success) {
               rsyptr->fpos=(LONG)((ULONG)rsyptr->fpos-1);
          }
     }
     if (!success) {
          usrptr->flags&=~NOINJO;
          setmbk(rsymb);
          prfmsg(rsyptr->chan ? RSOP23B : RSOP23C);
          stop_polling(usrnum);
          rsprom(RSSMNU);
     }
     outprf(usrnum);
}

static VOID
bgnads(VOID)                  /* begin account database search             */
{
     dfaSetBlk(accbb);
     dfaStepLO(&rsyptr->acc);
     usrptr->flags|=NOINJO;
     rsyptr->fpos=dfaAbs();
     rsprom(RSOP25D);
     begin_polling(usrnum,scnacc);
}

static VOID
scnacc(VOID)                  /* scan account and find next one for        */
{                             /*    account database search cycling        */
     if (!ok2poll()) {
          return;
     }
     setmbk(rsymb);
     dfaSetBlk(accbb);
     dfaGetAbs(&rsyptr->acc,rsyptr->fpos,0);
     switch (rsyptr->chan) {
     case 1:
          chkstg(rsyptr->acc.userid);
          break;
     case 2:
          chkstg(rsyptr->acc.psword);
          break;
     case 3:
          chkstg(rsyptr->acc.usrnam);
          break;
     case 4:
          chkstg(rsyptr->acc.usrad1);
          break;
     case 5:
          chkstg(rsyptr->acc.usrad2);
          break;
     case 6:
          chkstg(rsyptr->acc.usrad3);
          break;
     case 7:
          chkstg(rsyptr->acc.usrpho);
          break;
     case 8:
          chkstg(sysstg[(SHORT)rsyptr->acc.systyp]);
          break;
     case 9:
          chkint(rsyptr->acc.age);
          break;
     case 10:
          if (toupper(rsyptr->text[0]) == rsyptr->acc.sex) {
               prfmsg(RSOP25E,rsyptr->acc.userid,rsyptr->acc.usrnam);
          }
          break;
     case 11:
          chkstg(rsyptr->acc.curcls);
          break;
     case 12:
          chkcrd(rsyptr->acc.totcreds);
          break;
     case 13:
          chkcrd(rsyptr->acc.totpaid);
          break;
     case 14:
          chkcrd(rsyptr->acc.creds);
          break;
     case 15:
          chkdat(rsyptr->acc.credat);
          break;
     case 16:
          chkdat(rsyptr->acc.usedat);
          break;
     }
     if (dfaStepNX(&rsyptr->acc)) {
          rsyptr->fpos=dfaAbs();
          prf("");
     }
     else {
          usrptr->flags&=~NOINJO;
          prfmsg(RSOP25F);
          stop_polling(usrnum);
          rsprom(RSSMNU);
     }
     outprf(usrnum);
}

static VOID
chkstg(stg)                        /* check string for account search */
CHAR *stg;
{
     if (findstg(rsyptr->text,stg)) {
          prfmsg(RSOP25E,rsyptr->acc.userid,rsyptr->acc.usrnam);
     }
}

static VOID
chkint(                            /* check int for account search         */
INT numb)                          /* number to compare against search crit*/
{
     INT a,retval;

     a=atoi(rsyptr->text);
     retval=glthrv[rsyptr->genctr-1]
                  [(numb >= a ? 1 : 0)+(numb > a ? 1 : 0)];
     if (retval) {
          prfmsg(RSOP25E,rsyptr->acc.userid,rsyptr->acc.usrnam);
     }
}

VOID
chkdat(                            /* check date for account search        */
INT date)                          /* date to compare against search crit  */
{
     INT a,retval;

     a=dcdate(rsyptr->text);
     retval=glthrv[rsyptr->genctr-1]
                  [(date >= a ? 1 : 0)+(date > a ? 1 : 0)];
     if (retval) {
          prfmsg(RSOP25E,rsyptr->acc.userid,rsyptr->acc.usrnam);
     }
}

VOID
chkcrd(                            /* check credits for account search     */
LONG credits)                    /* amount to compare against search crit*/
{
     INT retval;
     LONG a;

     a=atol(rsyptr->text);
     retval=glthrv[rsyptr->genctr-1]
                  [(credits >= a ? 1 : 0)+(credits > a ? 1 : 0)];
     if (retval) {
          prfmsg(RSOP25E,rsyptr->acc.userid,rsyptr->acc.usrnam);
     }
}

VOID
xltescp(VOID)                 /* translate ctrl chars to up-arrow seqs     */
{                             /* for remote sysop setting logon message    */
     CHAR *lptr,*aptr,c;

     setmem(rsyptr->text,MTXSIZ,0);
     rsyptr->text[0]='\r';
     for (lptr=sv.lonmsg,aptr=rsyptr->text+1 ; *lptr != '\0' ; lptr++) {
          if ((c=*lptr) < ' ' && c != '\r') {
              *aptr++='^';
              *aptr++=c|0x40;
          }
          else {
               *aptr++=c;
          }
     }
}

static VOID
prfaxlin(                          /* print one line of remote menu        */
struct usracc *uacptr,             /* pointer to user account to display   */
INT msg,                           /* message to display                   */
INT b1,INT b2, INT b3, INT b4)     /* bit positions to check               */
{
     static CHAR *arrow="=>",*space="  ";

     prfmsg(msg,(axs4op(uacptr,b1) ? arrow : space),
                (axs4op(uacptr,b2) ? arrow : space),
                (axs4op(uacptr,b3) ? arrow : space),
                (axs4op(uacptr,b4) ? arrow : space));
}

VOID
prfaxs(                            /* print access-marked sysop menu       */
struct usracc *uacptr)             /* pointer to user account to display   */
{
     prfaxlin(uacptr,AXSM10,11,41,12,42);
     prfaxlin(uacptr,AXSM11,13,43,44,00);
     prfaxlin(uacptr,AXSM12,71,22,51,00);
     prfaxlin(uacptr,AXSM13,23,52,24,53);
     prfaxlin(uacptr,AXSM14,25,54,31,61);
     prfaxlin(uacptr,AXSM15,32,62,33,63);
     prfaxlin(uacptr,AXSM16,34,64,35,65);
     prfaxlin(uacptr,AXSM17,36,66,73,67);
}

static INT
axs4op(                            /* does user have access to this op?    */
struct usracc *uacptr,             /* pointer to user account to check     */
INT op)                            /* operation to check access to         */
{
     if (sameas(uacptr->userid,"Sysop")
      || (op == 99 && usrptr->flags&MASTER)) {
          return(1);
     }
     return(uacptr->access[op>>4]&(1<<(op%16)));
}

static VOID
togaxs(                            /* toggle user's access to this op      */
struct usracc *uacptr,             /* pointer to user account to toggle    */
INT op)                            /* operation to toggle access to        */
{
     INT opdiv,opmod;

     opdiv=op>>4;
     opmod=op%16;
     if (axs4op(uacptr,op)) {
          uacptr->access[opdiv]&=~(1<<opmod);
     }
     else {
          uacptr->access[opdiv]|=(1<<opmod);
     }
}

static INT
isvalop(                           /* is this a valid op?                  */
CHAR *opstg)                       /* option name to check                 */
{
     INT i;

     for (i=0 ; i < sizeof(valops)/sizeof(struct valop) ; i++) {
          if (sameas(valops[i].opname,opstg)) {
               op=valops[i].op;
               return(valops[i].msgstt);
          }
     }
     return(0);
}

VOID
clsfils(VOID)                 /* close open files if they are open         */
{
     if (rsyptr->sfp != NULL) {
          fclose(rsyptr->sfp);
          rsyptr->sfp=NULL;
          setmem(rsyptr->sfname,FNDSIZE,0);
     }
     if (rsyptr->dfp != NULL) {
          fclose(rsyptr->dfp);
          rsyptr->dfp=NULL;
          setmem(rsyptr->dfname,FNDSIZE,0);
     }
}

INT
fnamchk(                      /* go through file names checking for use    */
CHAR *touse)                  /* name of file to check to see if in use    */
{
     INT i=0;

     while (i < nterms) {
          if (i != usrnum && usroff(i)->state == rmsyst) {
               if (ckfnams(touse,remoff(i)->sfname)
             || ckfnams(touse,remoff(i)->dfname)) {
                    return(1);
               }
          }
          i++;
     }
     return(0);
}

/* class-based Stuff */

static VOID
chkkey(                            /* check proposed key name & add if ok  */
INT remove)                             /* remove if there? (1 or 0)       */
{
     static CHAR key[KEYSIZ];

     strcpy(key,cncall());
     if (!keynam(key)) {
          prfmsg(BADKEY);
     }
     else if (remove) {
          rmvkey(rsyptr->text,key);
          prfmsg(OKGONE);
     }
     else if (!givkey(rsyptr->text,key)) {
          prfmsg(NOSKEY);
     }
     else {
          prfmsg(OKKEY);
     }
     rsprom(RSOP71JM);
}

static VOID
impkey(                            /* import one keyring into another      */
INT remove)                             /* remove the list? (1 or 0)       */
{
     CHAR keyring[UIDSIZ];
     INT len;

     keyring[0]=RINGID;
     strcpy(keyring+1,cncall());
     if (namacls(keyring+1)) {
          if (getlst(keyring,NULL)) {
               len=strlen(&kysbuf[KLSTOF])+1;
               movmem(&kysbuf[KLSTOF],vdatmp,len);
               if (remove) {
                    rmvkey(rsyptr->text,vdatmp);
               }
               else {
                    if (!givkey(rsyptr->text,vdatmp)) {
                         prfmsg(RSOP71JU);
                         return;
                    }
               }
               prfmsg(remove ? OKDKRR : OKDKRA);
          }
          else {
               prfmsg(NOSKYR);
          }
     }
     else {
          prfmsg(INVKYR);
     }
     rsprom(RSOP71JM);
}

static CHAR *
setdft(                            /* show default selection for class     */
CHAR c)
{
     INT tmp;
     CHAR *ptr=NULL;

     if (!(rsyptr->flags&EDTCLS) || c != '.') {
          return(NULL);
     }
     switch (usrptr->substt) {
     case RSOP71J1:
          ptr=rclsptr->limcal == -1 ? "UNLIMITED" : spr("%d",rclsptr->limcal);
          break;
     case RSOP71J2:
          ptr=rclsptr->limday == -1 ? "UNLIMITED" : spr("%d",rclsptr->limday);
          break;
     case RSOP71J3:
          ptr=(rclsptr->flags&KCKOFF) ? "1" : "2";
          break;
     case RSOP71J4:
          ptr=rclsptr->nxtcls[0];
          break;
     case RSOP71J5:
          ptr=rclsptr->msgs[0][0] != '\0' ? "Yes" : "No";
          break;
     case ROP71J7A:
          ptr=rclsptr->flags&CRDXMT ? "Yes" : "No";
          break;
     case RSOP71J8:
          ptr=rclsptr->dbtlmt != 0L ? "Yes" : "No";
          break;
     case RSOP71J9:
          if (rclsptr->dbtlmt) {
               ptr=rclsptr->dbtlmt < 0L ? "UNLIMITED" : l2as(rclsptr->dbtlmt);
          }
          break;
     case RSOP71JA:
          tmp=rclsptr->flags;
          ptr=(tmp&FSTMTH) ? "1" : (tmp&MONDAY) ? "2" :
                   (tmp&NUMDAY) ? "3" : (tmp&HITLMT) ? "4" : "5";
          break;
     case RSOP71JB:
          ptr=rclsptr->fgvday < 1 ? "7" : spr("%d",rclsptr->fgvday);
          break;
     case RSOP71JG:
          ptr=rclsptr->idlday < 1 ? "60" : spr("%d",rclsptr->idlday);
          break;
     case RSOP71JH:
          ptr=rclsptr->dftday < 1 ? "30" : spr("%d",rclsptr->dftday);
          break;
     case RSOP71JI:
          tmp=(rsyptr->chan > 2 ? 3 : rsyptr->chan);
          if (rclsptr->nxtcls[tmp][0] != '\0') {
               ptr=rclsptr->nxtcls[tmp];
          }
          break;
     case RSOP71JJ:
          ptr=rclsptr->msgs[1][0] != '\0' ? "Yes" : "No";
          break;
     }
     return(ptr);
}

VOID
shwdft(VOID)                       /* show default selection for class     */
{
     CHAR *ptr;

     if (!(rsyptr->flags&EDTCLS) || rsyptr->dftinp != '.') {
          return;
     }
     if ((ptr=setdft(rsyptr->dftinp)) != NULL) {
          prfmsg(DFTSEL,ptr);
     }
}

VOID
dspcll(VOID)                       /* display a rough list of classes      */
{
     if (clshead != NULL) {
          prfmsg(RSOP71JO);
          for (clsptr=clshead ; clsptr != NULL ; clsptr=clsptr->next) {
               if (!(clsptr->flags&HASCRD && clsptr->flags&NOCRED)) {
                    prf("%-15.15s ",clsptr->clname);
               }
          }
          prf("\r");
     }
     else {
          prfmsg(NOCLSS);
     }
}

static VOID
dspkys(                            /* display a list of keys in list       */
CHAR *keyr,                             /* keyring name to display (or UID)*/
INT ring)                               /* is it a keyring? (0 or 1)       */
{
     INT i=0;
     CHAR *bas,*ptr,keyring[UIDSIZ];

     if (ring) {
          keyring[0]=RINGID;
          strcpy(keyring+1,keyr);
          if (!namacls(keyring+1)) {
               prfmsg(INVKYR);
               return;
          }
     }
     else {
          strcpy(keyring,keyr);
     }
     if (!getlst(keyring,NULL)) {
          prfmsg(ring ? NOSKYR : UNOTEX2);
          return;
     }
     ptr=&kysbuf[KLSTOF];
     if (ring) {
          prfmsg(RSOP71JR,strupr(keyr));
     }
     else {
          prfmsg(UIDKYS,keyr);
     }
     while (1) {
          bas=ptr;
          while (*ptr != ' ') {
               if (*ptr++ == '\0') {
                    prf("%-16.16s\r",bas);
                    return;
               }
          }
          *ptr='\0';
          prf("%-16.16s ",bas);
          *ptr++=' ';
          if (++i > 3) {
               prf("\r");
               i=0;
          }
     }
}

static INT
canedt(VOID)                       /* can this guy edit a class right now? */
{
     INT i=-1;

     while (++i < nterms) {
          if (i != usrnum && (usroff(i)->state == rmsyst || inedit(i,dwedtj5) ||
              inedit(i,dwedtjj))) {
               if (remoff(i)->flags&(EDTCLS|CRTCLS)) {
                    return(0);
               }
          }
     }
     return(1);
}

static INT
ok2poll(VOID)                      /* enough space to prf for a pollrou?   */
{
     return(btuoba(usrnum) >= outbsz-256);
}

static INT
dnlmnu(                            /* download WGSMENU2.DAT (start or end) */
INT on)                            /*   are we beginning or ending?        */
{
     IMPORT_VARIABLE(DFAFILE*) mnubb;

     if (on && mnudnl == usrnum) {      /* trying a download again...      */
          return(1);
     }
     if ((on && mnudnl != -1) || (!on && mnudnl != usrnum)) {
          return(0);
     }
     if (on) {
          dfaClose(mnubb);
          chmod("wgsmenu2.dat",S_IREAD);
          dfaMode(RONLBV);
          mnubb=dfaOpen("wgsmenu2.dat",sizeof(struct mnupag),NULL);
          dfaMode(PRIMBV);
          mnudnl=usrnum;
     }
     else {
          dfaClose(mnubb);
          chmod("wgsmenu2.dat",S_IREAD|S_IWRITE);
          mnubb=dfaOpen("wgsmenu2.dat",sizeof(struct mnupag),NULL);
          mnudnl=-1;
     }
     return(1);
}

static VOID
usercopy(                          /* copy user information to new User-ID */
CHAR *fromid,
CHAR *toid)
{
     struct usracc *u;
     CHAR newu[UIDSIZ];
     CHAR *rv;

     u=onsysn(fromid,1) ? othuap : NULL;
     stzcpy(newu,toid,UIDSIZ);
     rv=copyuser(fromid,newu,NULL,u);
     setmbk(rsymb);
     if (rv == NULL) {   /* success */
          prfmsg(RSOP71UD);
     }
     else {              /* failure */
          prfmsg(RSOP71UE,rv);
     }
}
