/***************************************************************************
 *                                                                         *
 *   REMSYS2.C                                                             *
 *                                                                         *
 *   Copyright (c) 1987-1997 Galacticomm, Inc.    All Rights Reserved.     *
 *                                                                         *
 *   This is 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"

#define FILREV "$Revision: 13 $"

static VOID rstmsg(INT msgno);
static VOID setmil(INT stt);

extern HMCVFILE rsymb;             /* remote Sysop message file block ptr  */
extern struct acclass * rclsptr;   /* single occurence of class element    */
IMPORT_VARIABLE(INT) errcod;       /* error code used for system shutdown  */
extern INT rsykil;                 /* remote sysop event kill counter      */

VOID
rsop62(VOID)                       /* process source filename for copy     */
{
     strcpy(rsyptr->sfname,cncall());
     if (fnamchk(rsyptr->sfname)) {
          prfmsg(FILINU);
          rsprom(RSOP62);
     }
     else if ((rsyptr->sfp=fopen(rsyptr->sfname,FOPRB)) == NULL) {
          prfmsg(BADFIL,rsyptr->sfname);
          setmem(rsyptr->sfname,FNDSIZE,0);
          rsprom(RSSMNU);
     }
     else {
          rsprom(RSOP62A);
     }
}

VOID
rsop62a(VOID)                      /* handle destination filename for copy */
{
     strcpy(rsyptr->dfname,cncall());
     if (fnamchk(rsyptr->dfname)) {
          prfmsg(FILINU);
          rsprom(RSOP62A);
     }
     else if ((rsyptr->dfp=gcfsopen(rsyptr->dfname,FOPWB,GSH_DENYRW)) == NULL) {
          prfmsg(BADFIL,rsyptr->dfname);
          rsprom(RSSMNU);
          clsfils();
     }
     else {
          rsprom(RSOP62B);
          begin_polling(usrnum,rcpydat);
     }
}

VOID
rsop71(VOID)                       /* handle accounting sub-menu input     */
{
     if (sameto("CLASS",nxtcmd)) {
          rsprom(RSOP71H);
     }
     else if (sameto("POST",nxtcmd)) {
          rsprom(RSOP71A);
     }
     else if (sameto("SHOW",nxtcmd)) {
          dspcll();
          rsprom(RSOP71M0);
     }
     else if (sameto("LIST",nxtcmd)) {
          rsprom(RSOP71B);
     }
     else if (sameto("SWITCH",nxtcmd)) {
          rsprom(RSOP71C);
     }
     else if (sameto("EDIT",nxtcmd)) {
          rsprom(RSOP71D);
     }
     else if (sameto("USERCOPY",nxtcmd)) {
          if (usrptr->flags&MASTER) {
               rsprom(RSOP71U);
          }
          else {
               prfmsg(RSOP71UM);
               cncall();
               rsprom(RSOP71M0);
               return;
          }
     }
     else {
          cncall();
          rsprom(RSOP71M0);
          return;
     }
     cncwrd();
}

VOID
acczero(VOID)                      /* account, margc=0                     */
{
     switch (usrptr->substt) {
     case RSSMNU:
          rsprom((usrptr->flags&INJOIP) ? RSSMNU : RSMENU);
          break;
     case RSOP52A:
          usrptr->flags&=~(NOINJO+MONALL+MONINP);
          echon();
          rsprom(RSSMNU);
          break;
     case RSOP61A:
          clsfils();
     case RSOP23A:
     case RSOP25D:
     case RSOP64A:
          stop_polling(usrnum);
          btuclo(usrnum);
          usrptr->flags&=~NOINJO;
          rsprom(RSSMNU);
     case RSOP62B:
          break;
     case RSOP99B:
          prfmsg(usrptr->substt);
          break;
     default:
          rsprom(usrptr->substt);
     }
}

INT
acconex(VOID)                      /* account, margc=1, sameas x handler   */
{
     if ((rsyptr->flags&(EDTCLS|CRTCLS)) && usrptr->substt >= RSOP71J1
         && usrptr->substt < RSOP71JN) {
          rsyptr->fpos=usrptr->substt;
          rsprom(RSOP71JW);
     }
     else {
          switch (usrptr->substt) {
          case RSMENU:
          case RSSMNU:
               prf("");
               outprf(usrnum);
               return(0);
          case RSOP71A:
          case RSOP71AA:
          case RSOP71AB:
          case RSOP71AC:
          case RSOP71B:
          case RSOP71C:
          case RSOP71C1:
          case RSOP71D:
          case RSOP71H:
          case RSOP71U:
               rsprom(RSOP71M0);
          case RSOP23A:
          case RSOP25D:
          case RSOP52A:
          case RSOP61A:
          case RSOP62B:
          case RSOP64A:
               break;
          case RSOP71I1:
          case RSOP71I2:
               rsprom(RSOP71H);
               break;
          case RSOP71JM:
               rsprom(RSOP71M0);
               if (rsyptr->text[0] != RINGID) {
                    axschg(rsyptr->text);
               }
               break;
          case RSOP71JN:
          case ROP71JN1:
          case RSOP71JQ:
          case RSOP71JS:
          case RSOP71JT:
               rsprom(RSOP71JM);
               break;
          case RSOP71JW:
               rsprom((INT)(rsyptr->fpos));
               break;
          case RSOP99B:
               updaxs();
               break;
          default:
               rsyptr->flags&=~(CRTCLS|EDTCLS);
               clsfils();
               rsprom(RSSMNU);
          }
     }
     return(1);
}

VOID
clsrsy(VOID)                  /* close remote sysop files for shutdown     */
{
     clsmsg(rsymb);
}

INT
rsyevt(VOID)                  /* prepare for an event or cleanup warning   */
{
     if ((--rsykil) <= 0) {
          hupall();
          return(1);
     }
     setmbk(rsymb);
     prfmlt(errcod == 0 ? GOINGD2 : GOINGM,rsykil,(rsykil == 1 ? "" : "s"));
     for (othusn=0 ; othusn < nterms ; othusn++) {
          if (usroff(othusn)->usrcls > SUPIPG) {
               injoth();
          }
     }
     clrmlt();
     rtkick(60,(VOID (*)())rsyevt);
     return(0);
}

INT
emuinu(VOID)                  /* test to see if anyone is using emulation  */
{
     INT i;
     struct user *uptr;

     for (i=0 ; i < nterms ; i++) {
          uptr=usroff(i);
          if (uptr->state == rmsyst) {
               if (uptr->substt == RSOP51A) {
                    return(1);
               }
          }
     }
     return(0);
}

INT
wrdlen(                            /* check the length of the word         */
CHAR *str)                         /* word to check length of              */
{
     INT retval=0;

     while (*str != ' ' && *str != '\0') {
          retval++;
          str++;
     }
     return(retval);
}

INT
anyaxs(                            /* does user have any access at all?    */
struct usracc *uacptr)             /* pointer to user account to check     */
{
     INT i;

     if (sameas(uacptr->userid,"Sysop")) {
          return(1);
     }
     for (i=0 ; i < AXSSIZ ; i++) {
          if (uacptr->access[i]&0xFFFF) {
               return(1);
          }
     }
     return(0);
}

VOID
zaprsy(VOID)                       /* hangup routine for remote sysop      */
{
     INT hldusn;

     if (usrptr->state == rmsyst) {
          clsfils();
          emuinp(1);
     }
     if (usrptr->flags&OPCHAT) {
          if (rmtsys != -1) {
               hldusn=usrnum;
               curusr(rmtsys);
               btutrg(usrnum,0);
               btuscr(usrnum,'\n');
               usrptr->flags&=~(NOINJO|CONCEX);
               setmbk(rsymb);
               prfmsg(RSOP51C);
               outprf(usrnum);
               usrptr->substt=RSSMNU;
               injacr();
               rmtsys=-1;
               curusr(hldusn);
          }
     }
}

INT
ckfnams(                      /* check file names for match without dir stf*/
CHAR *touse,                  /* can we use this file                      */
CHAR *test)                   /* check against this currently used name    */
{
     CHAR *p1,*bg1,*p2,*bg2;

     if (*test == '\0') {
          return(0);
     }
     p1=touse+strlen(touse)-1;
     bg1=p1;
     for ( ; p1 != touse ; p1--) {
          if (isvalds(*p1)) {
               if (p1 != bg1) {
                    p1++;
               }
               break;
          }
     }
     p2=test+strlen(test)-1;
     bg2=p2;
     for ( ; p2 != test ; p2--) {
          if (isvalds(*p2)) {
               if (p2 != bg2) {
                    p2++;
               }
               break;
          }
     }
     return(sameas(p1,p2) ? 1 : 0);
}

SHORT
dwedt11(                           /* when done routine for RSOP11 editing */
SHORT flags)                       /* some flags that are passed back      */
{
     VOID snd2al(CHAR *text);

     setmbk(rsymb);
     usrptr->state=rmsyst;
     if (!(flags&ED_QUITEX)) {
          movmem(rsyptr->text+1,rsyptr->text,MTXSIZ-1);
          rsyptr->text[MTXSIZ-1]='\0';
          xltctls(rsyptr->text);
          usrptr->flags|=NOINJO;
          snd2al(rsyptr->text);
          usrptr->flags&=~NOINJO;
          prfmsg(RSOP11A);
     }
     else {
          prfmsg(MNTSNT);
     }
     rsprom(RSSMNU);
     outprf(usrnum);
     return(1);
}

SHORT
dwedt12(                           /* when done routine for RSOP12 editing */
SHORT flags)                              /* some flags that are passed back */
{
     VOID snd2ch(INT chan,CHAR *text);

     setmbk(rsymb);
     usrptr->state=rmsyst;
     if (!(flags&ED_QUITEX)) {
          if (onsysn(rsyptr->acc.userid,1)) {
               if (!(usroff(othusn)->flags&NOINJO)) {
                    movmem(rsyptr->text+1,rsyptr->text,MTXSIZ-1);
                    rsyptr->text[MTXSIZ-1]='\0';
                    xltctls(rsyptr->text);
                    snd2ch(othusn,rsyptr->text);
                    prfmsg(RSOP12B,othuap->userid);
               }
          }
          else {
               prfmsg(UNOLON,rsyptr->acc.userid);
          }
     }
     else {
          prfmsg(MNTSNT);
     }
     rsprom(RSSMNU);
     outprf(usrnum);
     return(1);
}

SHORT
dwedt13(                           /* when done routine for RSOP13 editing */
SHORT flags)                       /* some flags that are passed back      */
{
     setmbk(rsymb);
     usrptr->state=rmsyst;
     if (!(flags&ED_QUITEX)) {
          movmem(rsyptr->text+1,rsyptr->text,MTXSIZ-1);
          rsyptr->text[MTXSIZ-1]='\0';
          xltctls(rsyptr->text);
          strcpy(sv.lonmsg,rsyptr->text);
          prfmsg(RSOP13A);
     }
     else {
          prfmsg(LONNST);
     }
     rsprom(RSSMNU);
     outprf(usrnum);
     return(1);
}

SHORT
dwedtj5(                           /* whndun routine for RSOP71J5 editing  */
SHORT flags)                       /* some flags that are passed back      */
{
     setmbk(rsymb);
     usrptr->state=rmsyst;
     if (flags&ED_QUITEX) {
          if (rsyptr->flags&EDTCLS) {
               rstmsg(0);
               prfmsg(MSGUNC);
          }
          else {
               rclsptr->msgs[0][0]='\0';
               prfmsg(RSOP71J7);
          }
     }
     rsprom(ROP71J7A);
     outprf(usrnum);
     return(1);
}

SHORT
dwedtjj(                           /* whndun routine for RSOP71JJ editing  */
SHORT flags)                       /* some flags that are passed back      */
{
     setmbk(rsymb);
     usrptr->state=rmsyst;
     if (flags&ED_QUITEX) {
          if (rsyptr->flags&EDTCLS) {
               rstmsg(1);
               prfmsg(MSGUNC);
          }
          else {
               rclsptr->msgs[1][0]='\0';
               prfmsg(MSGDFT);
          }
     }
     rsprom(RSOP71JE);
     outprf(usrnum);
     return(1);
}

static VOID
rstmsg(                            /* restore old value for exit message   */
INT msgno)                              /* message number to restore       */
{
     IMPORT_VARIABLE(DFAFILE*) clsbb;

     dfaSetBlk(clsbb);
     dfaGetEQ(vdatmp,rclsptr->clname,0);
     strcpy(rclsptr->msgs[msgno],((struct acclass *)vdatmp)->msgs[msgno]);
}

VOID
ntfysop(audrec)                    /* notify on-line sysop of audit post   */
CHAR *audrec;
{
     INT usn;
     struct user *usp;
     CHAR ntfybuf[40];

     sprintf(ntfybuf,"***\rAudit Trail: %14.14s ",audrec);
     ASSERT(strlen(ntfybuf) < 40);     /* tied to the variable declaration */
     for (usn=0 ; usn < nterms ; usn++) {
       usp=usroff(usn);
          if (usp->flags&MASTER) {
               if (!(usp->flags&NOINJO) && !(usp->flags&BYEBYE)) {
                    if (usrnum != usn
                       || (status != RELOG && status != CRSTG)) {
                         btuxmt(usn,ntfybuf);
                         btuxmt(usn,audrec+14);
                         btuxmt(usn,"\r");
                         btuxmt(usn,audrec+67);
                         btuxmt(usn,"\r");
                         btuoes(usn,1);
                         usp->flags|=INJOIP;
                    }
               }
          }
     }
}

VOID
rsprom(                            /* reprompt and set new "state"         */
INT msg)                           /*   message number to display          */
{
     INT oldstt;
     INT newlon;

     oldstt=usrptr->substt;
     usrptr->substt=msg;
     switch (msg) {
     case RSMENU:
     case RSSMNU:
          if (oldstt != 0) {
               stop_polling(usrnum);
               condex();
          }
          if (msg == RSSMNU) {
               prfmsg(msg);
               break;
          }
          prfmsg(RSMHDR);
          prfaxs(usaptr);
          if (usrptr->flags&MASTER) {
               prfmsg(SOPT99);
          }
          prfmsg(usrptr->substt=RSSMNU);
          break;
     case RSOP11:
          cncall();
          prf("");
          outprf(usrnum);
          newlon=0;
          newlon|=(ED_CLRTOP|ED_CLRTXT);
          bgnedt(MTXSIZ,rsyptr->text,0,NULL,dwedt11,newlon);
          return;
     case RSOP13:
          cncall();
          prf("");
          outprf(usrnum);
          newlon=0;
          if (sv.lonmsg[0] == '\0') {
               newlon|=(ED_CLRTOP|ED_CLRTXT);
          }
          else {
               xltescp();
          }
          bgnedt(MTXSIZ,rsyptr->text,0,NULL,dwedt13,newlon);
          return;
     case RSOP71AC:
          prfmsg(msg,rsyptr->text,(rsyptr->chan ? "PAID" : "FREE"),
                        rsyptr->acc.userid);
          break;
     case RSOP71JN:
          prfmsg((rsyptr->flags&(CRTCLS|EDTCLS|EDTKYR)) ? msg : ROP71JN1);
          break;
     case RSOP24:
          dsponl();
          break;
     case RSOP32A:
          prfmsg(msg,(rsyptr->acc.flags&SUSPEN) ? "unsuspend" : "suspend",
                       rsyptr->acc.userid);
          break;
     case RSOP33A:
          prfmsg(msg,(rsyptr->acc.flags&UNDAXS) ? "unprotect" : "protect",
                       rsyptr->acc.userid);
          break;
     case RSOP412:
          dspsts();
          break;
     case RSOP422:
          dspmdu();
          break;
     case RSOP43:
          dspsaa();
          break;
     case RSOP442:
          dspcus();
          break;
     case RSOP51:
          if (emuinu()) {
               rblwof(EMUINU);
          }
          else {
               prfmsg(msg);
          }
          break;
     case RSOP52:
          bgnmon(msg,MONALL);
          break;
     case RSOP53:
          bgnmon(msg,MONINP);
          break;
     case RSOP71C4:
          prfmsg(msg,rsyptr->cltptr->dftday);
          break;
     case RSOP71H:
          rsyptr->flags&=~(CRTCLS|EDTCLS);
          prfmsg(msg);
          break;
     case RSOP71I:
          prfmsg(msg,rclsptr->clname);
          break;
     case RSOP71I1:
     case RSOP71I2:
          prfmsg(msg,rsyptr->cltptr->clname);
          break;
     case RSOP71JE:
          if (rclsptr->flags&CRDXMT) {
               prfmsg(msg);
          }
          else {
               prfmsg(rclsptr->dbtlmt != 0L ? RSOP71JF : ROP71JE2);
          }
          break;
     case RSOP71JK:
          prfmsg(msg,rsyptr->sfname,rsyptr->dfname);
          break;
     case RSOP71JV:
          prfmsg((rsyptr->flags&EDTCLS) ? ROP71JVE : msg);
          break;
     case RSOP71JW:
          prfmsg((rsyptr->flags&EDTCLS) ? ROP71JWE : msg);
          break;
     case RSOP99B:
          prfmsg(EDTING,rsyptr->acc.userid);
          prfaxs(&rsyptr->acc);
          prfmsg(UHSYSA2,(rsyptr->acc.flags&HASMST ? "=>" : "  "));
          prfmsg(msg);
          break;
     default:
          prfmsg(msg);
     }
     setmil(usrptr->substt);
     rsyptr->dftinp=getdft();
     if (msg >= RSOP71J1 && msg < RSOP71JL) {
          shwdft();
     }
}

static VOID
setmil(                            /* set maximum input length             */
INT stt)                           /* what state to base max input length  */
{
     INT max;

     switch (stt) {
     case RSOP11:
     case RSOP13:
          return;
     case RSOP71AA:
          max=8;
          break;
     case RSOP61:
     case RSOP62:
     case RSOP62A:
     case RSOP63:
     case RSOP65:
     case RSOP66:
          max=FNDSIZE-1;
          break;
     case RSOP64:
          max=FNDSIZE-6;
          break;
     case RSOP71C:
     case RSOP71D:
     case RSOP71U:
          max=UIDSIZ-1;
          break;
     case RSOP71B:
     case RSOP71C1:
     case RSOP71H:
          max=KEYSIZ-1;
          break;
     case RSOP71I1:
     case RSOP71J3:
     case RSOP71JA:
     case RSOP71JE:
          max=2;
          break;
     case RSOP71I:
     case RSOP71I2:
     case RSOP71J5:
     case RSOP71JJ:
     case RSOP71JK:
     case ROP71J7A:
     case RSOP71J8:
     case RSOP71JV:
     case RSOP71JW:
          max=4;
          break;
     case RSOP71JB:
     case RSOP71JG:
     case RSOP71JH:
          max=6;
          break;
     case RSOP71JN:
          max=8;
          break;
     case RSOP71J1:
     case RSOP71J2:
     case RSOP71J9:
          max=10;
          break;
     case RSOP71JI:
     case RSOP71JM:
     case RSOP71JQ:
     case RSOP71JS:
     case RSOP71J4:
     case RSOP71JT:
          max=KEYSIZ;
          break;
     case RSOP731:
          max=5;
          break;
     default:
          max=DFTIMX;
     }
     btumil(usrnum,max);
}
