/***************************************************************************
 *                                                                         *
 *   CSRSYS.C                                                              *
 *                                                                         *
 *   Copyright (c) 1994-1997 Galacticomm, Inc.    All rights reserved.     *
 *                                                                         *
 *   This is the Remote System Console Agent module.                       *
 *                                                                         *
 *                                                - Joe Delekto 1/10/96    *
 *                                                                         *
 ***************************************************************************/

#ifdef GCWINNT
#include <windows.h>
#endif // GCWINNT
#include <sys\stat.h>
#include "gcomm.h"
#include "majorbbs.h"
#include "gcsasys.h"                                                      
#include "gcspsrv.h"
#include "oprlow.h"
#include "galrsy.h"
#include "remote.h"

#define   FILREV "$Revision: 52 $"
#define   CSWIDTH        81        /*  Width of the C/S Screen             */

#define   RSYAPN "GALRSY\0\0"      /* remote console application appid     */

#define   RSPOK  "ok"              /* ok, write had no problems            */
#define   RSPERR "error"           /* error, something went awry           */

#define   MENUDAT "wgsmenu2.dat"   /* menu data file name             */
#define   BBSNMN "newmenu.$$$"     /* temporary save file for bbsmenu.dat  */

                                        /* special args for std resp funcs */
#define   RAWMSG 1                 /* do the prfmsg() for me               */
#define   CKDMSG 2                 /* prfbuf already setup, (for args)     */

#define   NOCODE  0                /* no special code for response         */

#define   dynpak(x) "sa:"x         /* convert to full dynapak name         */
#define   fdynpak(x) "saf:"x       /* convert to full file dynapak name    */

#define   rsytmp(x) ((struct x *)vdatmp)     /* volatile fapdef structure  */
#define   rsycmn ((struct rsymem *)mrqptr)   /* command info between paks  */
#define   rsyarg (((struct rsymem *)mrqptr)->mrqu.rsyargs) /* dynapak args */
#define   rsyevn (((struct rsymem *)mrqptr)->mrqu.rsyevts) /* event info   */
#define   rsyclp (((struct rsymem *)mrqptr)->mrqu.rsyproc) /* cmd interp.  */
#define   rsyaud (((struct rsymem *)mrqptr)->mrqu.rsyaudt) /* audit trail  */
#define   rsyfnd (((struct rsymem *)mrqptr)->mrqu.rsysrch) /* account srch */

                                        /* special response building ops   */
#define   clear(s) *(s)='\0'                      /* set first char '0'    */
#define   cpyrsp(s) stlcpy(rsptmp,(s),MAXDPKV)    /* start new response str*/
#define   delimiter() stlcat(rsptmp,"\t",MAXDPKV) /* add delimiter to rsp  */
#define   catrsp(s) stlcat(rsptmp,(s),MAXDPKV)    /* add to response str   */
#define   cpyvda(s) stlcpy(vdatmp,(s),MAXDPKV)    /* start new response str*/
#define   vdelimiter() stlcat(vdatmp,"\t",MAXDPKV)/* add delimiter to rsp  */
#define   catvda(s) stlcat(vdatmp,(s),MAXDPKV)    /* add to response str   */


#define   nxtarg(s) skpwht(skpwrd(s))   /* point to next argument          */
#define   nularg(s) *(skpwrd(s))='\0'   /* null terminate an argument      */

#ifdef GCWINNT
#define OSTYPE "Windows NT"   /* type of OS Console is running on          */
#else
#define OSTYPE "DOS"          /* type of OS Console is running on          */
#endif

#define FLDSEP "\x01"         /* internal field separator for strings      */

#define POLLED "poll"         /* used to override realtime operations      */

#define SECURE "secure"       /* get security information on the server    */
#define INTERP "interp "      /* command line interpreter information      */
#define INTPRC "intprc "      /* process an outstanding command            */
#define GETCWD "getcwd"       /* get the current working directory         */
#define NXTUID "nxtuid "      /* get next user id from server              */
#define STRMON "strmon"       /* start system monitor (realtime)           */
#define STPMON "stpmon"       /* stop system monitor                       */
#define SUMINF "suminf"       /* get summary information from server       */
#define SVRLOD "svrlod"       /* get server load information               */
#define NUMTRM "numtrm"       /* get nterms on the server                  */
#define SYSABT "sysabt"       /* get about information for system          */
#define ABTRFS "abtrfs"       /* refresh pertinent about information       */
#define USRSON "usrson"       /* get a list of users online                */
#define SCHCHR "schchr"       /* get schochl() characters and attribs      */
#define SCHLNG "schlng"       /* get schochl() legend text                 */
#define CHROFF "chroff"       /* turn shochl() monitor off                 */
#define LNGOFF "lngoff"       /* turn shochl() legend monitor off          */
#define KILUSR "kilusr"       /* kill a user's channel, if the user in on  */
#define PSTUSR "pstusr"       /* post credits to a particular user         */
#define MSGUSR "msgusr"       /* pop a message to a particular user        */
#define MSGALL "msgall"       /* pop a message to all users                */
#define SYSEVT "sysevt"       /* system event is occurring                 */
#define KILSYS "kilsys"       /* system is being killed                    */
#define UPLFIL "uplfil "      /* upload a file to the system               */
#define DNLFIL "dnlfil "      /* download a file from the system           */
#define AUDSTR "audstr"       /* start audit trail                         */
#define AUDSTP "audstp"       /* stop the audit trail                      */
#define AUDSCR "audscr "      /* scroll the audit trail (line or page)     */
#define AUDGET "audget "      /* get audit trail text                      */
#define AUDNOT "audnot"       /* audit trail information avail. notific.   */
#define GETSTT "getstt "      /* get statistics information                */
#define SEARCH "search "      /* search dynapak name                       */
#define SRCHNF "srchnf"       /* return resulting information from search  */
#define LOGMSG "logmsg"       /* new system logon announcement             */
#define CHANOP "chanop "      /* perform an operation on a channel         */
#define UPLMNU "uplmnu"       /* upload a new wgsmenu2.dat                 */
#define USRCMT "sau:usrcmt"   /* edit/save user comments on server         */
#define VLDPTH "vldpth"       /* determine if a give path spec is valid    */

#define HRTONE 0x00010000UL   /* 1 second, in 1/65536 units (ala hrtval()) */

#define WAIT   0              /* wait for free qroom                       */
#define NOWAIT 1              /* qroom is available                        */

#define DIRCMD 1              /* list directory command                    */
#define TYPCMD 2              /* type out a file command                   */
#define CPYCMD 3              /* copy files command                        */
#define RENCMD 4              /* rename file command                       */
#define MKDCMD 5              /* make directory command                    */
#define RMDCMD 6              /* remove directory command                  */
#define DELCMD 7              /* delete file command                       */
#define EXTCMD 8              /* exit command interpreter command          */
#define UPLCMD 9              /* upload files command                      */
#define DNLCMD 10             /* download files command                    */
#define LNCCMD 11             /* launch a file command                     */

#define AUDUP    0            /* scroll the audit trail up                 */
#define AUDDN    1            /* scroll the audit trail down               */
#define AUDHOME  2            /* move audit trail to the top               */
#define AUDEND   3            /* move audit trail to the end               */
#define AUDPGUP  4            /* move audit trail up NUMADT elements       */
#define AUDPGDN  5            /* move audit trail down NUMADT elements     */

#define FLDUID 0              /* search for User-ID string                 */
#define FLDNAM 1              /* search for user name string               */
#define FLDPWD 2              /* search for password string                */
#define FLDCMP 3              /* search for company name, addr1            */
#define FLDAD1 4              /* search for address field one              */
#define FLDAD2 5              /* search for address field two              */
#define FLDAD3 6              /* search for address field three            */
#define FLDPHO 7              /* search for phone number string            */
#define FLDSYS 8              /* search for system type                    */
#define FLDAGE 9              /* search for age                            */
#define FLDSEX 10             /* search for sex                            */
#define FLDCLS 11             /* search for users' current class           */
#define FLDTCR 12             /* search for total credits                  */
#define FLDTPD 13             /* search for total paid credits             */
#define FLDCRD 14             /* search for credits available now          */
#define FLDCDT 15             /* search for creation date                  */
#define FLDUDT 16             /* search for last used date                 */
#define FLDDAY 17             /* search for number of days left in class   */

#define LGNSIZ 47                       /* size of label text for legend   */
#define LNMSIZ 34                       /* size of long value string       */
#define SSTSIZ 256                      /* maximum size of search string   */
#define NUMADT 8                        /* number of audit trail entries   */
#define CPYSIZ vdasiz                   /* size of chunk for copying files */

#define WRKDON 0                        /* no longer copying any files     */
#define WRKING 1                        /* currently copying a file        */

#define CHRFLG 0x01                     /* user is getting shochl() chars  */
#define LGDFLG 0x02                     /* user is getting legend info     */
#define AUDFLG 0x04                     /* user getting audit trail notif. */

#define DIRREQ 0x01                     /* this is a directory request     */
#define CPYREQ 0x02                     /* this is a copy file request     */
#define DELREQ 0x04                     /* this is a delete file request   */
#define TYPREQ 0x08                     /* this is a type file request     */
#define DNLREQ 0x10                     /* this is a download request      */
#define UPLREQ 0x20                     /* this is an upload request       */

#define LIUSTT 0                        /* lines in use statistics         */
#define SEBSTT 1                        /* sessions/Baudrate statistics    */
#define TUHSTT 2                        /* time used/hour stats            */
#define TUGSTT 3                        /* time used/group # stats         */
#define CUHSTT 4                        /* credits used/hour stats         */
#define CUGSTT 5                        /* credits used/Group # stats      */
#define DEMSTT 6                        /* demographics statistics         */
#define CLSSTT 7                        /* class statistics                */
#define MSCSTT 8                        /* miscellaneous statistics        */

#define DIRTRK 0x0001
#define CPYTRK 0x0002L                  /* track use of copy command       */
#define DELTRK 0x0004L                  /* track use of delete command     */
#define PUTTRK 0x0008L                  /* track use of upload command     */
#define GETTRK 0x0010L                  /* track use of download command   */
#define MDTRK  0x0020L                  /* track use of directory create   */
#define RDTRK  0x0040L                  /* track use of directory destroy  */
#define RENTRK 0x0080L                  /* track use of file rename        */
#define TYPTRK 0x0100L                  /* track use of type command       */
#define LNCTRK 0x0200L                  /* track use of lauch command      */
#define PSTTRK 0x0400L                  /* track use of credit posting     */
#define KILTRK 0x0800L                  /* track use of channel killing    */
#define EVTTRK 0x1000L                  /* track use of event takedown     */
#define KSYTRK 0x2000L                  /* track use of system kill        */
#define LOGTRK 0x4000L                  /* track use of logon announcement */
#define CHPTRK 0x8000L                  /* track use of channel operations */
#define MSGTRK 0x00010000L              /* track messages sent to users    */
#define AMSTRK 0x00020000L              /* track messages sent to all      */

CHAR *rsckey;                           /* key required to use remote agent*/

static GBOOL upldmnu=FALSE;             /* uploading wgsmenu2.dat?         */

static CHAR *abttl= SVR_NAME " -- Online Applications Server\n"
               "Copyright (c) 1986-1999 Galacticomm, Inc.  All Rights Reserved.";

static CHAR *crdts= SVR_NAME " developed by:\n\nJack Alvrus, Joe Delekto, "
                              "Phil Henning,  Wally Muharsky, Nathan Osterc, "
                              "Richard Skurnick, and Vincent Toscano, \n\n";

static CHAR *cprit="Portions of this program Copyright 1982-1995\n"
     "Btrieve Technologies, Inc.  All Rights Reserved";

static char *months[]={
     "","January's","February's","March's","April's","May's","June's","July's",
     "August's","September's","October's","November's","December's"
};

static INT kilmins[]={1,2,5,10,-1,0}; /* minutes until system shutdown     */
static INT glthrv[5][3]={{0,1,0},{0,0,1},{1,0,0},{0,1,1},{1,1,0}}; /* direc*/

static CHAR rsyflg[256];           /* rsyflags which set for unsolc. dpak  */

static UINT mytrack;               /* date of last zeroing of statistics   */

static struct chninf {             /* channel legend character map struct  */
     CHAR legend[256];             /*   legend characters                  */
     CHAR attrib[256];             /*   attribute (color) information      */
} chnlng;

static CHAR olegend[256];          /* old legend characters                */
static CHAR oattrib[256];          /* old legend character attributes      */

ULONG trkflgs;                     /* flags used during operation tracking */
extern INT rsykil;

IMPORT_VARIABLE(struct clstab*) clshead; /* pointer to class info in memory  */

IMPORT_VARIABLE(UINT) maxspd;      /* maximum baudrate                     */
IMPORT_VARIABLE(UINT) maxpol;      /* poll rate if necessary               */

IMPORT_VARIABLE(INT) curdlls;      /* count of DLLs loaded                 */
IMPORT_VARIABLE(INT) hichp1;       /* highest channel number plus one      */
IMPORT_VARIABLE(INT) errcod;       /* error code used for system shutdown  */

struct clstab *clmptr;             /* temporary ptr to class info          */

IMPORT_VARIABLE(DFAFILE*) keysbb;  /* keys database pointer                */
IMPORT_VARIABLE(DFAFILE*) clsbb;   /* class database pointer               */
IMPORT_VARIABLE(DFAFILE*) xrfbb;   /* user-id x-ref database pointer       */

IMPORT_VARIABLE(INT) sysload[60];  /* lines in use from SUMMARY.C load grph*/

struct load {
     SHORT loads[60];              /* load per minute on the server        */
};

struct rsymem {
     CHAR mysuffix[SFXSIZ];             /* my suffix for identification    */
     LONG myflags;                      /* flags to determine my purpose   */
     union {
          struct {                      /* general purpose argument memory */
               INT real;                /*   were credits paid or free?    */
               CHAR usrnam[UIDSIZ];     /*   username passed as argument   */
               CHAR crdstr[LNMSIZ];     /*   string used for credit posting*/
          } rsyargs;
          struct {                      /* remote sysop events information */
               INT chan;                /*   hold channel to perform event */
               INT timkil;              /*   time to kill channel          */
          } rsyevts;
          struct {                      /* remote sysop command interpreter*/
               INT request;             /*   my request id for identity    */
               INT funct;               /*   my purpose in the scheme      */
               INT status;              /*   current processing status     */
               GBOOL multifil;          /*   flag for multiple file copy   */
               FILE *sfptr;             /*   source file pointer           */
               FILE *dfptr;             /*   destination file pointer      */
               struct ffblk dirblk;     /*   structure used for directory  */
               CHAR sfname[FNDSIZE];    /*   file name 1 for general use   */
               CHAR sfpath[FNDSIZE];    /*   src path name for multi-copy  */
               CHAR dfname[FNDSIZE];    /*   file name 2 for general use   */
               CHAR dfpath[FNDSIZE];    /*   dest path name for multi-copy */
          } rsyproc;
          struct {                      /* remote sysop audit trail info   */
               INT request;             /*   saved outstanding write reqid */
               GBOOL audmov;            /*   audit trail moved off bottom? */
               ULONG lastVisible;       /*   rec # of last visible entry   */
          } rsyaudt;
          struct {                      /* remote sysop account search eng.*/
               INT field;               /*   field which is being searched */
               INT relate;              /*   ==, >, <, >=, <= operations   */
               LONG fpos;               /*   position in the account dbase */
               CHAR srchstg[SSTSIZ];    /*   string to be searching for    */
          } rsysrch;
     } mrqu;
};
IMPORT_FUNCTION(VOID,shochl_hook)(INT chan); /* Our own hook to shochl()! */
IMPORT_FUNCTION(VOID,rsyfad_hook)(VOID); /* Our hook to audit trail disp. */
IMPORT_FUNCTION(GBOOL,swtcls_hook)(struct usracc *usract,CHAR *usrcls,INT days);

static VOID rsyread(INT direction,struct saunam *dpknam);
static VOID rsywrite(struct saunam *dpknam,USHORT length,VOID *value);
static VOID rsyxdone(VOID);
static VOID rsyabort(VOID);

struct agent rsyagt={              /* agent information structure          */
     RSYAPN,                       /*   appid                              */
     rsyread,                      /*   read-dynapak function pointer      */
     rsywrite,                     /*   write-dynapak function pointer     */
     rsyxdone,                     /*   file xfer-done function pointer    */
     rsyabort                      /*   abort-request function pointer     */
};

extern CHAR *osversn(VOID);        /* get os version from about.c          */

static GBOOL doswitch(struct usracc *usract,CHAR *usrcls,INT days);
static VOID initaud(VOID);
static VOID topaud(VOID);
static VOID scraud(INT num);
static VOID getaud(VOID);
static VOID rsyfadd(VOID);
static VOID legends(INT chan);
static VOID shwchr(INT chan);
static VOID shwlng(INT chan);
static VOID getntrm(VOID);
static VOID getsyst(VOID);
static VOID osabt(VOID);
static VOID listdir(VOID);
CHAR * stpname(CHAR *fname);
CHAR * makpath(CHAR *fname);
CHAR * stppath(CHAR *fname);
CHAR * fixfil(CHAR *fname);
GBOOL iswild(CHAR *fname);
static GBOOL strtfil(VOID);
static GBOOL strttyp(VOID);
static GBOOL strtcpy(VOID);
static GBOOL strtdnl(VOID);
static GBOOL prepcpy(VOID);
static GBOOL strtdel(VOID);
static GBOOL lockmnu(GBOOL on);
static VOID dodelt(VOID);
static VOID docopy(VOID);
static VOID dotype(VOID);
static VOID dodnl(VOID);
static VOID accsrch(VOID);
static GBOOL chkstr(CHAR *string);
static GBOOL chkcdt(LONG credits);
static GBOOL chkdte(INT date);
static GBOOL chknum(INT number);
static VOID demstt(VOID);
static VOID clsstt(VOID);
static VOID mscstt(VOID);
static VOID initgrph(VOID);
static VOID liugph(VOID);
static VOID sebgph(VOID);
static VOID tuhgph(VOID);
static VOID tuggph(VOID);
static VOID cuhgph(VOID);
static VOID cuggph(VOID);
static struct clstab *nxtcls(struct clstab *from);
char * rtmfmt(ULONG ntval);
static VOID genabt(VOID);

VOID
inicsrsy(VOID)                /* called from remsys init, mcv file set up  */
{
     INT index;

     rsckey=stgopt(RSCKEY);
     trkflgs=0L;
     if (ynopt(TRKDIR)) {
          trkflgs|=DIRTRK;
     }
     if (ynopt(TRKCPY)) {
          trkflgs|=CPYTRK;
     }
     if (ynopt(TRKDEL)) {
          trkflgs|=DELTRK;
     }
     if (ynopt(TRKPUT)) {
          trkflgs|=PUTTRK;
     }
     if (ynopt(TRKGET)) {
          trkflgs|=GETTRK;
     }
     if (ynopt(TRKMD)) {
          trkflgs|=MDTRK;
     }
     if (ynopt(TRKRD)) {
          trkflgs|=RDTRK;
     }
     if (ynopt(TRKREN)) {
          trkflgs|=RENTRK;
     }
     if (ynopt(TRKTYP)) {
          trkflgs|=TYPTRK;
     }
     if (ynopt(TRKLNC)) {
          trkflgs|=LNCTRK;
     }
     if (ynopt(TRKPST)) {
          trkflgs|=PSTTRK;
     }
     if (ynopt(TRKKIL)) {
          trkflgs|=KILTRK;
     }
     if (ynopt(TRKEVT)) {
          trkflgs|=EVTTRK;
     }
     if (ynopt(TRKKSY)) {
          trkflgs|=KSYTRK;
     }
     if (ynopt(TRKLOG)) {
          trkflgs|=LOGTRK;
     }
     if (ynopt(TRKCHP)) {
          trkflgs|=CHPTRK;
     }
     if (ynopt(TRKMSG)) {
          trkflgs|=MSGTRK;
     }
     if (ynopt(TRKAMS)) {
          trkflgs|=AMSTRK;
     }
     register_agent(&rsyagt);
     dclmrq(sizeof(struct rsymem));
     dclvda(MAXDPKV);
     for (index=0 ; index < 256 ; index++) {
          rsyflg[index]=0;
          olegend[index]=0;
          oattrib[index]=0;
     }
     shochl_hook=legends;
     swtcls_hook=doswitch;
     rsyfad_hook=rsyfadd;
}

static VOID
rsyread(
INT direction,
struct saunam *dpknam)
{
     INT index,outer,inner,cntr,comval,savreq,clireq;
     struct user *uptr;
     struct usracc nxtusr,*aptr;
     struct load *ld;
     CHAR *dpkstg,*usrid,*arg1,*arg2;
     ULONG eavl;
     GBOOL result;

     if (stdchk(rsckey)) {
          stlcpy(rsycmn->mysuffix,dpknam->suffix,SFXSIZ);
          *namtmp=*dpknam;
          dpkstg=cnvs2d(namtmp);
          if (sameto(dynpak(NXTUID),dpkstg)) {
               if (ISMASTER() || ACCESS(OPDETL)) {
                    usrid=nxtarg(dpkstg);
                    dfaSetBlk(accbb);
                    switch (direction) {
                    case 0:
                         result=dfaAcqEQ(&nxtusr,usrid,0);
                         break;
                    case 1:
                         result=dfaAcqGT(&nxtusr,usrid,0);
                         break;
                    case -1:
                         result=dfaAcqLT(&nxtusr,usrid,0);
                         break;
                    }
                    clear(rsptmp);
                    if (result) {
                         cpyrsp(nxtusr.userid);
                         stlcpy(namtmp->suffix,NXTUID,SFXSIZ);
                         stlcat(namtmp->suffix,nxtusr.userid,SFXSIZ);
                         rsp2read(namtmp,STGLEN,rsptmp,NULL);
                         return;
                    }
                    else {
                         rejectreq();
                    }
                    dfaRstBlk();
               }
               else {
                    rejectreq();
               }
               return;
          }
          if (direction == 0) {
               if (samepato(dynpak(LOGMSG),dpkstg)) {
                    if (ISMASTER() || ACCESS(OPLOGN)) {
                         rsp2read(NULL,STGLEN,sv.lonmsg,NULL);
                         return;
                    }
               }
               if (samepato(dynpak(SECURE),dpkstg)) {
                    clear(rsptmp);
                    if (vispsw) {
                         catrsp(RSPOK);
                    }
                    delimiter();
                    if (ISMASTER()) {
                         catrsp(RSPOK);
                    }
                    delimiter();
                    if (ISMASTER()) {
                         catrsp(RSPOK);
                    }
                    delimiter();
                    for (index=0 ; index < AXSSIZ ; index++) {
                         catrsp(spr("%d",usaptr->access[index]));
                         if (index < (AXSSIZ-1)) {
                              delimiter();
                         }
                    }
                    rsp2read(NULL,STGLEN,rsptmp,NULL);
                    return;
               }
               if (samepato(dynpak(CHANOP),dpkstg)) {
                    if (ISMASTER() || ACCESS(OPCHNG)) {
                         clear(rsptmp);
                         arg1=nxtarg(dpkstg);
                         arg2=nxtarg(arg1);
                         nularg(arg1);
                         nularg(arg2);
                         comval=atoi(arg1);
                         cntr=atoi(arg2);
                         if ((cntr < 0) || (cntr > 255)) {
                              rejectreq();
                              return;
                         }
                         if ((inner=usridx(cntr)) == -1) {
                              cpyrsp(RSPERR);
                              delimiter();
                              catrsp("Sorry, but no operations can be "
                                     "performed on that channel.");
                              rsp2read(NULL,STGLEN,rsptmp,NULL);
                              return;
                         }
                         if (usroff(inner)->usrcls != VACANT && comval != 3) {
                              cpyrsp(RSPERR);
                              delimiter();
                              catrsp("Sorry, but that channel is currently "
                                     "active.  First disconnect any user from "
                                     "that channel and try again.");
                              rsp2read(NULL,STGLEN,rsptmp,NULL);
                              return;
                         }
                         switch(comval) {
                         case 0:
                              comval=BUSYRS;
                              cpyvda("BUSY-OUT");
                              break;
                         case 1:
                              comval=NANSRS;
                              cpyvda("NO-ANSWER");
                              break;
                         case 2:
                              comval=NORMRS;
                              cpyvda("NORMAL");
                              break;
                         case 3:
                              btuinj(inner,RING);
                              cpyrsp(RSPOK);
                              rsp2read(NULL,0,NULL,NULL);
                              return;
                         default:
                              comval=NORMRS;
                              cpyvda("NORMAL");
                              break;
                         }
                         rsmodes[inner]=comval;
                         kilchn(inner);
                         cpyrsp(RSPOK);
                         if (trkflgs&CHPTRK) {
                              shocst("REMOTE CHANNEL OPERATION",
                                     "[%-33s]  Channel: %-2x  Op: %-9s",
                                     usaptr->userid,cntr,vdatmp);
                         }
                         rsp2read(NULL,0,NULL,NULL);
                         return;
                    }
               }
               if (samepato(dynpak(STRMON),dpkstg)) {
                    if (ISMASTER() || ACCESS(OPMNTR)) {
                         usrptr->flags|=(NOINJO+MONALL);
                         rsp2read(NULL,0,NULL,NULL);
                         return;
                    }
               }
               else if (samepato(dynpak(STPMON),dpkstg)) {
                    if (ISMASTER() || ACCESS(OPMNTR)) {
                         usrptr->flags&=~(NOINJO+MONALL+MONINP);
                         rsp2read(NULL,0,NULL,NULL);
                         return;
                    }
               }
               else if (samepato(dynpak(SUMINF),dpkstg)) {
                    if (ISMASTER() || ACCESS(OPAUDT)) {
                         clear(rsptmp);
#ifdef GCWINNT
                         catrsp("N/A");
#else
                         DosMemAvail(&eavl);
                         catrsp(dbytes(eavl/1024));
#endif
                         delimiter();
                         eavl=dskfre(".");
                         catrsp(dbytes(eavl));
                         delimiter();
                         catrsp(rtmfmt(rsptim));
                         delimiter();
                         eavl=(ULONG)sv.emlopn;
                         catrsp(ultoa(eavl,vdatmp,10));
                         delimiter();
                         eavl=(ULONG)sv.sigopn;
                         catrsp(ultoa(eavl,vdatmp,10));
                         delimiter();
                         catrsp(l2as(sv.msgtot));
                         delimiter();
                         eavl=(ULONG)sv2.numact;
                         catrsp(ultoa(eavl,vdatmp,10));
                         delimiter();
                         catrsp(l2as(sv2.totcalls));
                         delimiter();
                         catrsp(l2as(sv.uplds));
                         delimiter();
                         catrsp(l2as(sv.dwnlds));
                         delimiter();
                         catrsp(itoa(dtmin(now()),vdatmp,10));
                         delimiter();
                         catrsp(nctime(now()));
                         delimiter();
                         catrsp(ncdatel(today()));
                         rsp2read(NULL,STGLEN,rsptmp,NULL);
                         return;
                    }
               }
               else if (samepato(dynpak(SVRLOD),dpkstg)) {
                    if (ISMASTER() || ACCESS(OPAUDT)) {
                         ld=(struct load *)vdatmp;
                         for (index=0 ; index < 60 ; index++) {
                              ld->loads[index]=sysload[index];
                         }
                         rsp2read(namtmp,sizeof(struct load),ld,shortsFDA);
                         return;
                    }
               }
               else if (samepato(dynpak(NUMTRM),dpkstg)) {
                    if (ISMASTER() || ACCESS(OPAUDT)) {
                         clear(rsptmp);
                         getntrm();
                         rsp2read(namtmp,STGLEN,rsptmp,NULL);
                         return;
                    }
               }
               else if (samepato(dynpak(SYSABT),dpkstg)) {
                    genabt();
                    osabt();
                    rsp2read(namtmp,STGLEN,rsptmp,NULL);
                    return;
               }
               else if (samepato(dynpak(ABTRFS),dpkstg)) {
                    clear(rsptmp);
                    catrsp(OSTYPE);
                    delimiter();
                    getsyst();
                    rsp2read(namtmp,STGLEN,rsptmp,NULL);
                    return;
               }
               else if (samepato(dynpak(USRSON),dpkstg)) {
                    if (ISMASTER() || ACCESS(OPUSRS)) {
                         clear(rsptmp);
                         for (index=0 ; index < nterms ; index++) {
                              uptr=usroff(index);
                              aptr=uacoff(index);
                              switch (incusr(index,TRUE,TRUE)) {
                              case UIDNGD:
                              case VACANT:
                              case ONLINE:
                              case SUPIPG:
                                   break;
                              case BBSPRV:
                                   catrsp(aptr->userid);
                                   delimiter();
                                   catrsp(spr("%2x",channel[index]));
                                   delimiter();
                                   catrsp(module[uptr->state]->descrp);
                                   delimiter();
                                   delimiter();
                                   delimiter();
                                   catrsp(spr("%d",(uptr->minut4+2)>>2));
                                   delimiter();
                                   if (index < (nterms-1)) {
                                        stlcat(rsptmp,FLDSEP,MAXDPKV);
                                   }
                                   break;
                              case SUPLON:
                              case SUPLOF:
                              case ACTUSR:
                                   catrsp(aptr->userid);
                                   delimiter();
                                   catrsp(spr("%2x",channel[index]));
                                   delimiter();
                                   catrsp(module[uptr->state]->descrp);
                                   delimiter();
                                   catrsp(aptr->curcls);
                                   delimiter();
                                   catrsp(l2as(aptr->creds));
                                   delimiter();
                                   catrsp(spr("%d",(uptr->minut4+2)>>2));
                                   delimiter();
                                   if (usroff(index)->flags&INVISB) {
                                        catrsp("Y");
                                   }
                                   else {
                                        catrsp("N");
                                   }
                                   if (index < (nterms-1)) {
                                        stlcat(rsptmp,FLDSEP,MAXDPKV);
                                   }
                                   break;
                              }
                         }
                         rsp2read(namtmp,STGLEN,rsptmp,NULL);
                         return;
                    }
               }
               else if (samepato(dynpak(SCHCHR),dpkstg)) {
                    if (ISMASTER() || ACCESS(OPAUDT)) {
                         cntr=0;
                         for (outer=0 ; outer < 16 ; outer++) {
                              for (inner=0 ; inner < 16 ; inner++) {
                                   index=((16*inner)+outer);
                                   if (cntr < hichp1) {
                                        chnlng.legend[index]=uidarr[cntr].sing;
                                        olegend[index]=uidarr[cntr].sing;
                                        chnlng.attrib[index]=uidarr[cntr].attrib;
                                        oattrib[index]=uidarr[cntr].attrib;
                                   }
                                   else {
                                        chnlng.legend[index]='\xFE';
                                        olegend[index]='\xFE';
                                        chnlng.attrib[index]=0x03;
                                        oattrib[index]=0x03;
                                   }
                                   cntr++;
                              }
                         }
                         if (!sameas(nxtarg(dpknam->suffix),POLLED)) {
                              rsyflg[usrnum]|=CHRFLG;
                         }
                         rsp2read(namtmp,sizeof(struct chninf),&chnlng,NULL);
                         return;
                    }
               }
               else if (samepato(dynpak(SCHLNG),dpkstg)) {
                    if (ISMASTER() || ACCESS(OPAUDT)) {
                         clear(rsptmp);
                         for (index=0 ; index < 256 ; index++) {
                              if (index < hichp1) {
                                   catrsp(uidarr[index].labl);
                              }
                              if (index < 255) {
                                   delimiter();
                              }
                         }
                         if (!sameas(nxtarg(dpknam->suffix),POLLED)) {
                              rsyflg[usrnum]|=LGDFLG;
                         }
                         rsp2read(namtmp,STGLEN,rsptmp,NULL);
                         return;
                    }
               }
               else if (samepato(dynpak(CHROFF),dpkstg)) {
                    if (ISMASTER() || ACCESS(OPAUDT)) {
                         rsyflg[usrnum]&=(~CHRFLG);
                         rsp2read(namtmp,0,NULL,NULL);
                         return;
                    }
               }
               else if (samepato(dynpak(LNGOFF),dpkstg)) {
                    if (ISMASTER() || ACCESS(OPAUDT)) {
                         rsyflg[usrnum]&=(~LGDFLG);
                         rsp2read(namtmp,0,NULL,NULL);
                         return;
                    }
               }
               else if (samepato(dynpak(KILUSR),dpkstg)) {
                    if (ISMASTER() || ACCESS(OPHNGP)) {
                         clear(rsptmp);
                         arg1=nxtarg(dpkstg);
                         if (onsysn(arg1,TRUE)) {
                              btuinj(othusn,RING);
                              catrsp(RSPOK);
                         }
                         else {
                              catrsp(RSPERR);
                         }
                         if (trkflgs&KILTRK) {
                              shocst("USER KICKED OFF OF SERVER",
                                     "[%-24s] User kicked: %-23s",
                                     usaptr->userid,arg1);
                         }
                         rsp2read(namtmp,STGLEN,rsptmp,NULL);
                         return;
                    }
               }
               else if (samepato(dynpak(SYSEVT),dpkstg)) {
                    if (ISMASTER() || ACCESS(OPCLNP)) {
                         arg1=nxtarg(dpkstg);
                         outer=atoi(itemidx(arg1,0));
                         inner=atoi(itemidx(arg1,1));
                         if ((outer >= 1) && (outer <= 5)) {
                              if ((inner >= 1) && (inner <= 10)) {
                                   rsyevn.chan=outer;
                                   rsykil=inner+1;
                                   errcod=(rsyevn.chan == 1 ? 0 :
                                           rsyevn.chan+9);
                                   cntr=greqid;
                                   rsyevn.chan=usrnum;
                                   rsmode=rsetop;
                                   if (trkflgs&EVTTRK) {
                                        shocst("REMOTE CLEANUP/EVENT SHUTDOWN",
                                        "[%-23s]  Op: %-25s",usaptr->userid,
                                        ((outer == 1) ? "SYSTEM CLEANUP" :
                                        spr("TIMED EVENT %d",(outer-1))));
                                   }
                                   prepff();
                                   rsyevt();
                                   curusr(rsyevn.chan);
                                   if (ismyreq(cntr,RSYAPN)) {
                                        curreq(cntr);
                                        rsp2read(namtmp,0,NULL,NULL);
                                        return;
                                   }
                              }
                         }
                    }
               }
               else if (samepato(dynpak(KILSYS),dpkstg)) {
                    if (ISMASTER() || ACCESS(OPSHDN)) {
                         arg1=nxtarg(dpkstg);
                         outer=atoi(itemidx(arg1,0));
                         if ((outer >=1) && (outer <= 7)) {
                              if (outer == 7) {
                                   kilipg=0;
                                   errcod=1;
                                   rsyevn.chan=usrnum;
                                   rsmode=NORMRS;
                                   prepff();
                                   kilctr=-1;
                                   curusr(rsyevn.chan);
                                   if (trkflgs&KSYTRK) {
                                        shocst("REMOTE SHUTDOWN CANCELLED",
                                               "[%-35s]",usaptr->userid);
                                   }
                                   rsp2read(namtmp,0,NULL,NULL);
                              }
                              else {
                                   if (trkflgs&KSYTRK) {
                                        shocst("REMOTE SHUTDOWN INITIATED",
                                               "[%-35s]",usaptr->userid);
                                   }
                                   rsp2read(namtmp,0,NULL,NULL);
                                   kilsrc=usrnum;
                                   errcod=8;
                                   kilctr=kilmins[outer-1];
                                   fupkil();
                              }
                              return;
                         }
                    }
               }
               else if (samepato(dynpak(GETCWD),dpkstg)) {
                    clear(rsptmp);
                    normspec(rsptmp,".");
                    rsp2read(namtmp,STGLEN,rsptmp,NULL);
                    return;
               }
               else if (samepato(dynpak(AUDGET),dpkstg)) {
                    if (ISMASTER() || ACCESS(OPAUDT)) {
                         arg1=nxtarg(dpkstg);
                         nularg(arg1);
                         clireq=atoi(arg1);
                         rsyaud.request=srvrqid(usrnum,clireq);
                         if (ismyreq(rsyaud.request,RSYAPN)) {
                              savreq=greqid;
                              curreq(rsyaud.request);
                              clear(rsptmp);
                              if (sameas(rsycmn->mysuffix,AUDSTR)) {
                                   getaud();
                              }
                              curreq(savreq);
                              rsp2read(NULL,STGLEN,rsptmp,NULL);
                              return;
                         }
                    }
               }
               else if (samepato(dynpak(AUDSCR),dpkstg)) {
                    if (ISMASTER() || ACCESS(OPAUDT)) {
                         arg1=nxtarg(dpkstg);
                         arg2=nxtarg(arg1);
                         nularg(arg1);
                         nularg(arg2);
                         clireq=atoi(arg1);
                         comval=atoi(arg2);
                         rsyaud.request=srvrqid(usrnum,clireq);
                         if (ismyreq(rsyaud.request,RSYAPN)) {
                              savreq=greqid;
                              curreq(rsyaud.request);
                              if (sameas(rsycmn->mysuffix,AUDSTR)) {
                                   clear(rsptmp);
                                   switch (comval) {
                                   case AUDHOME:
                                        topaud();
                                        break;
                                   case AUDEND:
                                        initaud();
                                        break;
                                   case AUDPGDN:
                                        scraud(NUMADT);
                                        break;
                                   case AUDPGUP:
                                        scraud(-NUMADT);
                                        break;
                                   case AUDDN:
                                        scraud(-1);
                                        break;
                                   case AUDUP:
                                        scraud(1);
                                        break;
                                   }
                                   getaud();
                              }
                              curreq(savreq);
                              rsp2read(NULL,STGLEN,rsptmp,NULL);
                              return;
                         }
                    }
               }
               else if (samepato(USRCMT,dpkstg)) {
                    if (ISMASTER() || ACCESS(OPACCT)) {
                         r2rgdp(direction,namtmp);
                         return;
                    }
                    else {
                         rejectreq();
                         return;
                    }
               }
               else if (samepato(dynpak(GETSTT),dpkstg)) {
                    arg1=nxtarg(dpkstg);
                    nularg(arg1);
                    comval=atoi(arg1);
                    clear(rsptmp);
                    if ((comval >= LIUSTT) && (comval <= CUGSTT)) {
                         if (!ISMASTER() && !ACCESS(OPSYSS)) {
                              rejectreq();
                              return;
                         }
                    }
                    switch(comval) {
                    case LIUSTT:
                         liugph();
                         break;
                    case SEBSTT:
                         sebgph();
                         break;
                    case TUHSTT:
                         tuhgph();
                         break;
                    case TUGSTT:
                         tuggph();
                         break;
                    case CUHSTT:
                         cuhgph();
                         break;
                    case CUGSTT:
                         cuggph();
                         break;
                    case DEMSTT:
                         if (ISMASTER() || ACCESS(OPDEMS)) {
                              demstt();
                         }
                         else {
                              rejectreq();
                              return;
                         }
                         break;
                    case CLSSTT:
                         if (ISMASTER() || ACCESS(OPCLSS)) {
                              clsstt();
                         }
                         else {
                              rejectreq();
                              return;
                         }
                         break;
                    case MSCSTT:
                         if (ISMASTER() || ACCESS(OPMODS)) {
                              mscstt();
                         }
                         else {
                              rejectreq();
                              return;
                         }
                         break;
                    default:
                         break;
                    }
                    rsp2read(NULL,STGLEN,rsptmp,NULL);
                    return;
               }
               else if (samepato(dynpak(INTPRC),dpkstg) ||
                        samepato(fdynpak(INTPRC),dpkstg)) {
                    arg1=nxtarg(dpkstg);
                    arg2=nxtarg(arg1);
                    nularg(arg1);
                    nularg(arg2);
                    comval=atoi(arg1);
                    clireq=atoi(arg2);
                    rsyclp.request=srvrqid(usrnum,clireq);
                    if (ismyreq(rsyclp.request,RSYAPN)) {
                         switch (comval) {
                         case DIRCMD:
                              listdir();
                              return;
                         case CPYCMD:
                              if (prepcpy()) {
                                   return;
                              }
                              rsp2read(NULL,0,NULL,NULL);
                              return;
                         case DELCMD:
                              dodelt();
                              return;
                         case TYPCMD:
                              dotype();
                              return;
                         case DNLCMD:
                              dodnl();
                              return;
                         default:
                              break;
                         }
                    }
               }
          }
     }
     rejectreq();
}

static VOID
rsywrite(
struct saunam *dpknam,
USHORT length,
VOID *value)
{
     CHAR *dpkstg,*arg1,*arg2;
     INT comval,savreq,stroff,outer,reqidx,reqnum;
     GBOOL isthere;
     struct ffblk fb;
     
     if (stdchk(rsckey)) {
          stlcpy(rsycmn->mysuffix,dpknam->suffix,SFXSIZ);
          rsycmn->myflags=0L;
          *namtmp=*dpknam;
          dpkstg=cnvs2d(namtmp);
          if (samepato(dynpak(PSTUSR),dpkstg)) {
               if (ISMASTER() || ACCESS(OPACCT)) {
                    stlcpy(rsyarg.usrnam,itemidx(value,0),UIDSIZ);
                    stlcpy(rsyarg.crdstr,itemidx(value,1),LNMSIZ);
                    if (sameas(itemidx(value,2),"paid")) {
                         rsyarg.real=1;
                    }
                    else {
                         rsyarg.real=0;
                    }
                    if (trkflgs&PSTTRK) {
                         shocst("REMOTE POSTING OF CREDITS",
                                "[%-23s]  Posted to: %-23s",usaptr->userid,
                                rsyarg.usrnam);
                    }
                    switch(addcrd(rsyarg.usrnam,rsyarg.crdstr,rsyarg.real)) {
                    case 0:
                         break;
                    case 1:
                         saycrd(rsyarg.crdstr,rsyarg.real);
                    case -1:
                         break;
                    }
                    rsp2write(TRUE,0,NULL,NULL);
                    return;
               }
          }
          else if (samepato(dynpak(VLDPTH),dpkstg)) {
               if (isdir(value)) {
                    rsp2write(TRUE,STGLEN,RSPOK,NULL);
                    return;
               }
               rejectreq();
               return;
          }
          else if (samepato(dynpak(LOGMSG),dpkstg)) {
               if (ISMASTER() || ACCESS(OPLOGN)) {
                    arg1=(char *)value;
                    xltctls(arg1);
                    stlcpy(sv.lonmsg,value,MTXSIZ);
                    if (trkflgs&LOGTRK) {
                         shocst("SYSTEM LOGON MESSAGE CHANGED",
                                "[%-35s]",usaptr->userid);
                    }
                    rsp2write(TRUE,0,NULL,NULL);
                    return;
               }
          }
          else if (samepato(dynpak(MSGUSR),dpkstg)) {
               if (ISMASTER() || ACCESS(OPSEND)) {
                    arg1=nxtarg(dpkstg);
                    if (onsysn(arg1,TRUE)) {
                         if (length > 0) {
                              snd2ch(othusn,value);
                              if (trkflgs&MSGTRK) {
                                   shocst("REMOTE MESSAGE SENT TO USER",
                                          "[%-23s]  Message to: %-23s",
                                          usaptr->userid,arg1);
                              }
                         }
                    }
                    rsp2write(TRUE,0,NULL,NULL);
                    return;
               }
          }
          else if (samepato(dynpak(MSGALL),dpkstg)) {
               if (ISMASTER() || ACCESS(OPSALL)) {
                    if (length > 0) {
                         snd2al(value);
                         if (trkflgs&AMSTRK) {
                              shocst("REMOTE MESSAGE SENT TO ALL",
                                        "[%-35s]",usaptr->userid);
                         }
                    }
                    rsp2write(TRUE,0,NULL,NULL);
                    return;
               }
          }
          else if (samepato(USRCMT,dpkstg)) {
               if (ISMASTER() || ACCESS(OPACCT)) {
                    writegdp(namtmp,length,value,NULL);
                    rsp2write(TRUE,0,NULL,NULL);
                    return;
               }
               else {
                    rejectreq();
                    return;
               }
          }
          else if (samepato(dynpak(SEARCH),dpkstg)) {
               if (ISMASTER() || ACCESS(OPSRCH)) {
                    arg1=nxtarg(dpkstg);
                    arg2=nxtarg(arg1);
                    nularg(arg1);
                    nularg(arg2);
                    comval=atoi(arg1);
                    rsyfnd.relate=atoi(arg2);
                    if ((comval >= FLDUID) && (comval <= FLDDAY)) {
                         rsyfnd.field=comval;
                         stlcpy(rsyfnd.srchstg,(char *)value,SSTSIZ);
                         dfaSetBlk(accbb);
                         if (dfaStepLO(NULL)) {
                              rsyfnd.fpos=dfaAbs();
                              dfaRstBlk();
                              cycleme(accsrch);
                              accsrch();
                              return;
                         }
                         else {
                              dfaRstBlk();
                              rsp2write(TRUE,0,NULL,NULL);
                              return;
                         }
                    }
               }
          }
          else if (samepato(dynpak(AUDSTR),dpkstg)) {
               if (ISMASTER() || ACCESS(OPAUDT)) {
                    for (reqidx=0 ; reqidx < 30 ; reqidx++) {
                         reqnum=srvrqid(usrnum,reqidx);
                         if (ismyreq(reqnum,RSYAPN) && (reqnum != greqid)) {
                              savreq=greqid;
                              curreq(reqnum);
                              if (sameas(rsycmn->mysuffix,AUDSTR)) {
                                   rsp2write(TRUE,0,NULL,NULL);
                              }
                              curreq(savreq);
                         }
                    }
                    initaud();
                    rsyflg[usrnum]|=AUDFLG;
                    return;
               }
          }
          else if (samepato(dynpak(AUDSTP),dpkstg)) {
               rsyflg[usrnum]&=(~AUDFLG);
               for (reqidx=0 ; reqidx < 30 ; reqidx++) {
                    reqnum=srvrqid(usrnum,reqidx);
                    if (ismyreq(reqnum,RSYAPN) && (reqnum != greqid)) {
                         savreq=greqid;
                         curreq(reqnum);
                         if (sameas(rsycmn->mysuffix,AUDSTR)) {
                              rsp2write(TRUE,0,NULL,NULL);
                         }
                         curreq(savreq);
                    }
               }
               rsp2write(TRUE,0,NULL,NULL);
               return;
          }
          else if (samepato(dynpak(INTERP),dpkstg)) {
               for (reqidx=0 ; reqidx < 30 ; reqidx++) {
                    reqnum=srvrqid(usrnum,reqidx);
                    if (ismyreq(reqnum,RSYAPN) && (reqnum != greqid)) {
                         savreq=greqid;
                         curreq(reqnum);
                         if (sameas(rsycmn->mysuffix,INTERP)) {
                              rsp2write(TRUE,0,NULL,NULL);
                         }
                         curreq(savreq);
                    }
               }
               arg1=nxtarg(dpkstg);
               comval=atoi(arg1);
               clear(rsptmp);
               switch (comval) {
               case DIRCMD:
                    if (ISMASTER() || ACCESS(OPDIR)) {
                         rsycmn->myflags|=DIRREQ;
                         stlcpy(rsyclp.sfname,value,FNDSIZE);
                         if (trkflgs&DIRTRK) {
                              shocst("REMOTE DIR COMMAND USED",
                                     "[%-23s]  arg: %-29s",usaptr->userid,
                                     value);
                         }
                         if (strtfil()) {
                              return;
                         }
                         catrsp(RSPERR);
                         delimiter();
                         catrsp("DIR");
                         rsp2write(FALSE,STGLEN,rsptmp,NULL);
                         return;
                    }
                    break;
               case CPYCMD:
                    if (ISMASTER() || ACCESS(OPCOPY)) {
                         rsycmn->myflags|=CPYREQ;
                         arg1=value;
                         arg2=nxtarg(arg1);
                         nularg(arg1);
                         nularg(arg2);
                         if (*arg1 != '\0' && *arg2 != '\0') {
                              stlcpy(rsyclp.sfname,arg1,FNDSIZE);
                              stlcpy(rsyclp.dfname,arg2,FNDSIZE);
                              if (trkflgs&CPYTRK) {
                                   shocst("REMOTE COPY COMMAND USED",
                                          "[%-15s] arg1: %-15s arg2: %-15s",
                                          usaptr->userid,arg1,arg2);
                              }
                              if (strtcpy()) {
                                   return;
                              }
                         }
                         catrsp(RSPERR);
                         delimiter();
                         catrsp("CPY");
                         rsp2write(FALSE,STGLEN,rsptmp,NULL);
                         return;
                    }
                    break;
               case DELCMD:
                    if (ISMASTER() || ACCESS(OPDEL)) {
                         rsycmn->myflags|=DELREQ;
                         arg1=value;
                         nularg(arg1);
                         if (*arg1 != '\0') {
                              stlcpy(rsyclp.sfname,arg1,FNDSIZE);
                              if (trkflgs&DELTRK) {
                                   shocst("REMOTE DEL COMMAND USED",
                                          "[%-23s] arg: %-20s",usaptr->userid,
                                          arg1);
                              }
                              if (strtdel()) {
                                   return;
                              }
                         }
                         catrsp(RSPERR);
                         delimiter();
                         catrsp("DEL");
                         rsp2write(FALSE,STGLEN,rsptmp,NULL);
                         return;
                    }
                    break;
               case TYPCMD:
                    if (ISMASTER() || ACCESS(OPTYPE)) {
                         rsycmn->myflags|=TYPREQ;
                         arg1=value;
                         nularg(arg1);
                         stlcpy(rsyclp.sfname,arg1,FNDSIZE);
                         if (trkflgs&TYPTRK) {
                              shocst("REMOTE TYPE COMMAND USED",
                                     "[%-23s] arg: %-20s",usaptr->userid,
                                     arg1);
                         }
                         if (strttyp()) {
                              return;
                         }
                         catrsp(RSPERR);
                         delimiter();
                         catrsp("TYP");
                         rsp2write(FALSE,STGLEN,rsptmp,NULL);
                         return;
                    }
                    break;
               case MKDCMD:
                    if (ISMASTER() || ACCESS(OPMD)) {
                         arg1=value;
                         nularg(arg1);
                         stlcpy(vdatmp,arg1,FNDSIZE);
                         if (trkflgs&MDTRK) {
                              shocst("REMOTE MD COMMAND USED",
                                     "[%-23s] arg: %-20s",usaptr->userid,
                                     arg1);
                         }
                         clear(rsptmp);
                         if (MKDIR(vdatmp) == 0) {
                              stlcpy(rsptmp,vdatmp,FNDSIZE);
                              rsp2write(TRUE,STGLEN,rsptmp,NULL);
                              return;
                         }
                         catrsp(RSPERR);
                         delimiter();
                         catrsp("MD");
                         rsp2write(FALSE,STGLEN,rsptmp,NULL);
                         return;
                    }
                    break;
               case RMDCMD:
                    if (ISMASTER() || ACCESS(OPRD)) {
                         arg1=value;
                         nularg(arg1);
                         stlcpy(vdatmp,arg1,FNDSIZE);
                         if (trkflgs&RDTRK) {
                              shocst("REMOTE RD COMMAND USED",
                                     "[%-23s] arg: %-20s",usaptr->userid,
                                     arg1);
                         }
                         clear(rsptmp);
                         if (rmdir(vdatmp) == 0) {
                              stlcpy(rsptmp,vdatmp,FNDSIZE);
                              rsp2write(TRUE,STGLEN,rsptmp,NULL);
                              return;
                         }
                         catrsp(RSPERR);
                         delimiter();
                         catrsp("RD");
                         rsp2write(FALSE,STGLEN,rsptmp,NULL);
                         return;
                    }
                    break;
               case RENCMD:
                    if (ISMASTER() || ACCESS(OPRENM)) {
                         arg1=value;
                         arg2=nxtarg(arg1);
                         nularg(arg1);
                         nularg(arg2);
                         stlcpy(rsyclp.sfpath,stppath(arg1),FNDSIZE);
                         stlcpy(rsyclp.sfname,arg1,FNDSIZE);
                         stlcpy(rsyclp.dfname,rsyclp.sfpath,FNDSIZE);
                         stlcat(rsyclp.dfname,stpname(arg2),FNDSIZE);
                         clear(rsptmp);
                         if (trkflgs&RENTRK) {
                              shocst("REMOTE RENAME COMMAND USED",
                                        "[%-15s] arg1: %-15s arg2: %-15s",
                                        usaptr->userid,rsyclp.sfname,
                                        rsyclp.dfname);
                         }
                         if (!(isthere=fndfile(&fb,rsyclp.sfname,0))) {
                              stlcpy(rsptmp,"File not found: ",CSWIDTH);
                              stlcat(rsptmp,rsyclp.sfname,CSWIDTH);
                              rsp2write(NULL,STGLEN,rsptmp,NULL);
                              return;
                         }
                         if (rename(rsyclp.sfname,rsyclp.dfname) == 0) {
                              stlcpy(rsptmp,rsyclp.sfname,CSWIDTH);
                              stlcat(rsptmp,"->",CSWIDTH);
                              stlcat(rsptmp,rsyclp.dfname,CSWIDTH);
                              rsp2write(TRUE,STGLEN,rsptmp,NULL);
                              return;
                         }
                         else if (isthere) {
                              stlcpy(rsptmp,"Unable to rename file: ",CSWIDTH);
                              stlcat(rsptmp,rsyclp.sfname,CSWIDTH);
                              rsp2write(NULL,STGLEN,rsptmp,NULL);
                              return;
                         }
                         catrsp(RSPERR);
                         delimiter();
                         catrsp("REN");
                         rsp2write(FALSE,STGLEN,rsptmp,NULL);
                         return;
                    }
                    break;
               case DNLCMD:
               case LNCCMD:
                    if (ISMASTER() || ACCESS(OPTRNF)) {
                         rsycmn->myflags|=DNLREQ;
                         arg1=value;
                         nularg(arg1);
                         stlcpy(rsyclp.sfname,arg1,FNDSIZE);
                         if ((trkflgs&GETTRK) || (trkflgs&LNCTRK)) {
                              shocst("REMOTE GET/LAUNCH COMMAND USED",
                                     "[%-23s] arg: %-20s",usaptr->userid,
                                     arg1);
                         }
                         if (strtdnl()) {
                              return;
                         }
                         rsp2write(TRUE,0,NULL,NULL);
                         return;
                    }
                    break;
               case UPLCMD:
                    if (ISMASTER() || ACCESS(OPTRNF)) {
                         rsycmn->myflags|=UPLREQ;
                         arg1=value;
                         nularg(arg1);
                         stroff=strlen(arg1);
                         if (trkflgs&PUTTRK) {
                              shocst("REMOTE PUT COMMAND USED",
                                     "[%-23s] arg: %-20s",usaptr->userid,arg1);
                         }
                         if (stroff > 0) {
                              if (samend(arg1,"\\.")) {
                                   arg1[--stroff]='\0';
                              }
                              if (arg1[stroff-1] == '\\'
                               || isdir(arg1) != FALSE) {
                                   rsyclp.multifil=TRUE;
                                   stlcpy(rsyclp.dfpath,arg1,FNDSIZE);
                                   stlcat(rsyclp.dfpath,"\\",FNDSIZE);
                              }
                              else {
                                   stlcpy(rsyclp.dfpath,stppath(arg1),FNDSIZE);
                                   stlcpy(rsyclp.dfname,stpname(arg1),FNDSIZE);
                                   rsyclp.multifil=iswild(rsyclp.dfname);
                              }
                         }
                         else {
                              stlcpy(rsyclp.dfpath,".\\",FNDSIZE);
                              rsyclp.multifil=TRUE;
                         }
                         return;
                    }
                    break;
               default:
                    break;
               }
          }
          else if (samepato(fdynpak(UPLMNU),dpkstg)) {
               if (ISMASTER() || ACCESS(OPTRNF)) {
                    if (upldmnu) {
                         rejectreq();
                         return;
                    }
                    upldmnu=TRUE;
                    ok2write(BBSNMN);
                    return;
               }
          }
          else if (samepato(fdynpak(INTPRC),dpkstg)) {
               arg1=nxtarg(dpkstg);
               arg2=nxtarg(arg1);
               nularg(arg1);
               nularg(arg2);
               comval=atoi(arg1);
               outer=atoi(arg2);
               rsyclp.request=srvrqid(usrnum,outer);
               switch (comval) {
               case UPLCMD:
                    if (ismyreq(rsyclp.request,RSYAPN)) {
                         rsycmn->myflags|=UPLREQ;
                         rsyclp.dirblk.ff_fdate=FINFPTR->date;
                         rsyclp.dirblk.ff_ftime=FINFPTR->time;
                         savreq=greqid;
                         curreq(rsyclp.request);
                         if (rsycmn->myflags&UPLREQ) {
                              clear(rsptmp);
                              cpyrsp(rsyclp.dfpath);
                              if (rsyclp.multifil) {
                                   stlcpy(rsyclp.dfname,FINFPTR->name,FNDSIZE);
                              }
                              catrsp(rsyclp.dfname);
                              curreq(savreq);
                              if (rsvnam(rsptmp)
                               || (rsyclp.dfptr=fopen(rsptmp,FOPWB)) == NULL) {
                                   clear(rsptmp);
                                   catrsp(RSPERR);
                                   delimiter();
                                   catrsp("PUT");
                                   rsp2write(FALSE,STGLEN,rsptmp,NULL);
                              }
                              else {
                                   if (rsyclp.dfptr != NULL) {
                                        fclose(rsyclp.dfptr);
                                   }
                                   ok2write(rsptmp);
                              }
                              return;
                         }
                         curreq(savreq);
                    }
                    break;
               default:
                    break;
               }
          }
     }
     rejectreq();
}

static VOID
rsyxdone(VOID)
{
     IMPORT_VARIABLE(DFAFILE*) mnubb;

     if (rsycmn->myflags&UPLREQ) {
          clear(rsptmp);
          cpyrsp(rsyclp.dfpath);
          catrsp(rsyclp.dfname);
          setFileTm(rsptmp,rsyclp.dirblk.ff_fdate,rsyclp.dirblk.ff_ftime);
          rsp2write(TRUE,0,NULL,NULL);
     }
     if (sameas(rsycmn->mysuffix,UPLMNU)) {
          dfaClose(mnubb);
          unlink(MENUDAT);
          rename(BBSNMN,MENUDAT);
          mnubb=dfaOpen(MENUDAT,sizeof(struct mnupag),NULL);
          shocst("NEW "MENUDAT" UPLOADED","Uploading user: %s",
                 usaptr->userid);
          rsp2write(TRUE,0,NULL,NULL);
          upldmnu=FALSE;
     }
     if (sameto(INTPRC,rsycmn->mysuffix)) {
          if (sameas(MENUDAT,rsyclp.dirblk.ff_name)) {
               lockmnu(FALSE);
          }
     }
}

static VOID
rsyabort(VOID)
{
     if (sameas(rsycmn->mysuffix,AUDSTR)) {
          rsyflg[usrnum]&=(~AUDFLG);
     }
     else if (sameas(rsycmn->mysuffix,SCHCHR)) {
          rsyflg[usrnum]&=(~CHRFLG);
     }
     else if (sameas(rsycmn->mysuffix,SCHLNG)) {
          rsyflg[usrnum]&=(~LGDFLG);
     }
     else if (sameas(rsycmn->mysuffix,UPLMNU)) {
          unlink(BBSNMN);
          upldmnu=FALSE;
     }
     if (sameto(INTPRC,rsycmn->mysuffix)) {
          if (sameas(MENUDAT,rsyclp.dirblk.ff_name)) {
               lockmnu(FALSE);
          }
     }
     if (rsycmn->myflags&CPYREQ) {
          rsyclp.status=WRKDON;
          if (rsyclp.sfptr != NULL) {
               fclose(rsyclp.sfptr);
               rsyclp.sfptr=NULL;
          }
          if (rsyclp.dfptr != NULL) {
               fclose(rsyclp.dfptr);
               rsyclp.dfptr=NULL;
               unlink(rsyclp.dfname);
          }
     }
     else if (rsycmn->myflags&TYPREQ) {
          if (rsyclp.sfptr != NULL) {
               fclose(rsyclp.sfptr);
               rsyclp.sfptr=NULL;
          }
     }
}

#ifdef GCWINNT
static VOID
osabt(VOID)                        /* handle "about" info for NT server    */
{
     OSVERSIONINFO versionInfo;
     SYSTEM_INFO systemInfo;
     CHAR dspBuffer[1024];

     versionInfo.dwOSVersionInfoSize=sizeof(OSVERSIONINFO);
     GetVersionEx(&versionInfo);
     GetSystemInfo(&systemInfo);
     if (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) {
          sprintf(dspBuffer,"Windows NT v%d.%d (Build %d)",
                  versionInfo.dwMajorVersion,
                  versionInfo.dwMinorVersion,
                  versionInfo.dwBuildNumber);
          catrsp(dspBuffer);
          delimiter();
          switch(systemInfo.u.s.wProcessorArchitecture) {
          case PROCESSOR_ARCHITECTURE_INTEL:
               catrsp("Intel ");
               switch(systemInfo.dwProcessorType) {
               case PROCESSOR_INTEL_386:
                    catrsp("80386");
                    break;
               case PROCESSOR_INTEL_486:
                    catrsp("80486");
                    break;
               case PROCESSOR_INTEL_PENTIUM:
                    catrsp("Pentium");
                    break;
               default:
                    catrsp("Unknown Type");
                    break;
               }
               break;
          case PROCESSOR_ARCHITECTURE_MIPS:
               catrsp("MIPS");
               break;
          case PROCESSOR_ARCHITECTURE_ALPHA:
               catrsp("ALPHA");
               break;
          case PROCESSOR_ARCHITECTURE_PPC:
               catrsp("PPC ");
               break;
          case PROCESSOR_ARCHITECTURE_UNKNOWN:
          default:
               catrsp("UNKNOWN");
               break;
          }
          sprintf(dspBuffer," (%d Processor%s)",systemInfo.dwNumberOfProcessors,
                 systemInfo.dwNumberOfProcessors == 1 ? "" : "s");
          catrsp(dspBuffer);
          delimiter();
          sprintf(dspBuffer,"NT %s",isRunAsService() ? "Service" : "Application");
          catrsp(dspBuffer);
     }
     else {
          sprintf(dspBuffer,"Windows 95 v%d.%d (Build %d)",
                         versionInfo.dwMajorVersion,
                         versionInfo.dwMinorVersion,
                         LOWORD(versionInfo.dwBuildNumber));
          catrsp(dspBuffer);
          delimiter();
          catrsp("Intel ");
          switch (systemInfo.dwProcessorType) {
          case PROCESSOR_INTEL_386:
               catrsp("80386 ");
               break;
          case PROCESSOR_INTEL_486:
               catrsp("80486 ");
               break;
          case PROCESSOR_INTEL_PENTIUM:
               catrsp("Pentium ");
               break;
          default:
               catrsp("Unknown Type ");
               break;
          }
          catrsp("(1 Processor)");
     }
     delimiter();
     delimiter();   /* second delimiter because prior string is blank */
}
#else
static VOID
osabt(VOID)                        /* handle "about" info for DOS server   */
{
     catrsp("DOS v");
     catrsp(osversn());
     delimiter();
     if (multsk) {
          catrsp("Yes - ");
          if (mulmth == COMIRP) {
               catrsp("Interrupt");
          }
          else {
               catrsp("Timer");
          }
     }
     else {
          catrsp("No");
     }
     delimiter();
     catrsp(l2as(maxspd));
     if (maxspd != maxpol) {
          catrsp("/");
          catrsp(l2as(maxpol));
     }
     delimiter();
}
#endif                             // GCWINNT

static VOID
getntrm(VOID)                      /* get nterms into rsptmp               */
{
     catrsp(itoa(nterms,vdatmp,10));
}

static VOID
getsyst(VOID)                      /* get system statistics into rsptmp    */
{

#ifdef GCWINNT
     catrsp(dbytes(dskfre(".")));
#else
     ULONG ravl,eavl;

     catrsp(dbytes(dskfre(".")));
     delimiter();
     DosRealAvail(&ravl);
     DosMemAvail(&eavl);
     catrsp(dbytes(eavl/1024));
     delimiter();
     catrsp(dbytes(ravl/1024));
#endif // GCWINNT
}

static VOID
legends(                      /* this hook to schochl() updates legend info*/
INT chan)                     /*   channel currently serviced by shochl()  */
{
     if ((olegend[chan] != uidarr[chan].sing)
        || (oattrib[chan] != uidarr[chan].attrib)) {
          shwchr(chan);
          olegend[chan]=uidarr[chan].sing;
          oattrib[chan]=uidarr[chan].attrib;
     }
     shwlng(chan);
}

static VOID
shwchr(                       /* show channel character legend matrix      */
INT chan)                     /*   channel whose information is changed    */
{
     INT index;
     struct saunam rfdpk;
     CHAR tmpstr[17];

     cpyvda(itoa((chan&0x0F),tmpstr,10));
     vdelimiter();
     catvda(itoa(((chan&0xF0)>>4),tmpstr,10));
     vdelimiter();
     catvda(itoa(uidarr[chan].sing,tmpstr,10));
     vdelimiter();
     catvda(itoa(uidarr[chan].attrib,tmpstr,10));
     setmem(&rfdpk,sizeof(struct saunam),0);
     stlcpy(rfdpk.sysid,msysid,SIDSIZ);
     stlcpy(rfdpk.appid,RSYAPN,AIDSIZ);
     rfdpk.usrid[0]='\0';
     stlcpy(rfdpk.suffix,SCHCHR,SFXSIZ);
     for (index=0 ; index < nterms ; index++) {
          if ((usroff(index)->flags&ISGCSU) && (rsyflg[index]&CHRFLG)) {
               if (qroom(index,NORMAL)) {
                    senddpk(index,RSYAPN,NORMAL,&rfdpk,STGLEN,vdatmp,NULL);
               }
          }
          else {
               if (rsyflg[usrnum]&CHRFLG) {
                    rsyflg[usrnum]&=(~CHRFLG);
               }
          }
     }
}

static VOID
shwlng(                       /* show visible channel legend text          */
INT chan)                     /*   channel to get string for               */
{
     struct saunam rfdpk;
     INT index;
     CHAR tmpstr[17];

     cpyvda(itoa(chan,tmpstr,10));
     vdelimiter();
     catvda(uidarr[chan].labl);
     setmem(&rfdpk,sizeof(struct saunam),0);
     stlcpy(rfdpk.sysid,msysid,SIDSIZ);
     stlcpy(rfdpk.appid,RSYAPN,AIDSIZ);
     rfdpk.usrid[0]='\0';
     stlcpy(rfdpk.suffix,SCHLNG,SFXSIZ);
     for (index=0 ; index < nterms ; index++) {
          if ((usroff(index)->flags&ISGCSU) && (rsyflg[index]&LGDFLG)) {
               if (qroom(index,NORMAL)) {
                    senddpk(index,RSYAPN,NORMAL,&rfdpk,STGLEN,vdatmp,NULL);
               }
          }
          else {
               if (rsyflg[usrnum]&LGDFLG) {
                    rsyflg[usrnum]&=(~LGDFLG);
               }
          }
     }
}

CHAR *                             /* returns pointer to 7-character string*/
rtmfmt(                            /*   format Response Time number        */
ULONG ntval)                       /*   interval, 1/65536 second units     */
{
     CHAR *cp;

     if (ntval >= HRTONE) {
          if (strlen(cp=ul2as((ntval+HRTONE/2)>>16)) > 3) {
               return("999 sec");
          }
          else if ((ntval=((ntval+HRTONE/20)*10)>>16) > 99L) {
               return(spr("%3s sec",cp));
          }
          else {
               return(spr("%d.%d sec",((int)ntval)/10,((int)ntval)%10));
          }
     }
     else {
          if (strlen(cp=ul2as(ntval=((ntval+HRTONE/2000)*1000)>>16)) > 3) {
               return(" 999 ms");
          }
          else if (ntval > 0L) {
               return(spr("%4s ms",cp));
          }
          else {
               return(" < 1 ms");
          }
     }
}

static GBOOL
strtfil(VOID)                 /* get first file name for a directory list  */
{
     if (!iswild(rsyclp.sfname)) {
          if (isdir(rsyclp.sfname)) {
               stlcat(rsyclp.sfname,"\\*.*",FNDSIZE);
          }
          else {
               fixfil(rsyclp.sfname);
          }
     }
     if (fnd1st(&rsyclp.dirblk,rsyclp.sfname,FAMDIR)) {
          return(TRUE);
     }
     return(FALSE);
}

static GBOOL
strtdnl(VOID)                 /* get first filename for download suite     */
{
     if (iswild(rsyclp.sfname)) {
          rsyclp.multifil=TRUE;
     }
     else if (isdir(rsyclp.sfname)) {
          stlcat(rsyclp.sfname,"\\*.*",FNDSIZE);
          rsyclp.multifil=TRUE;
     }
     stlcpy(rsyclp.sfpath,stppath(rsyclp.sfname),FNDSIZE);
     rsyclp.multifil=iswild(rsyclp.sfname);
     if (fnd1st(&rsyclp.dirblk,rsyclp.sfname,0)) {
          return(TRUE);
     }
     return(FALSE);
}

static GBOOL
strtcpy(VOID)                 /* get first filename for file copy          */
{
     rsyclp.status=WRKDON;
     if ((rsyclp.multifil=iswild(rsyclp.sfname)) != FALSE) {
          if (!isdir(rsyclp.dfname)) {
               return(FALSE);
          }
     }
     else if ((rsyclp.multifil=isdir(rsyclp.sfname)) != FALSE) {
          stlcat(rsyclp.sfname,"\\*.*",FNDSIZE);
          if (!isdir(rsyclp.dfname)) {
               return(FALSE);
          }
     }
     else {
          rsyclp.multifil=iswild(fixfil(rsyclp.sfname));
     }
     if ((rsyclp.multifil) || isdir(rsyclp.dfname)) {
          stlcpy(rsyclp.sfpath,stppath(rsyclp.sfname),FNDSIZE);
          stlcpy(rsyclp.dfpath,makpath(rsyclp.dfname),FNDSIZE);
          if (!rsyclp.multifil) {
               stlcpy(rsyclp.dfname,rsyclp.dfpath,FNDSIZE);
               stlcat(rsyclp.dfname,stpname(rsyclp.sfname),FNDSIZE);
          }
     }
     if (fnd1st(&rsyclp.dirblk,rsyclp.sfname,0)) {
          return(TRUE);
     }
     return(FALSE);
}

static GBOOL
strtdel(VOID)                 /* get first filename for delete operation   */
{
     rsyclp.multifil=FALSE;
     if (iswild(rsyclp.sfname)) {
          rsyclp.multifil=TRUE;
     }
     else if (isdir(rsyclp.sfname)) {
          stlcat(rsyclp.sfname,"\\*.*",FNDSIZE);
          rsyclp.multifil=TRUE;
     }
     if (rsyclp.multifil) {
          stlcpy(rsyclp.dfpath,stppath(rsyclp.sfname),FNDSIZE);
     }
     if (fnd1st(&rsyclp.dirblk,rsyclp.sfname,0)) {
          return(TRUE);
     }
     return(FALSE);
}

static GBOOL
strttyp(VOID)                 /* get filename for type operation           */
{
     if (iswild(rsyclp.sfname) || isdir(rsyclp.sfname)
         || rsvnam(rsyclp.sfname)) {
          return(FALSE);
     }
     rsyclp.sfptr=fopen(rsyclp.sfname,FOPRA);
     if (rsyclp.sfptr == NULL) {
          return(FALSE);
     }
     return(TRUE);
}

static VOID
dotype(VOID)                  /* Handle the file viewing process           */
{
     INT savreq,hldreq;

     clear(rsptmp);
     savreq=greqid;
     curreq(rsyclp.request);
     if (rsycmn->myflags&TYPREQ) {
          clear(vdatmp);
          if (fgets(vdatmp,CSWIDTH,rsyclp.sfptr) != NULL) {
               stlcpy(rsptmp,vdatmp,CSWIDTH);
               curreq(savreq);
               rsp2read(NULL,STGLEN,stp4cs(rsptmp),NULL);
               return;
          }
          else {
               fclose(rsyclp.sfptr);
               rsyclp.sfptr=NULL;
               curreq(savreq);
               hldreq=rsyclp.request;
               rsp2read(NULL,STGLEN,stp4cs(rsptmp),NULL);
               curreq(hldreq);
               rsp2write(TRUE,0,NULL,NULL);
               return;
          }
     }
     curreq(savreq);
     rejectreq();
}

static VOID
dodelt(VOID)                  /* handle the cycled deleting process        */
{
     INT savreq,hldreq;

     clear(rsptmp);
     savreq=greqid;
     curreq(rsyclp.request);
     if (rsycmn->myflags&DELREQ) {
          if (rsyclp.multifil) {
               stlcpy(rsyclp.sfname,rsyclp.dfpath,FNDSIZE);
               stlcat(rsyclp.sfname,rsyclp.dirblk.ff_name,FNDSIZE);
          }
          if (unlink(rsyclp.sfname) == 0) {
               stlcpy(rsptmp,rsyclp.sfname,CSWIDTH);
               stlcat(rsptmp," Deleted!",CSWIDTH);
          }
          else {
               stlcpy(rsptmp,"Access Denied",CSWIDTH);
          }
          curreq(savreq);
          hldreq=rsyclp.request;
          rsp2read(NULL,STGLEN,rsptmp,NULL);
          curreq(hldreq);
          if (!rsyclp.multifil) {
               rsp2write(TRUE,0,NULL,NULL);
          }
          else if (!fndnxt(&rsyclp.dirblk)) {
               rsp2write(TRUE,0,NULL,NULL);
          }
     }
}

static GBOOL
prepcpy(VOID)                 /* prepare for cycled copy processing        */
{
     INT savreq;

     savreq=greqid;
     curreq(rsyclp.request);
     if (!(rsycmn->myflags&CPYREQ) || (rsyclp.status == WRKING)) {
          curreq(savreq);
          return(FALSE);
     }
     rsyclp.status=WRKING;
     if (rsyclp.multifil) {
          stlcpy(rsyclp.dfname,rsyclp.dfpath,FNDSIZE);
          stlcat(rsyclp.dfname,rsyclp.dirblk.ff_name,FNDSIZE);
          stlcpy(rsyclp.sfname,rsyclp.sfpath,FNDSIZE);
          stlcat(rsyclp.sfname,rsyclp.dirblk.ff_name,FNDSIZE);
     }
     if (rsvnam(rsyclp.sfname) || rsvnam(rsyclp.dfname)) {
          cycleme(NULL);
          rsyclp.status=WRKDON;
          rsyclp.sfptr=NULL;
          rsyclp.dfptr=NULL;
          rsp2write(FALSE,0,NULL,NULL);
          curreq(savreq);
          return(FALSE);
     }
     rsyclp.sfptr=fopen(rsyclp.sfname,FOPRB);
     rsyclp.dfptr=gcfsopen(rsyclp.dfname,FOPWB,GSH_DENYRW);
     if ((rsyclp.sfptr == NULL) || (rsyclp.dfptr == NULL)) {
          cycleme(NULL);
          *rsptmp='\0';
          if (rsyclp.sfptr == NULL) {
               stlcpy(rsptmp,"Unable to open source file.",CSWIDTH);
          }
          else if (rsyclp.dfptr == NULL) {
               stlcpy(rsptmp,"Unable to open destination file.",CSWIDTH);
          }
          rsyclp.status=WRKDON;
          if (rsyclp.sfptr != NULL) {
               fclose(rsyclp.sfptr);
          }
          if (rsyclp.dfptr != NULL) {
               fclose(rsyclp.dfptr);
          }
          rsyclp.sfptr=NULL;
          rsyclp.dfptr=NULL;
          rsp2write(FALSE,STGLEN,rsptmp,NULL);
          curreq(savreq);
          return(FALSE);
     }
     curreq(savreq);
     cycleme(docopy);
     return(TRUE);
}

static VOID
docopy(VOID)                  /* perform the actual copy process           */
{
     INT siz,savreq,hldreq;
     LONG tdstamp;

     savreq=greqid;
     if (ismyreq(rsyclp.request,RSYAPN)) {
          curreq(rsyclp.request);
          if (rsycmn->myflags&CPYREQ) {
               if ((rsyclp.sfptr != NULL) && (rsyclp.dfptr != NULL)) {
                    siz=fread(vdatmp,1,CPYSIZ,rsyclp.sfptr);
                    if (siz > 0) {
                         fwrite(vdatmp,1,siz,rsyclp.dfptr);
                    }
                    if (siz <= 0) {
                         cycleme(NULL);
                         rsyclp.status=WRKDON;
                         if (rsyclp.sfptr != NULL) {
                              tdstamp=getFileGMT(rsyclp.sfname);
                              fclose(rsyclp.sfptr);
                              rsyclp.sfptr=NULL;
                              setFileGMT(rsyclp.dfname,tdstamp);
                         }
                         if (rsyclp.dfptr != NULL) {
                              fclose(rsyclp.dfptr);
                              rsyclp.dfptr=NULL;
                         }
                         clear(rsptmp);
                         cpyrsp(rsyclp.sfname);
                         curreq(savreq);
                         hldreq=rsyclp.request;
                         rsp2read(NULL,STGLEN,rsptmp,NULL);
                         curreq(hldreq);
                         if (rsyclp.multifil) {
                              if (!fndnxt(&rsyclp.dirblk)) {
                                   rsp2write(TRUE,0,NULL,NULL);
                              }
                         }
                         else {
                              rsp2write(TRUE,0,NULL,NULL);
                         }
                         return;
                    }
               }
               else {
                    curreq(savreq);
                    cycleme(NULL);
                    rejectreq();
               }
          }
          else {
               curreq(savreq);
               cycleme(NULL);
               rejectreq();
          }
          curreq(savreq);
     }
     else {
          rejectreq();
     }
}

static VOID
dodnl(VOID)                   /* Perform the actual download process       */
{
     INT savreq,hldreq;

     savreq=greqid;
     curreq(rsyclp.request);
     clear(rsptmp);
     clear(vdatmp);
     if (rsycmn->myflags&DNLREQ) {
          cpyrsp(rsyclp.sfpath);
          catrsp(rsyclp.dirblk.ff_name);
          cpyvda(rsyclp.dirblk.ff_name);
          if (sameas(MENUDAT,rsyclp.dirblk.ff_name)) {
               hldreq=greqid;
               curreq(savreq);
               stlcpy(rsyclp.dirblk.ff_name,vdatmp,FNDSIZE);
               curreq(hldreq);
               if (!lockmnu(TRUE)) {
                    hldreq=greqid;
                    curreq(savreq);
                    rsp2read(NULL,0,NULL,NULL);
                    curreq(hldreq);
                    rsp2write(TRUE,0,NULL,NULL);
                    return;
               }
          }
          hldreq=greqid;
          curreq(savreq);
          rsp2read(NULL,STGLEN,rsptmp,NULL);
          curreq(hldreq);
          if (!fndnxt(&rsyclp.dirblk)) {
               rsp2write(TRUE,0,NULL,NULL);
          }
     }
}

static VOID
listdir(VOID)                 /* get a directory listing from server       */
{
     INT hr,savreq,hldreq;

     savreq=greqid;
     curreq(rsyclp.request);
     clear(vdatmp);
     if (rsycmn->myflags&DIRREQ) {
          hr=dthour(rsyclp.dirblk.ff_ftime)%12;
          if (hr == 0) {
               hr=12;
          }
          cpyvda(spr("%-12.12s ",rsyclp.dirblk.ff_name));
          catvda(spr("%8.8s ",(rsyclp.dirblk.ff_attrib&FAMDIR) ?
             "<DIR>" : l2as(rsyclp.dirblk.ff_fsize)));
          catvda(spr("%8.8s ",ncdate(rsyclp.dirblk.ff_fdate)));
          catvda(spr("%2d:%02d%s",hr,dtmin(rsyclp.dirblk.ff_ftime),
             ((dthour(rsyclp.dirblk.ff_ftime)/12) ? "p" : "a")));
          clear(rsptmp);
          cpyrsp(vdatmp);
          curreq(savreq);
          hldreq=rsyclp.request;
          rsp2read(NULL,STGLEN,rsptmp,NULL);
          curreq(hldreq);
          if (!fndnxt(&rsyclp.dirblk)) {
               rsp2write(TRUE,0,NULL,NULL);
          }
     }
}

CHAR * 
stpname(                      /* get a pointer to filename sans path       */
CHAR *fname)                  /*   fully qualified filespec                */
{
     INT stroff;
     CHAR *sptr;

     stlcpy(vdatmp,fname,FNDSIZE);
     stroff=strlen(vdatmp);
     if (stroff > 0) {
          sptr=vdatmp+stroff-1;
     }
     else {
          clear(vdatmp);
          return(vdatmp);
     }
     while ((*sptr != '\\') && (sptr > vdatmp)) {
          sptr--;
     }
     if (*sptr == '\\' && (sptr < vdatmp+stroff-1)) {
          sptr++;
     }
     if (*sptr == NULL) {
          clear(vdatmp);
          return(vdatmp);
     }
     return(sptr);
}

CHAR * 
makpath(CHAR *fname)          /* expand string to qualified pathname       */
{
     INT stroff;

     stroff=strlen(fname);
     if (stroff > 0) {
          switch(*(fname+stroff-1)) {
          case '\\':
               break;
          default:
               stlcat(fname,"\\",FNDSIZE);
               break;
          }
     }
     else {
          stlcpy(fname,"\\",FNDSIZE);
     }
     return(fname);
}

CHAR * 
stppath(CHAR *fname)          /* strip the pathname from a filespec        */
{
     INT stroff;
     CHAR *sptr;

     stlcpy(vdatmp,fname,FNDSIZE);
     stroff=strlen(vdatmp);
     if (stroff > 0) {
          sptr=vdatmp+stroff-1;
     }
     else {
          clear(vdatmp);
          return(vdatmp);
     }
     while ((*sptr != '\\') && (sptr > vdatmp)) {
          sptr--;
     }
     if ((*sptr == '\\') && (sptr < vdatmp+stroff-1)) {
          sptr++;

     }
     *sptr='\0';
     return(vdatmp);
}


GBOOL 
iswild(                       /* does this filespec contain wildcards?     */
CHAR *fname)                  /*   filename to check for wildcards         */
{
     if ((strchr(fname,'*') != NULL) || (strchr(fname,'?') != NULL)) {
          return(TRUE);
     }
     return(FALSE);
}

CHAR * 
fixfil(                       /* this will fix args to give full filespec  */
CHAR *fname)                  /*   passed filename which may be modified   */
{
     INT stroff;

     stroff=strlen(fname);
     if (stroff > 0) {
          switch(*(fname+(stroff-1))) {
          case '.':
               stlcat(fname,"\\*.*",FNDSIZE);
               break;
          case ':':
          case '\\':
               stlcat(fname,"*.*",FNDSIZE);
               break;
          default:
               break;
          }
     }
     else {
          stlcat(fname,".\\*.*",FNDSIZE);
     }
     return(fname);
}

static GBOOL
doswitch(                     /* swtclass vector for account change        */
struct usracc *usract,        /*   user account to switch                  */
CHAR *usrcls,                 /*   name of class to switch them to         */
INT days)                     /*   number of days to remain in class       */
{
     struct clstab *clptr;

     (void)days;
     clptr=fndcls(usrcls);
     if (clptr != NULL) {
          if (clptr->flags&DAYEXP) {
               swtcls(usract,1,usrcls,3,clptr->dftday);
          }
          else if (!(clptr->flags&HASCRD && clptr->flags&NOCRED)) {
               swtcls(usract,1,usrcls,3,0);
          }
          else {
               return(FALSE);
          }
     }
     else {
          return(FALSE);
     }
     return(TRUE);
}

static VOID
initaud(VOID)                      /* initialize the audit trail at end    */
{
     rsyaud.lastVisible=audfNumRecs(hAuditTrail)-1;
}

static VOID
topaud(VOID)                       /* scroll to topmost part of audit trail*/
{
     ULONG lastRec;

     lastRec=audfNumRecs(hAuditTrail)-1;
     rsyaud.lastVisible=min(lastRec,NUMADT-2);
     rsyaud.audmov=(rsyaud.lastVisible != lastRec);
}

static VOID
scraud(                            /* scroll audit trail pointers around   */
INT num)                           /*   # records to move (< 0 == up)    */
{
     ULONG lastRec,newPos;
     GBOOL newMoved;

     newMoved=TRUE;
     lastRec=audfNumRecs(hAuditTrail)-1;
     newPos=rsyaud.lastVisible;
     if (num < 0 && newPos < -num) {
          newPos=0;
     }
     else {
          newPos+=num;
     }
     if (newPos >= lastRec) {
          newPos=lastRec;
          newMoved=FALSE;
     }
     else if (newPos < NUMADT-2) {
          newPos=min(lastRec,NUMADT-2);
     }
     rsyaud.lastVisible=newPos;
     rsyaud.audmov=newMoved;
}

static VOID
getaud(VOID)                       /* get full audit trail lines           */
{
     INT i;
     struct audOldStyle buf;

     for (i=0 ; i < NUMADT ; ++i) {
          if (rsyaud.lastVisible >= (NUMADT-1)-i) {
               audfReadOldStyle(hAuditTrail,rsyaud.lastVisible-((NUMADT-1)-i),
                                &buf,sizeof(struct audOldStyle));
          }
          else {
               memset(&buf,0,sizeof(buf));
          }
          catrsp(buf.stamp);  /* includes brief and channel */
          delimiter();
          catrsp(buf.detail);
          if (i < (NUMADT-1)) {
               delimiter();
          }
     }
}

static VOID
rsyfadd(VOID)                       /* add new entry to the audit trail    */
{
     VOID *mrqptr;
     ULONG lastRec;
     INT usridx,reqidx,reqnum;
     struct saunam rfdpk;

     lastRec=audfNumRecs(hAuditTrail)-1;
     for (usridx=0 ; usridx < nterms ; usridx++) {
          if ((usroff(usridx)->flags&ISGCSU) && (rsyflg[usridx]&AUDFLG)) {
               for (reqidx=0 ; reqidx < 30 ; reqidx++) {
                    reqnum=srvrqid(usridx,reqidx);
                    if (ismyreq(reqnum,RSYAPN)) {
                         mrqptr=(void *)mrqoff(reqnum);
                         if (sameas(rsycmn->mysuffix,AUDSTR)) {
                              if (!rsyaud.audmov) {
                                   rsyaud.lastVisible=lastRec;
                                   if (qroom(usridx,NORMAL)) {
                                        memset(&rfdpk,0,sizeof(struct saunam));
                                        stlcpy(rfdpk.sysid,msysid,SIDSIZ);
                                        stlcpy(rfdpk.appid,RSYAPN,AIDSIZ);
                                        rfdpk.usrid[0]='\0';
                                        stlcpy(rfdpk.suffix,AUDNOT,SFXSIZ);
                                        senddpk(usridx,RSYAPN,NORMAL,&rfdpk,
                                                0,NULL,NULL);
                                   }
                                   break;
                              }
                         }
                    }
               }
          }
     }
}

static VOID
accsrch(VOID)                      /* Search the account database          */
{
     struct saunam rfdpk;
     struct usracc tmpacc;
     GBOOL found;

     dfaSetBlk(accbb);
     clear(vdatmp);
     dfaGetAbs(&tmpacc,rsyfnd.fpos,0);
     found=FALSE;
     switch(rsyfnd.field) {
     case FLDUID:
          found=chkstr(tmpacc.userid);
          break;
     case FLDNAM:
          found=chkstr(tmpacc.usrnam);
          break;
     case FLDPWD:
          found=chkstr(tmpacc.psword);
          break;
     case FLDCMP:
          found=chkstr(tmpacc.usrad1);
          break;
     case FLDAD1:
          found=chkstr(tmpacc.usrad2);
          break;
     case FLDAD2:
          found=chkstr(tmpacc.usrad3);
          break;
     case FLDAD3:
          found=chkstr(tmpacc.usrad4);
          break;
     case FLDPHO:
          found=chkstr(tmpacc.usrpho);
          break;
     case FLDSYS:
          found=chkstr(sysstg[tmpacc.systyp]);
          break;
     case FLDAGE:
          found=chknum(tmpacc.age);
          break;
     case FLDSEX:
          found=(toupper(rsyfnd.srchstg[0]) == tmpacc.sex);
          break;
     case FLDCLS:
          found=chkstr(tmpacc.curcls);
          break;
     case FLDTCR:
          found=chkcdt(tmpacc.totcreds);
          break;
     case FLDTPD:
          found=chkcdt(tmpacc.totpaid);
          break;
     case FLDCRD:
          found=chkcdt(tmpacc.creds);
          break;
     case FLDCDT:
          found=chkdte(tmpacc.credat);
          break;
     case FLDUDT:
          found=chkdte(tmpacc.usedat);
          break;
     case FLDDAY:
          found=chknum(tmpacc.daystt);
          break;
     default:
          break;
     }
     if (found) {
          cpyvda(tmpacc.userid);
          vdelimiter();
          catvda(tmpacc.usrnam);
          setmem(&rfdpk,sizeof(struct saunam),0);
          stlcpy(rfdpk.sysid,msysid,SIDSIZ);
          stlcpy(rfdpk.appid,RSYAPN,AIDSIZ);
          stlcpy(rfdpk.usrid,usaptr->userid,UIDSIZ);
          stlcpy(rfdpk.suffix,SRCHNF,SFXSIZ);
     }
     if (qroom(usrnum,NORMAL)) {
          if (found) {
               senddpk(usrnum,RSYAPN,NORMAL,&rfdpk,STGLEN,vdatmp,NULL);
          }
          if (dfaStepNX(&tmpacc)) {
               rsyfnd.fpos=dfaAbs();
               dfaRstBlk();
          }
          else {
               dfaRstBlk();
               rsp2write(NULL,0,NULL,NULL);
               return;
          }
     }
}

static GBOOL
chkstr(                       /* compare database string to search key     */
CHAR *string)                 /*   string to compare to                    */
{
     return(findstg(rsyfnd.srchstg,string));
}

static GBOOL
chkcdt(                       /* compare database credits to search key    */
LONG credits)                 /*   number of credits to compare with       */
{
     LONG a;

     a=atol(rsyfnd.srchstg);
     if ((rsyfnd.relate >= 1) && (rsyfnd.relate <= 5)) {
          return(glthrv[rsyfnd.relate-1]
                 [(credits >= a ? 1 : 0)+(credits > a ? 1 : 0)]);
     }
     return(FALSE);
}

static GBOOL
chkdte(                       /* compare database date with search key     */
INT date)                     /*   dos date format to comare with          */
{
     INT a;

     a=dcdate(rsyfnd.srchstg);
     if ((rsyfnd.relate >= 1) && (rsyfnd.relate <= 5)) {
          return(glthrv[rsyfnd.relate-1]
                 [(date >= a ? 1 : 0)+(date > a ? 1 : 0)]);
     }
     return(FALSE);
}

static GBOOL
chknum(                       /* compare database number with search key   */
INT number)                   /*   number to compare with                  */
{
     INT a;

     a=atoi(rsyfnd.srchstg);
     if ((rsyfnd.relate >= 1) && (rsyfnd.relate <= 5)) {
          return(glthrv[rsyfnd.relate-1]
                 [(number >= a ? 1 : 0)+(number > a ? 1 : 0)]);
     }
     return(FALSE);
}

static VOID
demstt(VOID)                  /* Get demographics statistics               */
{
     INT ct,ab,cttot;
     USHORT agetot[NAGEBK];

     setmem(agetot,sizeof(agetot),0);
     for (ct=1 ; ct < NACMTY ; ct++) {
          for (ab=0,cttot=0 ; ab < NAGEBK ; ab++) {
               catrsp(spr("%u ",sv2.matrix[ct][ab]));
               cttot+=sv2.matrix[ct][ab];
               agetot[ab]+=sv2.matrix[ct][ab];
          }
          catrsp(spr("%u",cttot));
          delimiter();
     }
     for (ab=0,cttot=0 ; ab < NAGEBK ; ab++) {
          catrsp(spr("%u ",sv2.matrix[0][ab]));
          cttot+=sv2.matrix[0][ab];
          agetot[ab]+=sv2.matrix[0][ab];
     }
     catrsp(spr("%u",cttot));
     delimiter();
     for (ab=0 ; ab < NAGEBK ; ab++) {
          catrsp(spr("%u ",agetot[ab]));
     }
     catrsp(spr("%u ",sv2.numact));
     delimiter();
     catrsp(spr("%u ",sv2.numact-sv2.numfem));
     catrsp(spr("%u ",sv2.numfem));
     catrsp(spr("%u ",sv2.numcor));
     catrsp(spr("%u",sv2.numans));
}

static VOID
clsstt(VOID)                  /* Get class statistical information         */
{
     LONG val;

     if ((clsptr=clshead) == NULL) {
          return;
     }
     while (clsptr != NULL) {
          if (clsptr->flags&HASCRD && clsptr->flags&NOCRED) {
               clsptr=nxtcls(clsptr);
          }
          catrsp(clsptr->clname);
          delimiter();
          val=(clsptr->seconds+1800L)/3600L;
          catrsp(l2as(val));
          delimiter();
          val=(((clsptr->seconds+1800L)/3600L)*24+dtrack/2)/dtrack;
          catrsp(l2as(val));
          delimiter();
          catrsp(spr("%u",clsptr->users));
          delimiter();
          val=((clsptr->seconds)*24+dtrack/2)/dtrack;
          val=(val/(clsptr->users > 0 ? clsptr->users : 1)+30L)/60L;
          catrsp(l2as(val));
          clsptr=nxtcls(clsptr);
          if (clsptr != NULL) {
               catrsp(FLDSEP);
          }
     }
}

static
struct clstab *
nxtcls(                            /* get the next class in sequence       */
struct clstab *from)                    /* starting from here              */
{
     struct clstab *ptr=from;

     while (ptr != NULL) {
          ptr=ptr->next;
          if (ptr == NULL || !(ptr->flags&HASCRD && ptr->flags&NOCRED)) {
               break;
          }
     }
     return(ptr);
}

static VOID
mscstt(VOID)                       /* get miscellaneous and module stats   */
{
     INT i;

     catrsp(l2as(sv2.totcalls));
     delimiter();
     catrsp(l2as(sv.uplds));
     delimiter();
     catrsp(l2as(sv.dwnlds));
     delimiter();
     catrsp(l2as(sv.msgtot));
     delimiter();
     catrsp(l2as(sv.emlopn));
     delimiter();
     catrsp(l2as(sv.sigopn));
     delimiter();
     catrsp(l2as(sv2.x25mbs));
     delimiter();
     catrsp(l2as(sv2.x25kps));
     delimiter();
     catrsp(l2as(sv2.freepst));
     delimiter();
     catrsp(l2as(sv2.paidpst));
     delimiter();
     for (i=0 ; i < nmods ; i++) {
          catrsp(mdstats[i].mdname);
          catrsp(FLDSEP);
          catrsp(l2as((mdstats[i].seconds+1800L)/3600L));
          catrsp(FLDSEP);
          catrsp(l2as(mdstats[i].creds));
          if (i < (nmods-1)) {
               delimiter();
          }
     }
}

static VOID
initgrph(VOID)                     /* initialize variables for graphs */
{
     if (sv2.lstzer == 0) {
          sv2.lstzer=today();
          mytrack=1;
     }
     else {
          mytrack=cofdat(today())-cofdat(sv2.lstzer);
          mytrack=(mytrack == 0 ? 1 : mytrack);
     }
     catrsp(months[ddmon(sv2.lstzer)]);
     delimiter();
}

static VOID
liugph(VOID)
{
     INT i;
     LONG biggest;

     initgrph();
     for (i=0 ; i < 48 ; i++) {
          biggest=(LONG)((sv2.nliniu[i]+mytrack/2)/mytrack);
          catrsp(l2as(biggest));
          if (i < 47) {
               catrsp(FLDSEP);
          }
     }
}

static VOID
sebgph(VOID)                       /* get sessions/baudrate data      */
{
     INT i;

     initgrph();
     for (i=0 ; i < 8 ; i++) {
          catrsp(l2as((LONG)sv.calls[i]));
          if (i < 7) {
               catrsp(FLDSEP);
          }
     }
}

static VOID
tuhgph(VOID)                       /* get time used statistics info   */
{
     INT i,j;
     LONG totals[24];

     initgrph();
     setmem(totals,sizeof(totals),0);
     for (i=0 ; i < 24 ; i++) {
          for (j=0 ; j < NUMGRPS-1 ; j++) {
               totals[i]+=sv3.secghr[j][i];
          }
          totals[i]=((totals[i]+30L)/60L+mytrack/2)/mytrack;
     }
     for (i=0 ; i < 24 ; i++) {
          catrsp(l2as(totals[i]));
          if (i < 23) {
               catrsp(FLDSEP);
          }
     }
}

static void
tuggph(void)
{
     INT i,j;
     LONG totals[NUMGRPS-1],temp;

     initgrph();
     setmem(totals,sizeof(totals),0);
     for (i=0 ; i < NUMGRPS-1 ; i++) {
          for (j=0 ; j < 24 ; j++) {
               totals[i]+=sv3.secghr[i][j];
          }
          totals[i]=(temp=((totals[i]+1800L)/3600L+mytrack/2)/mytrack) > 9999L
               ? 9999L : temp;
     }
     for (i=0 ; i < NUMGRPS-1 ; i++) {
          catrsp(l2as(totals[i]));
          if (i < (NUMGRPS-2)) {
               catrsp(FLDSEP);
          }
     }
}

static VOID
cuhgph(VOID)                       /* draw graph of credits used      */
{
     INT i,j;
     LONG totals[24];

     initgrph();
     setmem(totals,sizeof(totals),0);
     for (i=0 ; i < 24 ; i++) {
          for (j=0 ; j < NUMGRPS-1 ; j++) {
               totals[i]+=sv3.crdghr[j][i];
          }
          totals[i]=((totals[i]+500L)/1000L+mytrack/2)/mytrack;
     }
     for (i=0 ; i < 24 ; i++) {
          catrsp(l2as(totals[i]));
          if (i < 23) {
               catrsp(FLDSEP);
          }
     }
}

static VOID
cuggph(VOID)                       /* draw graph of credits used/g#   */
{
     INT i,j;
     LONG totals[NUMGRPS-1],temp;

     initgrph();
     setmem(totals,sizeof(totals),0);
     for (i=0 ; i < NUMGRPS-1 ; i++) {
          for (j=0 ; j < 24 ; j++) {
               totals[i]+=sv3.crdghr[i][j];
          }
          totals[i]=(temp=((totals[i]+500L)/1000L+mytrack/2)/mytrack) > 9999L
               ? 9999L : temp;
     }
     for (i=0 ; i < NUMGRPS-1 ; i++) {
          catrsp(l2as(totals[i]));
          if (i < (NUMGRPS-2)) {
               catrsp(FLDSEP);
          }
     }
}

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

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

static VOID
genabt(VOID)                       /* general "about" screen information   */
{
     clear(rsptmp);
     catrsp(OSTYPE);
     delimiter();
     catrsp(abttl);
     delimiter();
     catrsp(crdts);
     delimiter();
     catrsp(cprit);
     delimiter();
     getntrm();
     delimiter();
     catrsp(bturno);
     delimiter();
     catrsp(version);
     catrsp(subvers);
     delimiter();
#ifdef GCWINNT
     catrsp("(See Registry)");
#else
     if (btrset[0] != '\0') {
          catrsp(btrset);
     }
     else {
          catrsp("defaults");
     }
#endif // GCWINNT
     delimiter();
     catrsp(itoa(curdlls,vdatmp,10));
     delimiter();
}
