' $linesize:132
' $title: 'RBBSSUB5.BAS CPC17.3, Copyright 1986 - 90 by D. Thomas Mack'
'  Copyright 1990 by D. Thomas Mack, all rights reserved.
'  Name ...............: RBBSSUB5.BAS
'  First Released .....: February 4, 1990
'  Subsequent Releases.: 
'  Copyright ..........: 1986 - 1990
'  Purpose.............: The Remote Bulletin Board System for the IBM PC,
'     RBBS-PC.BAS utilizes a lot of common subroutines.  Those that do not
'     require error trapping are incorporated within RBBSSUB 2-5 as
'     separately callable subroutines in order to free up as much
'     code as possible within the 64K code segment used by RBBS-PC.BAS.
'  Parameters..........: Most parameters are passed via a COMMON statement.
'
' Subroutine  Line               Function of Subroutine
'   Name     Number
'  BinSearch      63520  Binary searches sorted file for a key value
'  BreakFileName  63300  Break file name into component parts
'  BufAsUnit      63500  Buffer out a string with CR's
'  SetPrompt      63470  Set prompts based on the user's security
'  DoorReturn     63100  Process door requests
'  FdMacExe       63462  Executes a found macro
'  FileSystem     20117  File System for RBBS-PC
'  FindIt         63490  Check whether file exists and if so open as #2
'  FormRead       63420  Read from file into a form
'  LockAppend     63400  Prepare for a file append
'  MacroExe       63460  Execute internal macro rather than user
'  MsgNameMatch   63540  Match name to one in msg header
'  NoPath         63480  Detects whether string has a path in it
'  RestoreCom     63310  Restore comm port after external program
'  ReadMacro      63330  Read and process macro
'  ShellExit      63320  Exit RBBS via shell
'  TakeOffHook    63530  Take modem off hook
'  UnLockAppend   63410  Clean up after file append
'  VerifyAns      63510  Verify that string passes edits
'  WildCard       63200  Match string to a pattern
'
'  $INCLUDE: 'RBBS-VAR.BAS'
'
20117 ' $SUBTITLE: 'FileSystem -- subroutine for RBBS-PC's file system'
' $PAGE
'
' NAME    -- FileSystem
'
' INPUTS  --       PARAMETER                 MEANING
'             ZFileSysParm = 1  LIST THE SYSOP'S COMMENTS FILE
'                                 2  L)IST DIRECTORY COMMAND
'                                 3  D)OWNLOAD COMMAND
'                                 4  RETURN FROM EXTERNAL PROTOCOLS
'                                 5  U)PLOAD COMMAND
'                                 6  S)CAN DIRECTORY COMMAND
'                                 7  P)ERSONAL FILES COMMAND
'                                 8  N)EW FILES COMMAND
'                                 9  RETURN FROM EXTENDED DESCRIPTION
'
' OUTPUTS -- ZFileSysParm = 1  COMMAND PROCESSED SUCCESSFULLY
'                                2  RECYCLE TO TOP OF RBBS-PC (202)
'                                3  PROCESS NEXT COMMAND (1200)
'                                4  DENY USER ACCESS (1380)
'                                5  HANDLE EXTENDED DESCRIP. (2008)
'                                6  USER'S TIME EXCEEDED (10553)
'                                7  Carrier DROPPED (10595)
'
' PURPOSE -- To handle the RBBS-PC file system commands
'
      SUB FileSystem STATIC
      ZFF = ZFileSysParm
      ZFileSysParm = 1
      ON ZFF GOSUB 20119, _  ' HANDLER TO LIST COMMENTS TO SYSOP
                  20150, _  ' L)IST DIRECTORY COMMAND HANDLER
                  20180, _  ' D)OWNLOAD COMMAND HANDLER
                  20263, _  ' RETURN FROM EXTERNAL Protocol'S
                  20400, _  ' U)PLOAD COMMAND HANDLER
                  21800, _  ' S)CAN DIRECTORY COMMAND HANDLER
                  21850, _  ' P)ERSONAL FILES COMMAND HANDLER
                  21860, _  ' N)EW FILES COMMAND HANDLER
                  20705     ' RETURN FROM EXTENDED DESCRIPTIONS
      GOTO 21920
20119 ZErrCode = 0
      GOTO 20122
'
' *****  SCAN DIRECTORIES (PRINT TEXT)  ****
'
'  (formerly lines 7000 to 7260 in RBBS-PC.BAS CPC16-1ZWasA
20120 ZOutTxt$ = "Scanning Directory " + _
           ZFileNameHold$
      IF WasRS$ <> "" THEN _
         ZOutTxt$ = ZOutTxt$ + " for " + WasRS$
      GOSUB 21650
      IF ZFileSysParm > 1 THEN _
         RETURN
      WasPG = ZTrue
20122 CALL OpenWork (2,ZFileName$)
      IF ZErrCode = 53 THEN _
         ZOutTxt$ = "Missing File " + ZFileName$ : _
         CALL UpdtCalr (ZOutTxt$,2) : _
         ZOutTxt$ = ZOutTxt$ + _
              ". Please tell SYSOP" : _
         GOSUB 21650 : _
         RETURN
      ZJumpSupported = ZTrue
      ZJumpLast$ = ""
      LastOK = ZFalse
20124 CALL Carrier
      IF EOF(2) OR _
         (ZSubParm = -1 AND NOT ZLocalUser) THEN _
         GOTO 20142
20126 CALL ReadDir (2,1)
      IF ZErrCode <> 0 THEN _
         ZWasEL = 20126 : _
         GOTO 21900
      IF WasCK = 0 THEN _
         GOTO 20140
      IF LEFT$(ZOutTxt$,1) = " " THEN _
         IF LastOK AND NOT ZExtendedOff THEN _
            GOTO 20140 _
         ELSE GOTO 20124
      LastOK = ZFalse
20128 IF ZJumpSearching THEN _
         GOTO 20129
      IF WasCK < 2 THEN _
         GOTO 20130
      IF WildSearch THEN _
         ZWasA = INSTR(ZOutTxt$," ") : _
         IF ZWasA = 0 THEN _
            GOTO 20124 _
         ELSE ZWasZ$ = LEFT$(ZOutTxt$,ZWasA - 1) : _
              CALL WildFile (WasRS$,ZWasZ$,WasXXX) : _
              WasXXX = NOT WasXXX : _
              GOTO 20136
20129 ZWasZ$ = ZOutTxt$
      CALL AllCaps (ZWasZ$)
      WasXXX = (INSTR(ZWasZ$,WasRS$) = 0)
      GOTO 20136
20130 ZWasA = INSTR(9,MID$(ZOutTxt$,1,32),"/")
      IF ZWasA = 0 THEN _
         ZWasA = INSTR(9,MID$(ZOutTxt$,1,32),"-")
20132 IF ZWasA < 3 THEN _
         GOTO 20124
      IF INSTR("0123456789",MID$(ZOutTxt$,ZWasA - 1,1)) = 0 THEN _
         GOTO 20124
      ZWasA = ZWasA - 2
      WasWK$ = RIGHT$(MID$(ZOutTxt$,ZWasA,8),2) + _
            LEFT$(MID$(ZOutTxt$,ZWasA,8),2) + _
            MID$(MID$(ZOutTxt$,ZWasA,8),4,2)
      IF MID$(WasWK$,3,1) = " " THEN _
         MID$(WasWK$,3,1) = "0"
      IF MID$(WasWK$,5,1) = " " THEN _
         MID$(WasWK$,5,1) = "0"
20134 WasXXX = (WasWK$ < WasRS$)
20136 IF WasXXX THEN _
         GOTO 20124
      IF ZJumpSearching THEN _
         WasRS$ = PrevSearch$ : _
         WasCK = PrevCK : _
         ZJumpSearching = ZFalse : _
         GOTO 20140
      IF WasPG THEN _
         WasPG = ZFalse : _
         CALL OpenWork (2,ZFileName$) : _
         ZWasQ = 0 : _
         GOTO 20124
20138 IF WasPG THEN _
         GOTO 20124
20140 LastOK = ZTrue
      GOSUB 21650
      IF ZFileSysParm > 1 THEN _
         RETURN
      CALL AskMore ("",ZTrue,ZTrue,ZAnsIndex,ZFalse)
      IF ZNo THEN _
         ZErrCode = 0 : _
         RETURN
      IF ZJumpSearching THEN _
         IF LEFT$(ZOutTxt$,1) <> " " THEN _
            PrevSearch$ = WasRS$ : _
            PrevCK = WasCK : _
            WasCK = 2 : _
            WasRS$ = ZJumpTo$
      IF NOT ZRet THEN _
         GOTO 20124
20142 ZWasQ = 0
      ZJumpSupported = ZFalse
      CLOSE 2
      CALL Carrier
      IF ZSubParm = -1 THEN _
         ZFileSysParm = 7
      RETURN
'
' *  L - COMMAND FROM FILES MENU (LIST DIRECTORY)
'
20150 ZListDir = ZTrue
      ListNew = ZFalse
      SearchDate$ = ""
      SearchString$ = ""
      WasRS$ = ""
      ShowDirOfDir = (ZLastIndex <= ZAnsIndex) AND NOT ZExpertUser
      WasCK = 0
      ZSearchingAll = ZFalse
20155 IF ZDnldCompleted AND ZAutoEnd = 1 THEN _   'Pe 02/05/90
        ZFileSysParm = 7: _
        RETURN
'  IF ListNew OR ZAnsIndex > 255 THEN _
'         RETURN
  IF ZAnsIndex > 255 THEN _    'Pe 03/18/90
         RETURN
      CALL GetDirs   (ShowDirOfDir)  'Pe 02/04/90     ' Bh 06/25/90
      IF ZWasQ = 0 THEN _
         RETURN
      ShowDirOfDir = ZFalse
      CALL ConvertDir (ZAnsIndex)
      WasQX = ZLastIndex
20157 CALL Carrier
      IF ZSubParm = -1 THEN _
         ZFileSysParm = 7 : _
         RETURN
      GOTO 20161
20159 IF ZAnsIndex < ZLastIndex THEN _
         GOTO 20155
      ZSearchingAll = ZFalse
      CALL CmdStackPushPop (1)
      ZLastIndex = 0
      IF ZNo OR (ZFileNameHold$ = ZDirPrefix$) THEN _
         GOTO 20155
  CALL QuickTPut (ZEmphasizeOff$,0)
  ZOutTxt$ = "__________________________________________________" + ZCrLf$     ' Bh 083090
  ZOutTxt$ = ZOutTxt$ + "That's all!  R)elist,+)xtra,V)iew,[Q]uit, or file(s) to download"   'Pe 02/15/90
      ZStackC = ZTrue
      GOSUB 21668
      CALL AllCaps (ZUserIn$(1))
'******************************* Pe 02/15/90 **********************
     IF ZUserIn$(1) = "+"  AND _
         ZUserSecLevel >= ZOptSec(19 - 20 * (ZMenuIndex = 6)) THEN _
         ZAnsIndex = 1 : _   
        CALL TypeFile : _
       RETURN
     IF ZUserIn$(1) = "V"  AND _
         ZUserSecLevel >= ZOptSec(19 - 20 * (ZMenuIndex = 6)) THEN _
         ZAnsIndex = 1 : _   
        CALL GetArc : _
       RETURN
'******************************************************************
      IF ZUserIn$(1) = "R" THEN _
         ZUserIn$(ZAnsIndex) = WasA1$ : _
         GOTO 20161
      IF LEN(ZUserIn$(1)) > 1 AND _
         ZUserSecLevel >= ZOptSec(19 - 20 * (ZMenuIndex = 6)) THEN _
         ZAnsIndex = 1 : _
         GOSUB 20202
      CALL CmdStackPushPop (2)
      RETURN
20161 IF INSTR(ZUserIn$(ZAnsIndex),".") THEN _
         GOTO 20172
      ZViolation$ = "List Dir. "
      ZWasZ$ = ZUserIn$(ZAnsIndex)
      ZWasA = INSTR("E+E-E",ZWasZ$)
      IF ZWasA > 0 THEN _
         IF ZWasA = 5 THEN _
            ZExtendedOff = NOT ZExtendedOff : _
            GOTO 20155 _
         ELSE ZExtendedOff = (ZWasA > 2) : _
              GOTO 20155
      CALL AllCaps(ZWasZ$)
      ZFileNameHold$ = ZWasZ$
      WasA1$ = ZWasZ$
      IF ZWasZ$ = ZDirPrefix$ THEN _
         GOTO 20164
      InFMS = ZFalse
20162 CALL CmdStackPushPop (1)         ' save dir list list processing
      CALL FMS (ZWasZ$,SearchString$,SearchDate$,InFMS, _
                ZCategoryName$(),ZCategoryCode$(),ZCategoryDesc$(),_
                DnldFlag,CatFound,ZAnsIndex)
      WHILE DnldFlag > 0 AND ZSubParm > -1
         GOSUB 20202
         IF ZFileSysParm > 1 THEN _
            RETURN
        IF ZDnldCompleted and ZAutoEnd = 1 THEN _  'Pe 02/05/90
           RETURN       ' AUTOLOGOFF MOD
         WasX$ = ZCategoryCode$(CatFound)
         CALL DispUpDir (WasX$,SearchString$,SearchDate$,DnldFlag,ZAnsIndex)
         CALL CheckTimeRemain (MinsRemaining)
         IF ZSubParm = -1 THEN _
            ZFileSysParm = 6 : _
            RETURN
         CALL Carrier
      WEND
      IF ZSubParm = -1 THEN _
         ZFileSysParm = 7 : _
         RETURN
      IF ZAnsIndex > 255 THEN _
         ZLastIndex = 0 : _
         RETURN
      CALL CmdStackPushPop (2)        ' restore dir list list processing
      ZActiveFMSDir$ = ""
      IF InFMS THEN _
         GOTO 20159
      IF ZUserSecLevel < ZMinSecToView THEN _
         IF ZFileNameHold$ = ZUpldDirCheck$ THEN _
        ZOutTxt$ = "Listing of Upload Directory Available to SYSOP Only" : _ 'DGS-TXT
        GOSUB 21640 : _                                           'DGS-TXT
        ZNo = ZTrue : _                                           'DGS-TXT
        GOTO 20155                                                'DGS-TXT
'            ZFileNameHold$ = "of uploads" : _
'            GOTO 20172
      ZFileNameHold$ = ZUserIn$(ZAnsIndex)
      IF ZLimitSearchToFMS THEN _
         GOTO 20166
      IF NOT ZSearchingAll THEN _
         IF ZFileNameHold$ = "ALL" OR ZFileNameHold$ = "A" THEN _
            ZSearchingAll = ZTrue : _
            GOSUB 21890 : _
            GOTO 20157
      CALL BadFile (ZFileNameHold$,BadFileNameIndex)
      ON BadFileNameIndex GOTO 20163,20172,20176
20163 ZFileName$ = ZFileNameHold$
      CALL BadName (BadFileNameIndex)
      ON BadFileNameIndex GOTO 20164,20176
20164 IF ZFileName$ = ZUpldDirCheck$ AND _
         ZUserSecLevel >= ZMinSecToView THEN _
            ZFileName$ = ZUpldPath$ _
      ELSE ZFileName$ = ZCurDirPath$
      ZFileName$ = ZFileName$ + _
                   ZFileNameHold$ + _
                   "." + _
                   ZDirExtension$
      CALL Graphic (ZUserGraphicDefault$,ZFileName$)
20165 IF ZOK THEN _
         CALL ReadDir (2,1) : _
         IF ZErrCode = 0 THEN _
            IF LEFT$(ZOutTxt$,4) = "\FMS" THEN _
               InFMS = ZTrue : _
               ZActiveFMSDir$ = ZFileName$ : _
               GOTO 20162 _
            ELSE GOTO 20167
20166 ZFileName$ = ZCurDirPath$ + _
                   ZFileNameHold$ + ".MNU"
      CALL FindIt (ZFileName$)
      IF ZOK THEN _
         CALL BufFile (ZFileName$,ZAnsIndex) : _
         GOTO 20155
      IF ZAltdirExtension$ = "" THEN _
         GOTO 20172
      ZFileName$ = ZCurDirPath$ + _
                   ZFileNameHold$ + _
                   "." + _
                   ZAltdirExtension$
      CALL Graphic (ZUserGraphicDefault$,ZFileName$)
      IF NOT ZOK THEN _
         GOTO 20172
20167 ZUserIn$(0) = ZUserIn$(ZAnsIndex)
      GOSUB 20120
      IF ZFileSysParm > 1 THEN _
         RETURN
      GOTO 20170
20168 CALL BufFile(ZFileName$,ZAnsIndex)
      CALL Carrier
      IF ZSubParm = -1 THEN _
         ZFileSysParm = 7 : _
         RETURN
20170 IF ZAnsIndex > 255 THEN _
         ZLastIndex = 0 : _
         RETURN
      ZUserIn$(ZAnsIndex) = ZUserIn$(0)
      GOTO 20159
20172 IF NOT ZSearchingAll THEN _
         ZOutTxt$ = "Directory " + _
              ZFileNameHold$ + _
              " not found!" : _
         GOSUB 21640 : _
         ZNo = ZTrue : _
         IF ZFileSysParm > 1 THEN _
            RETURN
      GOTO 20155
20176 CALL SecViolation
      IF ZDenyAccess THEN _
         ZFileSysParm = 4 : _
         RETURN
      GOTO 20172
'
' *  D - COMMAND FROM FILES MENU (SEARCH FOR FILE TO DOWNLOAD)
'
20180 ZOutTxt$ = "Default Extension is " +ZDefaultExtension$ + ZCrLf$ + _
                 "Download what file(s)"
      ZStackC = ZTrue
      GOSUB 21668
      IF ZFileSysParm > 1 THEN _
         RETURN
      IF ZWasQ = 0 THEN _
         RETURN
20202 IF (ZTimeLock AND 2) AND (NOT TimeLockExempt) AND NOT ZHasPrivDoor THEN _
         CALL TimeLock : _
         IF NOT ZOK THEN _
            RETURN
      LastDnld = ZLastIndex
      FirstDnld = ZAnsIndex
      ZCmdTransfer$ = ""
'      IF ZAutoDownYes THEN _   'Pe 02/04/90
'        ZCmdTransfer$ = "X"
'      ZAutoDownInProgress = ZAutoDownYes
      ZAnsIndex = ZLastIndex
      GOSUB 20470
      LastDnld = LastDnld + (WasX > 0)
      BatchBytes# = 0
      BatchBlocks# = 0
      ZDownFiles = 0
      CALL KillWork (ZNodeWorkFile$)
      ZErrCode = 0
      FOR ZAnsIndex = FirstDnld TO LastDnld
         GOSUB 20470
         GOSUB 20205
         ZCmdTransfer$ = ZWasFT$
         CALL Line25
         IF ZFileSysParm > 1 OR ZInternalProt$ = "N" THEN _
            ZAnsIndex = LastDnld + 1
20203 NEXT
      ZLastIndex = 0
      IF ZFileSysParm > 1 THEN _
         RETURN
      ZBatchTransfer = ZFalse
      ZCmdTransfer$ = ""
      RETURN
20205 MarkingTime = (ZAnsIndex = FirstDnld OR NOT ZConcatFIles)
      ZFileName$ = ZUserIn$(ZAnsIndex)
'      CALL AllCaps(ZFileName$)              'ANSIEd    ' Bh 110790
      CALL Remove (ZFileName$,", ")
      ZViolation$ = "Download "
      IF PersonalDnld THEN _
         CALL BreakFileName (ZFileName$,DR$,ZWasY$,WasX$,ZTrue) : _
         ZFileNameHold$ = ZWasY$ + _
                           WasX$ : _
         GOTO 20235
      ZFileNameHold$ = ZFileName$
      CALL BadFile (ZFileName$,BadFileNameIndex)
      ON BadFileNameIndex GOTO 20220,20231,20233
20220 FileNameAlt$ = ""                         ' Pe 02/16/90
      IF INSTR (ZFileName$,".") = 0 THEN _
         FileNameAlt$ = ZFileName$ : _
         ZFileName$ = ZFileName$ + "." + ZDefaultExtension$ : _
       ZFileNameHold$ = ZFileNameHold$ + "." + ZDefaultExtension$ ' Pe 02/16/90
20222 CALL RotorsDir (ZFileName$,ZSubDir$(),ZSubDirCount + _
                      ((ZUserSecLevel < ZMinSecToView) OR _
                       NOT ZCanDnldFromUp),MarkingTime,"D")
20225 IF ZOK THEN _
         GOTO 20235
      IF ZDotFlag THEN _
         RETURN
      IF FileNameAlt$ <> "" THEN _
         ZFileName$ = FileNameAlt$ : _
         FileNameAlt$ = "" : _
         ZFileNameHold$ = ZFileName$ : _
         GOTO 20222
20231 ZNotHere$ = ZWelcomeFileDrvPath$ + "NOTHERE.DEF"   ' Bh 090990
'      ZBobNo$ = "Hmmm....I can't seem to find " + ZFileNameHold$ + _
'           ". I don't think I have it."     ' Bh
      CALL BufFile (ZNotHere$,WasX)
      IF NOT ZOK THEN _
      ZBobNo$ = "Hmmm...I can't seem to find " + ZFileNameHold$ + _
           ". You sure it's in this collection?" + ZCrLf$  ' Bh
      ZOutTxt$ = ZBobNo$ + "Try typing it again "+ZPressEnterExpert$
'      CALL QuickTPut1 (ZBobNo$ + ZCrLf$ + "Try again "+ZPressEnterExpert$)
      CALL UpdtCalr ("Couldn't find " + ZFileNameHold$,1)
      'IF ZAutoDownInProgress THEN _                                  ' DA090903
      '   ZOutTxt$ = ZOutTxt$ + _
      '        " during AUTODOWNLOAD" : _
      '   GOSUB 21640 : _
      '   RETURN
      'ZOutTxt$ = ZOutTxt$ + ZCrLf$ + _
      '    "You are either in a BY REQUEST ONLY collection, or " + ZCrLf$    ' Bh 090690
      'ZOutTxt$ = ZOutTxt$ + _
      '     "Perhaps you misspelled.  Try again "+ZPressEnterExpert$   ' Bh 090690
      ZSuspendAutoLogoff = ZTrue                                     ' KG112202
      GOSUB 21660
      ZSuspendAutoLogoff = ZFalse
      IF ZFileSysParm > 1 THEN _
         RETURN
      IF ZWasQ=0 THEN _
         IF ZBatchTransfer AND ZAnsIndex >= LastDnld THEN _
            GOTO 20262 _
         ELSE ZAutoLogOffReq = ZFalse : _
              RETURN
      ZUserIn$(ZAnsIndex) = ZUserIn$(1)
      GOTO 20205
20233 CALL SecViolation
      IF ZDenyAccess THEN _
         ZFileSysParm = 4 : _
         RETURN
      GOTO 20231
20235 CALL BadName (BadFileNameIndex)
      ON BadFileNameIndex GOTO  20236,20245
20236 ZLine25$ = "(D) " + _
                 ZWasZ$
'      IF ZAutoDownInProgress THEN _
'         MID$(ZLine25$,2,1) = "A"
'
' *  TEST FOR DOWNLOAD SECURITY
'
      CALL OpenWork (2,ZFileSecFile$)
      IF ZErrCode = 53 THEN _
         CALL UpdtCalr ("Missing file " + ZFileSecFile$,2) : _
         GOTO 20247
20242 IF EOF(2) THEN _
         GOTO 20247
      CALL ReadParms (ZWorkAra$(),3,1)
      IF ZErrCode <> 0 THEN _
         ZWasEL = 20242 : _
         GOTO 21900
20243 CALL WildFile (ZWorkAra$(1),ZWasZ$,ZOK)
      IF NOT ZOK THEN _
         GOTO 20242
20244 IF ZUserSecLevel < VAL(ZWorkAra$(2)) THEN _
         GOTO 20245
      FilePswd$ = ZWorkAra$(3)
      IF FilePswd$ = "" THEN _
         GOTO 20247
      CALL AllCaps (FilePswd$)
      IF FilePswd$ = ZPswd$ THEN _
         GOTO 20247
      ZOutTxt$ = "Enter PASSWORD to download " + _
           ZFileName$
      GOSUB 21660
      IF ZFileSysParm > 1 THEN _
         RETURN
      IF ZWasQ = 0 THEN _
         RETURN
      CALL AllCaps (ZUserIn$(1))
      IF ZUserIn$(1) = FilePswd$ THEN _
         GOTO 20247
20245 ZViolation$ = "DownLoad " + _
                   ZFileName$
20246 CALL SecViolation
      IF ZDenyAccess THEN _
         ZFileSysParm = 4
      RETURN
20247 ZWasDF = 0
      CALL BreakFileName (ZFileName$,DR$,WasX$,Extension$,ZFalse)
      'IF ZAutoDownInProgress THEN _
      '   ZOutTxt$ = "Transferring -- " + _
      '        ZUserIn$(ZAnsIndex) : _
      '   GOSUB 21640 : _
      '   IF ZFileSysParm > 1 THEN _
      '      RETURN
      IF INSTR("...WRK.FW .ARC.EXE.COM.OBJ.WKS.LBR.ZIP.PAK.ZOO.LZH.","."+Extension$+".") > 2 OR _
         MID$(Extension$,2,1) = "Q" OR _
         (ZRequireNonASCII AND Extension$ = "BAS") THEN _
            ZWasDF = ZTrue
20248 ZOutTxt$ = ""
      IF ZBatchTransfer THEN _
         IF ZAnsIndex < LastDnld THEN _
            GOTO 20260
      CALL XferType (2,ZTrue)
      IF ZFF THEN _
         GOTO 20260
      CALL XferType (1,ZTrue)
      IF ZSubParm = -1 THEN _
         ZFileSysParm = 7 : _
         RETURN
20260 ZTransferFunction = 1
      GOSUB 21790
      IF ZFileSysParm > 1 THEN _
         RETURN
      ZBatchTransfer = ZBatchProto                     'Pe Batch Mod
      IF ZBatchTransfer AND ZCmdTransfer$ = "" THEN _
         ZCmdTransfer$ = ZWasFT$
      ON INSTR("AXCYN",ZInternalProt$) GOTO _
         20340, _              ' ASCII DOWNLOAD
         20290, _              ' Xmodem
         20290, _              ' Xmodem CRC
         20270, _              ' YMODEM
         21700                 ' NONE - CANCEL
'
' *  EXTERNAL Protocol Downloads/Uploads
'
20261 IF ZReq8Bit THEN _
         IF NOT ZEightBit THEN _
            GOSUB 20318 : _
            IF ZFileSysParm > 1 THEN _
               RETURN _
            ELSE GOSUB 20992 : _
                 IF ZFileSysParm > 1 THEN _
                    RETURN
      IF ZTransferFunction = 1 THEN _
         GOSUB 20750 : _
         CLOSE 2 : _
         IF ZFileSysParm > 1 OR NOT ZOK THEN _
            RETURN
20262 IF ZBatchTransfer THEN _
         IF ZAnsIndex < LastDnld THEN _
            RETURN _
         ELSE ZBlocksInFile# = BatchBlocks# : _
              ZBytesInFile# = BatchBytes# : _
              ZNumDnldBytes! = BatchBytes# : _
              IF ZBytesInFile# < 1 THEN _
                 RETURN _
              ELSE GOSUB 20780 : _
                   IF ZFileSysParm > 1 OR NOT ZOK THEN _
                      RETURN
'      IF ZAutoDownInProgress THEN _
'         CALL SendName                   'PE 02/16/90
         IF ZAbort THEN _
           ZDnldCompleted = ZFalse : _    'Pe 02/16/90
            GOSUB 21760 : _
            RETURN
      CALL Transfer
20263 IF ZPrivateDoor THEN _
         ZCmdTransfer$ = ZWasFT$ : _
         CALL XferType (2,ZTrue) : _
         ZCmdTransfer$ = ""
      CALL OpenWork (2,"XFER-" + ZNodeID$ + ".DEF")
      IF ZErrCode <> 0 THEN _
         GOTO 20267
      CALL ReadParms (ZWorkAra$(), ZFailureParm, 1)
      IF ZErrCode <> 0 THEN _
         GOTO 20267
      CALL KillWork ("XFER-" + ZNodeID$ + ".DEF")
20264 IF ZPrivateDoor THEN _
         ZFileName$ = ZWorkAra$(1) : _
         CALL BreakFileName (ZFileName$,WasX$,ZFileNameHold$,ZWasY$,ZTrue) : _
         ZFileNameHold$ = ZFileNameHold$ + _
                           ZWasY$
      IF LEFT$(ZWorkAra$(ZFailureParm),1) = "L" THEN _
         MID$(ZWorkAra$(ZFailureParm),1,1) = ZFailureString$
20265 IF ZTransferFunction = 2 THEN _
         IF INSTR(ZWorkAra$(ZFailureParm),ZFailureString$) <> 1 THEN _
            GOTO 20700 _
         ELSE GOTO 20730
      IF ZTransferFunction = 1 THEN _
  ZDnldCompleted = (INSTR(ZWorkAra$(ZFailureParm),ZFailureString$) <> 1) 'Pe 02/05/90
      GOSUB 21760
      CALL Carrier
      IF ZSubParm = -1 THEN _
         ZFileSysParm = 7
      RETURN
'
' *  XFER FILE NOT Found
'
20267 ZWasEL = 20263
      GOTO 21900

'
' *  YMODEM DOWNLOAD DRIVER
'
20270 GOTO 20292
'
' *  Xmodem DOWNLOAD DRIVER
'
20290 '
20292 GOSUB 20750
      IF ZFileSysParm > 1 OR NOT ZOK THEN _
         RETURN
      WasA1$ = "SEND"
      GOSUB 20320
      IF ZFileSysParm > 1 THEN _
         RETURN
      IF ZLocalUser THEN _
         CALL QuickTPut1 ("Protocol not available in local mode") : _
         RETURN
'      IF ZAutoDownInProgress THEN _
'         GOSUB 20294                    'PE 02/16/90
         IF ZAbort THEN _               'PE 02/16/90
            RETURN
      GOSUB 21300
      IF ZFileSysParm > 1 THEN _
         RETURN
      ZOutTxt$ = ""
      GOTO 20390
'20294 CALL SendName
'      RETURN
20318 ZOutTxt$ = "Please Switch to N,8,1 for binary transfer"
      GOSUB 21630
      IF ZFileSysParm > 1 THEN _
         RETURN
      CALL DelayTime (3)
      RETURN
20320 IF NOT ZEightBit THEN _
         GOSUB 20318 : _
         IF ZFileSysParm > 1 THEN _
            RETURN
20325 IF ZCheckSum THEN _
         ZNAK$ = CHR$(21) : _
         SOL = 132 _
      ELSE ZNAK$ = "C" : _
           SOL = 133
20330 'IF ZAutoDownInProgress THEN _
      '   RETURN
      ZOutTxt$ = ZProtoPrompt$ + _
            " " + WasA1$ + _
            " of " + _
            ZFileNameHold$ + _
            " ready.  <Ctrl X> aborts"
      GOSUB 21650
      'IF WasA1$ = "SEND" THEN _
      '   CALL Talk (8,ZOutTxt$) _
      'ELSE CALL Talk (9,ZOutTxt$)
      RETURN
'
' *  ASCII DOWNLOAD DRIVER
'
20340 IF ZWasDF THEN _
         ZOutTxt$ = "Switch to a non-ascii protocol" : _
         GOSUB 21650 : _
         GOTO 21700
      GOSUB 20750
      IF ZFileSysParm > 1 OR NOT ZOK THEN _
         RETURN
      CALL OpenWork (2,ZFileName$)
      IF (ZAnsIndex = FirstDnld OR NOT ZConcatFIles) THEN _
         ZOutTxt$ = "^X aborts.  ^S suspends ^Q resumes" : _
         GOSUB 21640 : _
         IF ZFileSysParm > 1 THEN _
            RETURN _
         ELSE ZOutTxt$ = ZProtoPrompt$ + " SEND of " + _
              ZFileNameHold$ + _
              " ready. Press Any Key to start" : _
         ZTurboKey = 2 : _
         ZForceKeyboard = ZTrue : _
         ZSuspendAutologoff = ZTrue : _
         GOSUB 21660 : _
         ZSuspendAutologoff = ZFalse : _
         IF ZFileSysParm > 1 THEN _
            RETURN
20380 ZStopInterrupts = ZFalse
      WasTU = 0
      SWAP WasTU,ZPageLength
      CALL BufFile (ZFileName$,WasX)
      SWAP WasTU,ZPageLength
      ZNonStop = (ZPageLength < 1)
      IF StopFile THEN _
         ZDnldCompleted = ZFalse : _  'Pe 02/05/90
         GOTO 20390
20381 IF (ZAnsIndex = LastDnld OR NOT ZConcatFIles) THEN _
         CALL QuickTPut (CHR$(26),0) : _
         IF NOT ZLocalUser AND ZSubParm = 0 THEN _
            FOR WasX = 1 TO 5 : _
               CALL PutCom (CHR$(7)) : _
               CALL DelayTime (3) : _
            NEXT
20385 ZDnldCompleted = ZTrue   'Pe 02/05/90
20390 GOTO 21760
'
' *  U - COMMAND FROM FILES MENU (UPLOAD)
'
20395 GOSUB 21640
      IF ZFileSysParm > 1 THEN _
         RETURN
      ZOutTxt$ = "Correct name of file to upload" + _
           ZPressEnterExpert$
      GOSUB 21660
      IF ZFileSysParm > 1 THEN _
         RETURN
      IF ZWasQ = 0 THEN _
         RETURN
      ZUserIn$(ZAnsIndex) = ZUserIn$(1)
      GOTO 20435
20400 CALL TimeBack (1)
      GOSUB 20420
      ZAutoLogOffReq = 0
      FirstUpld = ZAnsIndex
      GOTO 20430
20420 ZOutTxt$ = "Upload what file(s)"
      ZStackC = ZTrue
      GOSUB 21668
      RETURN
'
' *  SEARCH FOR DUPLICATE FILENAME
'
20430 ZAnsIndex = ZLastIndex
      GOSUB 20470
      ZLastIndex = ZLastIndex + (WasX > 0)
      FOR ZAnsIndex = FirstUpld TO ZLastIndex
         GOSUB 20470
         GOSUB 20435
         IF ZFileSysParm > 1 THEN _
            ZAnsIndex = ZLastIndex + 1
      NEXT
      ZCmdTransfer$ = ""
      RETURN
20435 ZFileNameHold$ = ZUserIn$(ZAnsIndex)
      IF INSTR(ZFileNameHold$,".") = 0 THEN _
         ZFileNameHold$ = ZFileNameHold$ + "." + ZDefaultExtension$
      CALL AllCaps(ZFileNameHold$)
      ZFileName$ = ZFileNameHold$
      ZViolation$ = "Upload "
      CALL NoPath (ZFileName$,BadFileNameIndex)
      IF BadFileNameIndex THEN _
         GOTO 20451
      CALL BadFile (ZFileName$,BadFileNameIndex)
      ON BadFileNameIndex GOTO 20440,20451,20515
20440 TmpName$ ="NOTHANX.DEF"                                       'PE mode to
      CALL FindIt (TmpName$)                                        'DGS-UNW
      IF ZOK THEN
       CALL QuickTPut ("Checking off line file list....",1)
CALL OpenWork (2,TmpName$)
    HaveFile$ = ""
     FileInList = ZFalse
      WHILE NOT EOF(2) AND NOT FileInList
	    INPUT #2, HaveFile$
	    CALL AllCaps (HaveFile$)
	    FileInList = (INSTR(ZFileNameHold$,HaveFile$) > 0)
	 WEND
	 CLOSE 2
      END IF
      IF FileInList THEN _
      CALL BufFile ("NOTHANX.MSG",WasX) : _
      CALL DelayTime (3) : _
	 GOTO 20453
      CALL Carrier
      IF ZSubParm = -1 THEN _
         ZFileSysParm = 7 : _
      RETURN
     CALL RotorsDir (ZFileName$,ZSubDir$(),ZSubDirCount,ZTrue,"U")
20445 IF ZOK THEN _
         GOTO 20452
      IF INSTR(ZFileName$,".") = 0 THEN _
         GOTO 20475
      CALL BreakFileName (ZFileName$,DR$,WasX$,Extension$,ZFalse)
      WasI = 1
20447 WasJ = INSTR(MID$(ZCompressedExt$+". ",WasI),".")
      IF WasJ = 0 THEN _
         GOTO 20475
      Check$ = MID$(ZCompressedExt$,WasI,WasJ-1)
      WasI = WasI + WasJ
20450 IF Extension$ <> Check$ THEN _
   CALL RotorsDir (WasX$ + "." + Check$,ZSubDir$(),ZSubDirCount,ZTrue,"U") : _
         IF ZOK THEN _
            GOTO 20452
      GOTO 20447
20451 ZOutTxt$ ="Invalid file name. File name cannot contain a Drive letter"+ _ 'Pe 02/04/90
       ZCrLf$ + "Subdirectory name, a Space, or any WildCard Characters "
      GOSUB 21655
      CALL DelayTime (2)
      ZFileSysParm = 3
      RETURN              'Pe 02/04/90
20452 IF ZUserSecLevel < ZOverWriteSecLevel THEN _
         GOTO 20453
      ZOutTxt$ = "Overwrite file (Y,[N])"
      GOSUB 21660
      IF ZFileSysParm > 1 THEN _
         RETURN
      IF NOT ZYes THEN _
         GOTO 20453
      ZWasZ$ = ZFileName$
      CALL KillWork (ZFileName$)
      IF ZErrCode <> 0 THEN _
         ZWasEL = 20452 : _
         GOTO 21900
      GOTO 20475
20453 CLOSE 2
      IF ZUserSecLevel >= ZAddDirSecurity THEN _
         GOTO 20455
20454 CALL QuickTPut1 ("Thanks, but we already have " + ZFileNameHold$)
      CALL UpdtCalr ("Upload duplicate " + ZFileNameHold$,2)
      RETURN
20455 ZOutTxt$ = "Add new directory entry (Y,[N])"
      ZTurboKey = - ZTurboKeyUser
      GOSUB 21660
      IF ZFileSysParm > 1 THEN _
         RETURN
      IF NOT ZYes THEN _
         RETURN
      AddingDescOnly = ZTrue
      ZWasFT$ = "l"
CALL UpdtUpload (ZCategoryName$(),ZCategoryCode$(),ZLinesInMsg,1) 'UPL-MOD
      GOSUB 20702
      RETURN
20470 ' *** CHECK FOR Protocol IN FILE LIST ***
      ZWasZ$ = ZUserIn$(ZAnsIndex)
      CALL AllCaps(ZWasZ$)
      WasX = 0
      IF LEN (ZWasZ$) = 1 THEN _
         WasX = INSTR(ZDefaultXfer$,ZWasZ$) : _
         IF WasX > 0 THEN _
            ZAnsIndex = ZAnsIndex + 1 : _
            ZCmdTransfer$ = ZWasZ$ : _
            ZAutoDownInProgress = ZFalse : _
            IF MID$(ZInternalEquiv$,WasX,1) = "N" THEN _
               ZCmdTransfer$ = ""
      RETURN
20475 ZWasZ$ = ZUpldDriveFile$
      CALL FindFree
      IF VAL(ZFreeSpace$) < 4096 THEN _
         CALL QuickTPut1 ("No room for uploads.  Try tomorrow.") : _
         ZAnsIndex = ZLastIndex + 1 : _
         RETURN
      ZOutTxt$ = "Upload disk has" + _
           ZFreeSpace$
      GOSUB 21640
      IF ZFileSysParm > 1 THEN _
         RETURN
'*****************
CALL UpdtUpload (ZCategoryName$(),ZCategoryCode$(),ZLinesInMsg,1)  '<++++++
'*****************
IF ZAbort THEN _     'PE 12/14/88
ZAbort = ZFalse : _   'PE 12/14/88
 RETURN
      ZLine25$ = "(U) " + _
                 ZFileNameHold$
      ZSubParm = 2
      CALL Line25
      ZOutTxt$ = ""
      ZOK = ZTrue
20477 CALL XferType (2,ZTrue)
      IF ZFF THEN _
         GOTO 20500
      CALL XferType (1,ZTrue)
      IF ZSubParm = -1 THEN _
         ZFileSysParm = 7 : _
         RETURN
20500 CALL AutoLogOff            'Pe 02/04/90
      ZTransferFunction = 2
      ZAutoDownInProgress = ZFalse
      GOSUB 21790
      IF ZFileSysParm > 1 THEN _
         RETURN
      ON INSTR("AXCYN",ZInternalProt$) GOTO _
         20560, _         ' ASCII UPLOAD
         20542, _         ' Xmodem
         20542, _         ' Xmodem CRC
         20542, _         ' YMODEM
         20735            ' NONE - CANCEL
      GOTO 20261
20510 WasD$ = "<Esc> by SYSOP aborts"
      GOSUB 21710
      RETURN
20515 CALL SecViolation
      IF ZDenyAccess THEN _
         ZFileSysParm = 4 : _
         RETURN
      GOTO 20420
'
' *  Xmodem/YMODEM UPLOAD DRIVER
'
20542 WasA1$ = "RECEIVE"
      GOSUB 20320
      IF ZFileSysParm > 1 THEN _
         RETURN
      ZOK = ZTrue
      GOSUB 20860
      IF ZFileSysParm > 1 THEN _
         RETURN
      IF ZOK THEN _
         GOTO 20700
      GOTO 20730
'
' *  ASCII UPLOAD
'
20560 LineACK = (ZDefaultLineACK$ <> "")
      IF LineACK THEN _
         ZOutTxt$ = "Acknowledge each line ([Y],N)" : _
         ZTurboKey = - ZTurboKeyUser : _
         LineACK = NOT ZNo : _
         GOSUB 21660 : _
         IF ZFileSysParm > 1 THEN _
            RETURN
      CALL QuickTPut1 ("Transfer MUST end with a <Ctrl-K>")
      CALL QuickTPut1 (ZProtoPrompt$+" RECEIVE of " + ZFileNameHold$ + " ready")
      ZOK = ZFalse
      XOff = ZFalse
      CALL OpenOutW(ZFileName$)
      IF ZErrCode <> 0 AND ZErrCode <> 53 THEN _
         ZWasEL = 20560 : _
         GOTO 21900
      GOSUB 20510
      IF ZFileSysParm > 1 THEN _
         RETURN
20600 CALL EofComm (Char)
      WHILE Char <> -1
         CALL Carrier
         IF ZSubParm = -1 THEN _
            ZFileSysParm = 7 : _
            RETURN
         IF NOT ZFossil THEN _
            IF LOF(3) < 512 THEN _
               CALL PutCom(ZXOff$) : _
               XOff = ZTrue
20610    CALL FlushCom (WasX$)
         IF ZSubParm = -1 THEN _
            ZFileSysParm = 7 : _
            RETURN
         IF INSTR(WasX$,CHR$(11)) THEN _
            GOTO 20650
         ZOK = ZTrue
20620    CALL PrintWork (WasX$)
         IF LineACK THEN _
            IF INSTR(WasX$,CHR$(10)) > 0 THEN _
               CALL PutCom (ZDefaultLineACK$)
         IF ZErrCode <> 0 THEN _
            ZWasEL = 20620 : _
            GOTO 21900
         WasD$ = WasX$
         NumReturns = 0
         GOSUB 21720
         IF ZFileSysParm > 1 THEN _
            RETURN
20621    CALL FindFKey
         IF ZSubParm < 0 THEN _
            ZFileSysParm = 2 : _
            RETURN
         IF ZKeyPressed$ = ZEscape$ THEN _
            GOTO 20745
         IF NOT ZOK THEN _
            GOTO 20670
      CALL EofComm (Char)
20630 WEND
      CALL Carrier
      IF ZSubParm = -1 THEN _
         ZFileSysParm = 7 : _
         RETURN
      IF XOff THEN _
         XOff = ZFalse : _
         CALL PutCom (ZXOn$) : _
         IF ZErrCode <> 0 THEN _
            ZWasEL = 20630 : _
            GOTO 21900
      GOTO 20600
20650 WasX = INSTR(WasX$,CHR$(11))
      IF WasX = 1 THEN _
         IF NOT ZOK THEN _
            GOTO 20730 _
         ELSE GOTO 20700
      CALL PrintWorkA (LEFT$(WasX$,WasX-1))
      IF ZErrCode <> 0 THEN _
         ZWasEL = 20650 : _
         GOTO 21900
      GOTO 20700
20670 ZOutTxt$ = ZXOff$ + _
           "System error! Upload aborted <Ctrl-K> continues"
20675 GOSUB 21650
      IF ZFileSysParm > 1 THEN _
         RETURN
      CALL DelayTime (3)
      CALL PutCom(ZXOn$)
20680 CALL EofComm (Char)
      WHILE Char <> -1
         CALL FlushCom(WasX$)
         IF INSTR(WasX$,CHR$(11)) THEN _
            GOTO 20730
20685    CALL Carrier
         IF ZSubParm = -1 THEN _
            ZFileSysParm = 7 : _
            RETURN
      CALL EofComm (Char)
      WEND
      GOTO 20680
'
' *  UPDATE UPLOAD DIRECTORY
'
20700 GOSUB 21780
      IF ZFileSysParm > 1 THEN _
         RETURN
20702 CALL UpdtUpload (ZCategoryName$(),ZCategoryCode$(), ZLinesInMsg,2) 'Pe 02/03/90
      IF ZAutoEnd = 1 THEN _                   'AUTO-UP MOD to next comment
      CALL BreakFileName (ZFileName$,DR$,WasX$,Extension$,ZTrue): _
      WasZ$ = WasX$+Extension$+ZWasDF$+" at "+ZTime$ + _
             " using " + ZWasFT$ + STR$(ZBytesInFile#) :_
      CALL UpdtCalr (WasZ$,2) : _
      RETURN                             'AUTO-UP MOD
'***** end of Auto Up Mod****
      ZPrivateDoor = ZFalse
      IF NOT ZGetExtDesc THEN _
         GOTO 20710
      ZMsgHeader$ = "Extra Information for " + ZFileNameHold$     ' KG072003   ' Bh
      ZSysopComment = ZTrue
      ZMaxMsgLines = ZMaxExtendedLines
      WasLL = ZRightMargin
'      ZRightMargin = 30 + ZMaxDescLen
      ZRightMargin = 24 + ZMaxDescLen          ' Bh 082790
      ZFileSysParm = 5
      RETURN
20705 ZMaxMsgLines = ZMaxMsgLinesDef
      ZRightMargin = WasLL
      CALL UpdtUpload (ZCategoryName$(),ZCategoryCode$(),ZLinesInMsg,3)  'Pe 02/04/90
20710 AddingDescOnly = ZFalse
      IF ZBytesInFile# > 0.0 THEN _
         GOTO 21770
20730 GOSUB 21780
      CALL QuickTPut1 ("Upload aborted")
      ZPrivateDoor = ZFalse
20735 CALL KillWork (ZFileName$)
      IF ZErrCode <>0 THEN _
         ZWasEL = 20736 : _
         GOTO 21900
      ZAnsIndex = ZLastIndex + 1                                     ' KG031501
      ZLastIndex = 0
      RETURN
'
' *  Sysop ABORTED UPLOAD
'
20745 ZOutTxt$ = ZXOff$ + _
           "SYSOP aborted upload. Stop tranfer. <Ctrl-K> continues"
      GOTO 20675
'
' *  CALCULATE DOWNLOAD TIME ESTIMATE
'
20750 ZStartOfHeader$ = CHR$(1 - (ZInternalProt$ = "Y"))
      CALL OpenRSeq (ZFileName$,MaxBlock,ZWasDF,ZFLen)
20760 IF ZErrCode <> 0 THEN _
         CALL QuickTPut1 ("Unable to access "+ZFileNameHold$) : _
         CALL UpdtCalr ("Unable to access "+ZFileName$,2) : _
         ZOK = ZFalse : _
         ZErrCode = 0 : _
         ZBytesInFile# = 0 : _
         RETURN
      ZBytesInFile# = LOF(2)
      ZNumDnldBytes! = LOF(2)
      ZOK = ZTrue
      IF SizeOnly THEN _
         SizeOnly = ZFalse : _
         RETURN
      ZBlocksInFile# = MaxBlock
      IF ZBatchTransfer THEN _
         Temp# = BatchBlocks# + ZBlocksInFile# : _
         CALL CheckTimeRemain (MinsRemaining) : _
         IF (NOT PersonalDnld) AND _
            (INT(Temp# / 60) + 1 > MinsRemaining) THEN _
            CALL QuickTPut1 ("Omitting " + ZFileNameHold$ + ".  Insufficient time") : _
            RETURN _
         ELSE BatchBlocks# = Temp# : _
              BatchBytes# = BatchBytes# + ZBytesInFile# : _
              CALL OpenWorkA (ZNodeWorkFile$) : _
              CALL PrintWorkA (ZFileName$) : _
              ZDownFiles = ZDownFiles + 1 : _
              RETURN
      ZDownFiles = 1
20780 ZOutTxt$ = "File Size    :"
      ZOK = ZTrue
      IF ZBlockSize > 0 THEN _
         ZOutTxt$ = ZOutTxt$ + _
              STR$(FIX(ZBlocksInFile#)) + _
              " blocks "
20785 ZBlocksInFile# = ZBlocksInFile# / _
                        VAL(MID$("00000300045012002400480096019203840", -4 * ZBPS, 4))
      ZBlocksInFile# = ZBlocksInFile# * ZFLen / ZSpeedFactor!
      IF (ZAnsIndex > 1 AND ZConcatFIles) THEN _
         RETURN
      ZOutTxt$ = ZOutTxt$ + _
           STR$(ZBytesInFile#) + _
           " bytes"
      GOSUB 21650
      IF ZFileSysParm > 1 THEN _
         RETURN
      IF ZBytesInFile# < 1 THEN _
         RETURN
20790 ZSubParm = 2
      CALL Line25
      ZOutTxt$ = "Transfer Time:" + _
         STR$(INT(ZBlocksInFile# / 60)) + _
         " min," + _
         STR$(INT(ZBlocksInFile# - (INT(ZBlocksInFile# / 60) * 60))) + _
         " sec (approx)"
      GOSUB 21650
      IF ZFileSysParm > 1 THEN _
         RETURN
20791 IF PersonalDnld THEN _
      Call AutoLogOff : _         'Pe 02/06/90
         RETURN
      CALL CheckTimeRemain (MinsRemaining)
      IF ZSubParm = -1 THEN _
         ZFileSysParm = 6 : _
         RETURN
      ZOK = ZTrue
      IF (INT(ZBlocksInFile# / 60) + 1) > MinsRemaining THEN _
         ZOutTxt$ = "Not enough time left!" : _
         CALL UpdtCalr (ZFileName$ + " " + ZOutTxt$,2) : _
         CALL QuickTPut1 (ZOutTxt$): _
         ZOutTxt$ = "" : _
         ZOK = ZFalse : _
         ZAutoLogoffReq = ZFalse : _
         RETURN
'****************************** TELL THEM mod *****************************  ' Bh
'
     ZNotify$ =  ZWelcomeFileDrvPath$ + _
         "TELTHEM.DEF"                              'Pe 06/12/89
    ZStopInterrupts = ZTrue                         'Pe 06/12/89
    CALL BUFFILE (ZNotify$,WasX)                    'Pe 06/12/89
'
'**********************  END OF MOD  **************************************  ' Bh
      CALL AutoLogoff         'Pe 02/16/90
      CALL QuickTPut1 ("New statistics will be")
      CALL CheckRatio (ZTrue)
      RETURN
20810 ZDelay! = TIMER + 6
20840 CALL EofComm (Char)
      IF Char = -1 THEN _
         GOTO 20850
      CALL FlushCom(ZWasY$)
      RETURN
20850 CALL CheckTime (ZDelay!, TempElapsed!, 1)
      IF TempElapsed! > 0 THEN GOTO 20840
20851 ZWasY$ = ""
      CALL CheckCarrier
      IF ZSubParm = -1 THEN _
         ZFileSysParm = 7 : _
         RETURN
      RETURN
'
' *  Xmodem/YMODEM UPLOAD
'
20860 GOSUB 20992
      IF ZFileSysParm > 1 THEN _
         RETURN
      IF NOT ZEightBit THEN _
         GOSUB 21280 : _
         IF ZFileSysParm > 1 THEN _
            RETURN
20900 WasX$ = ""
      Sec = 1
      'CALL OpenOutW (ZFileName$)
      IF ZFLen > ZWriteBufDef THEN _
         WriteBuf = ZFLen _
      ELSE WriteBuf = ZWriteBufDef
      CALL OpenRSeq (ZFileName$,WasY,ZWasDF,WriteBuf)
      IF ZErrCode <> 0 AND ZErrCode <> 53 THEN _
         ZWasEL = 20900 : _
         GOTO 21900
      FIELD #2, WriteBuf AS ZUpldRec$
      RecsWrit = 0
      NumInBuff = 0
      TransferAbort! = TIMER + ZWaitBeforeDisconnect
      Year$ = " " + _
            CHR$(1) + _
            CHR$(2) + _
            ZEndTransmission$ + _
            ZCancel$
20903 CALL PutCom (ZNAK$)
20920 WasX = 1
20922 CALL CheckCarrier
      IF ZSubParm = -1 THEN _
         ZFileSysParm = 7 : _
         RETURN
      CALL FindFKey
      IF ZKeyPressed$ = ZEscape$ THEN _
         GOSUB 20510 :_
         IF ZFileSysParm > 1 THEN _
            RETURN _
         ELSE GOTO 21240
      GOSUB 20810
      IF ZFileSysParm > 1 THEN _
         RETURN
20930 WasJ = INSTR(Year$,LEFT$(ZWasY$,1))
      ON WasJ GOTO 20960,20999,20999,21220,21230
20960 IF ZWasY$ <> "" THEN _
         GOSUB 21280 : _
         IF ZFileSysParm > 1 THEN _
            RETURN _
         ELSE CALL CheckTime (TransferAbort!,TempElapsed!,1) : _
              ON ZSubParm GOTO 20920,21230
20970 WasX = WasX + 1
      CALL DelayTime (1)
      CALL PutCom (ZNAK$)
      IF WasX < 6 THEN _
         GOTO 20922
      WasD$ = "Upload Timeout"
      GOSUB 21710
      IF ZFileSysParm > 1 THEN _
         RETURN
      CALL CheckTime (TransferAbort!,TempElapsed!,1)
      ON ZSubParm GOTO 20990,21230
20990 GOTO 20920
'
' *  CHANGE TO 8 BIT FOR Xmodem
'
20992 GOSUB 20510
      IF ZFileSysParm > 1 THEN _
         ZFileSysParm = 2 : _
         RETURN
      IF NOT ZEightBit THEN _
         PrevLineCntl = INP (ZLineCntlReg) : _
         CALL DelayTime (3) : _
         SwitchToEight = ZTrue : _
         OUT ZLineCntlReg,3
20996 WasSO = 0
      RETURN
'
' *  EXPECTED BLOCK LENGTH. 132 FOR CheckSum, 133 FOR CRC, 1029 FOR YMODEM
'
20999 SOL = 896 * WasJ - 1659 + ZCheckSum
      DataSol = 128 - (SOL > 1024)*896
      GOTO 21020
'
' *  Xmodem/YMODEM UPLOAD
'
21000 GOSUB 20810
      IF ZFileSysParm > 1 THEN _
         RETURN
      IF ZWasY$ = "" THEN _
         WasD$ = "Upload Timeout" : _
         GOSUB 21710 : _
         IF ZFileSysParm > 1 THEN _
            RETURN _
         ELSE GOTO 21040
21020 WasX$ = WasX$ + _
           ZWasY$
      IF LEN(WasX$) < SOL THEN _
         GOTO 21000
21040 IF LEN(WasX$) = SOL THEN _
         GOTO 21090
21050 IF LEN(WasX$) > SOL THEN _
         GOTO 21180
21060 IF WasX$ = ZEndTransmission$ THEN _
         GOTO 21220
21070 IF WasX$ = ZCancel$ THEN _
         GOTO 21230
21080 GOTO 21170
21090 WasJX = ASC(MID$(WasX$,2,1))
      IF Sec = WasJX THEN _
         GOTO 21100
      GOTO 21200
21100 IF (Sec XOR 255) <> ASC(MID$(WasX$,3,1)) THEN _
         GOTO 21210
21110 IF ZCheckSum THEN _
         WasWK$ = MID$(WasX$,4,128) : _
         GOSUB 21750 : _
         IF ZFileSysParm > 1 THEN _
            RETURN _
         ELSE IF XmodemChecksum <> ASC(MID$(WasX$,132,1)) THEN _
            GOTO 21190 _
         ELSE GOTO 21120
      WasWK$ = MID$(WasX$,4)
      GOSUB 21750
      IF ZFileSysParm > 1 THEN _
         RETURN
21113 IF CRCValue <> 0 THEN _
         GOTO 21191
21120 WasSO = WasSO + 1
      CALL PutCom (ZAcknowledge$)
21131 IF NumInBuff >= WriteBuf THEN _
         NumInBuff = 0 : _
         CALL PutWork (ZUpldRec$,RecsWrit,WriteBuf) : _
         IF ZErrCode <> 0 THEN _
            ZWasEL = 21131 : _
            GOTO 21900
      MID$(ZUpldRec$,NumInBuff+1,DataSol) = WasWK$
      NumInBuff = NumInBuff + DataSol
21145 Sec = 255 AND (Sec + 1)
      CALL QuickLPrnt ("OK Rec Blk #",WasSO)
21150 WasX$ = ""
      XmodemChecksum = 0
      TransferAbort! = TIMER + 45
      GOTO 20920
21170 ZOutTxt$ = "Short Blk #"
      GOTO 21212
21180 ZOutTxt$ = "Long Blk #"
      GOTO 21212
21190 ZOutTxt$ = "Chksum Error #"
      GOTO 21212
21191 ZOutTxt$ = "CRC Error"
      GOTO 21212
21200 IF Sec < WasJX THEN _ 
         ZOutTxt$ = "Blk # Error in #" : _
         GOTO 21212
      CALL PutCom (RIGHT$(ZAckChar$,1 - (WasJX = 0)))
      GOTO 21150
21210 ZOutTxt$ = "Complement Error in #"
21212 CALL PutCom (ZNAK$)
      CALL LPrnt(ZLineFeed$ + ZOutTxt$ + STR$(WasSO + 1),0)
      GOTO 21150
21220 IF NumInBuff < 1 THEN _
         GOTO 21225
      WasWK$ = LEFT$(ZUpldRec$,NumInBuff)
      CALL OpenRSeq (ZFileName$,MaxBlock,ZWasDF,128)
      FIELD #2, 128 AS ZUpldRec$
      MaxBlock = CDBL(RecsWrit) * WriteBuf / 128
      FOR WasI = 1 TO NumInBuff/128
         CALL PutWork (MID$(WasWK$,128*WasI-127,128),MaxBlock,128)
         IF ZErrCode > 0 THEN _
            ZWasEL = 21220 : _
            GOTO 21900
      NEXT
      CLOSE 2
21225 CALL PutCom (ZAcknowledge$)
      GOTO 21250
21230 WasD$ = ZLineFeed$ + _
           "Transfer Aborted"
      GOSUB 21710
      IF ZFileSysParm > 1 THEN _
         RETURN
21240 CALL EofComm (Char)
      IF Char <> -1 THEN _
         GOSUB 21280 : _
         IF ZFileSysParm > 1 THEN _
            RETURN _
         ELSE CALL DelayTime (1) : _
         GOTO 21240
      CALL PutCom (ZCancel$ + ZCancel$)
      CALL DelayTime (1)
      CALL EofComm (Char)
      IF Char <> -1 THEN _
         GOTO 21240
      ZOK = ZFalse
21250 ZEightBit = ZTrue
      RETURN
'
' *  CLEAR GARBAGE OUT OF COMMUNICATIONS BUFFER
'
21280 CALL CheckCarrier
      IF ZSubParm = -1 THEN _
         ZFileSysParm = 7 : _
         RETURN
      CALL EofComm (Char)
      IF Char = -1 THEN _
         RETURN
21281 CALL FlushCom(ZWasDF$)
      GOTO 21280
'
' *  Xmodem/YMODEM DOWNLOAD
'
21300 GOSUB 20992
      IF ZFileSysParm > 1 THEN _
         RETURN
      Sec = 0
      GOSUB 21280
      IF ZFileSysParm > 1 THEN _
         RETURN
      ZNAK$ = CHR$(21)
      TransferAbort! = TIMER + ZWaitBeforeDisconnect
   CALL OpenRSeq (ZFileName$,MaxBlock,ZWasDF,ZFLen)  'Pe 08/15/89
21303 FIELD 2,ZFLen AS ZDnldRecord$
'
' *  ROUTINE TO START AN "Xmodem" OR "YMODEM" DOWNLOAD.  CHECK'S INITIAL
' *  "HANDSHAKE" TO SEE IF CHARACTER IS SENT IS A:
' *           "X" = Xmodem WITH CheckSum AND 128 CHARACTER RECORDS
' *           "C" = Xmodem WITH CRC CHECK AND 128 CHARACTER RECORDS
' *           "Y" = YMODEM WITH CRC CHECK AND 1024 CHARACTER RECORDS
'
21350 CALL EofComm (Char)
      WHILE Char <> -1
21360    CALL GetCom(ZWasY$)
         IF ZWasY$ = ZCancel$ THEN _
            GOTO 21560
21380    ZCheckSum = (ZWasY$ = ZNAK$)
         IF ZCheckSum THEN _
            ZFF = INSTR(ZInternalEquiv$,"X") : _
            IF ZFF > 0 THEN _
               ZWasFT$ = MID$(ZDefaultXfer$,ZFF,1) : _
               GOTO 21480 _
            ELSE ZWasFT$ = "X" : _
                 GOTO 21480 _
         ELSE IF ZWasY$ = "C" THEN _
                 GOTO 21480
         CALL EofComm (Char)
21390 WEND
      GOSUB 21460
      IF ZFileSysParm > 1 THEN _
         RETURN
      IF ZKeyPressed$ = ZEscape$ THEN _
         RETURN
      CALL CheckTime (TransferAbort!, TempElapsed!, 1)
      ON ZSubParm GOTO 21350,21455
21410 TransferAbort! = TIMER + ZWaitBeforeDisconnect
'
' *  ROUTINE TO WAIT FOR AN ACKNOWLEDGEMENT ON AN "Xmodem" OR "YMODEM"
' *  DOWNLOAD
'
21415 CALL EofComm (Char)
      IF Char <> -1 THEN _
         GOTO 21420
      GOSUB 21460
      IF ZFileSysParm > 1 THEN _
         RETURN
      IF ZKeyPressed$ = ZEscape$ THEN _
         RETURN
      CALL CheckTime (TransferAbort!, TempElapsed!, 1)
      ON ZSubParm GOTO 21415,21455
21420 CALL GetCom(ZWasY$)
      IF ZWasY$ = ZAcknowledge$ THEN _
         GOTO 21470
21440 IF ZWasY$ <> ZNAK$ THEN _
         GOTO 21450
21443 WasD$ = ZLineFeed$ + _
         "Error -> retrans #" + _
         STR$(WasSO)
      GOSUB 21710
      IF ZFileSysParm > 1 THEN _
         RETURN
21445 WasSO = WasSO - 1
      GOTO 21490
21450 IF ZWasY$ = ZCancel$ THEN _
         IF HaveACancel THEN _
            GOTO 21560 _
         ELSE HaveACancel = ZTrue
      CALL CheckTime (TransferAbort!, TempElapsed!, 1)
      ON ZSubParm GOTO 21415,21455
21455 WasD$ = "Download timeout"
      GOSUB 21710
      IF ZFileSysParm > 1 THEN _
         RETURN
      GOTO 21560
21460 CALL CheckCarrier
      CALL FindFKey
      IF ZSubParm < 0 THEN _
         ZFileSysParm = 7 : _
         RETURN
      IF ZKeyPressed$ = ZEscape$ THEN _
         GOTO 21540
      RETURN
'
' *  DISPLAY BLOCK SENT OK AND THEN READ IN NEXT RECORD FROM DISK TO DOWNLOAD
'
21470 CALL QuickLPrnt ("OK Sent Blk #",WasSO)
21480 IF LOC(2) => MaxBlock THEN _
         GOTO 21530
      CALL GetWork (ZFLen)
      IF ZErrCode <> 0 THEN _
         ZWasEL = 21480 : _
         GOTO 21900
      Sec = 255 AND (Sec + 1)
      GOTO 21490
'
' *  ROUTINE TO WRITE OUT AN "Xmodem" OR "YMODEM" RECORD TO THE COMM. PORT
'
21490 WasSO = WasSO + 1
      CALL PutCom (ZStartOfHeader$ + CHR$(Sec) + CHR$(Sec XOR 255))
      CALL PutCom (ZDnldRecord$)
      HaveACancel = ZFalse
21503 WasWK$ = ZDnldRecord$
21504 GOSUB 21750
      IF ZFileSysParm > 1 THEN _
         RETURN
21510 IF ZCheckSum THEN _
         CALL PutCom(CHR$(XmodemChecksum)) _
      ELSE CALL PutCom(CHR$(CRCHigh) + CHR$(CRCLow))
      GOSUB 21280
      IF ZFileSysParm > 1 THEN _
         RETURN
      GOTO 21410
'
' *  END-OF-FILE FOR Xmodem Dnlds -- SEND THE "EOT" CHARACTER AND WAIT UP
' *  TO 2 SECONDS FOR A POSITIVE RESPONSE (I.E. AN "ACK").  IF NONE IS
' *  RE-TRY UP TO 10 TIMES.  IF No POSITIVE RESPONSE IS RECEIVED AFTER TEN
' *  Attempts, ASSUME THE DOWNLOAD WAS UNSUCCESSFULL.
'
21530 CALL PutCom (ZEndTransmission$)
      WasX = 1
21531 GOSUB 20810
      IF ZFileSysParm > 1 THEN _
         RETURN
      IF INSTR(ZWasY$,ZAcknowledge$) THEN _
         GOTO 21550
      CALL FindFKey
      IF ZSubParm < 0 THEN _
         ZFileSysParm = 2 : _
         RETURN
      IF ZKeyPressed$ = ZEscape$ THEN _
         GOSUB 21540 : _
         GOTO 21545
      IF WasX < 10 THEN _
         WasX = WasX + 1 : _
         GOTO 21531
      ZDnldCompleted = ZFalse  'Pe 02/05/90
      GOTO 21230
21540 GOSUB 20510
      IF ZFileSysParm > 1 THEN _
         RETURN
      RETURN
21545 ZWasY$ = ZCancel$
      CALL PutCom (ZCancel$ + ZCancel$ + ZCancel$)
      ZDnldCompleted = ZFalse 'Pe 02/05/90
      GOTO 21250              'Pe 02/05/90
21550 ZDnldCompleted = ZTrue
      GOTO 21250
21560 ZDnldCompleted = ZFalse   'Pe 02/05/90
      WasD$ = ZLineFeed$ + _
           "Caller aborted trans"
      GOSUB 21710
      IF ZFileSysParm > 1 THEN _
         RETURN
      GOTO 21545
'
' STANDARD ENTRY FOR RBBS-PC'S COMMON TERMINAL OUTPUT ROUTINE
'
' Modeled on lines 12975 to 12983 in RBBS-PC.BAS
21630 ZSubParm = 1
      GOTO 21655
21640 ZSubParm = 3
      GOTO 21655
21650 ZSubParm = 5
21655 CALL TPut
      IF ZSubParm < 0 THEN _
         ZFileSysParm = 2 : _
         RETURN
      IF ZSubParm = 8 THEN _
         GOSUB 21660
      RETURN
'
' STANDARD ENTRY FOR RBBS-PC'S COMMON TERMINAL INPUT ROUTINE
'
' Modeled on lines 12995 to 12997 in RBBS-PC.BAS
21660 ZSubParm = 1
      CALL TGet
21665 IF ZSubParm < 0 THEN _
         ZFileSysParm = 2
      RETURN
21668 CALL PopCmdStack
      GOTO 21665
21700 ZErrCode = 0
      ZLastIndex = 0
      RETURN
'
' **** COMMON LOCAL DISPLAY PRINT ***
'
'  (formerly lines 1315 to 1320 in RBBS-PC.BAS
21710 NumReturns = 1
21720 CALL LPrnt (WasD$,NumReturns)
      RETURN
'
' *  Xmodem / CRC INTERFACE
'
'  (formerly line 46000 in RBBS-PC.BAS
21750 XmodemChecksum = 0
      CRCValue = 0
      CALL Xmodem(WasWK$,XmodemChecksum,CRCValue,CRCHigh,CRCLow)
      RETURN
'
' * UPDATE DOWNLOAD STATISTICS
'
'  (formerly lines 50600 to 50614 in RBBS-PC.BAS
21760 GOSUB 21780
      IF ZFileSysParm > 1 THEN _
         RETURN
      IF ZBatchTransfer THEN _
         CALL LinesInFile (ZNodeWorkFile$,ZDownFiles) _
      ELSE ZDownFiles = 1
      IF NOT ZDnldCompleted THEN _    'Pe 02/05/90
         ZAutoLogoffReq = ZFalse : _
         ZWasDF$ = " Aborted" : _
         GOTO 21768
      CALL LogPDown (PersonalDnld,1+ZAnsIndex-FirstDnld)
         GOSUB 21778
         ZDnlds = ZDnlds + ZDownFiles
         ZGlobalDLToday! = ZGlobalDLToday! + ZDownFiles
         ZGlobalDnlds = ZGlobalDnlds + ZDownFiles
         ZDLBytes! = ZDLBytes! + ZNumDnldBytes! 
         ZGlobalDLBytes! = ZGlobalDLBytes! + ZNumDnldBytes! 
         ZDLToday! = ZDLToday! + ZDownFiles
         ZBytesToday! = ZBytesToday! + ZNumDnldBytes! 
         ZGlobalBytesToday! = ZGlobalBytesToday! + ZNumDnldBytes!
      ZNumDnldBytes! = 0
'      CALL Muzak (6)
      ZWasDF$ = " Downloaded"
      IF (ZAnsIndex = LastDnld OR NOT ZConcatFIles) THEN _
         CALL SkipLine (1) : _
         CALL QuickTPut1 ("Download successful")   ' PE 02/16/90
       '  IF WasX THEN _
       '     CALL QuickTPut1 ("but not counted against ratios")
21768 'IF ZAutoDownInProgress THEN _
      '   ZWasDF$ = " AUTO" + _          ' Pe 02/04/90
      '        MID$(ZWasN$,2)
'      IF INSTR(ZWasN$,"Aborted") THEN _
'         ZAutoDownInProgress = 0
      ZOutTxt$ = ""
21770 CALL AMorPM
      IF NOT ZBatchTransfer THEN _
         GOTO 21773
      CALL OpenWork (2,ZNodeWorkFile$)
      IF ZErrCode > 0 THEN _
         RETURN
      ZWasQ = 0
      WHILE NOT EOF(2)
         CALL ReadAny
         ZWasQ = ZWasQ + 1
         ZUserIn$(ZWasQ) = ZOutTxt$
      WEND
21772 IF ZWasQ < 1 THEN _
         ZBatchTransfer = ZFalse : _
          RETURN
      CALL OpenWork (2,ZUserIn$(ZWasQ))
      IF ZErrCode > 0 THEN _
         ZErrCode = 0 : _
         ZWasQ = ZWasQ - 1 : _
         GOTO 21772
      ZBytesInFile# = LOF(2)
      ZFileName$ = ZUserIn$(ZWasQ)
21773 CALL BreakFileName (ZFileName$,DR$,WasX$,Extension$,ZTrue)
      ZWasZ$ = WasX$ + _
           Extension$ + _
           ZWasDF$ + _
           " at " + _
           ZTime$ + _
           " using " + _
           ZWasFT$ + _
           STR$(ZBytesInFile#)
      CALL UpdtCalr (ZWasZ$,2)
      IF ZBatchTransfer THEN _
         ZWasQ = ZWasQ - 1 : _
         GOTO 21772
'      CALL CheckRatio (ZFalse)
21774 IF ZMenuIndex = 6 THEN _
         IF ZDnldCompleted THEN _      'Pe 02/05/90
            ZOutTxt$ = WasX$ : _
            ZSubParm = 5 : _
'            CALL Library
      RETURN
'********************************************************************
21778   CALL AllCaps (ZFileNameHold$)
      IF ZFileNameHold$ = "ALLFILES.ZIP" OR_
         ZfileNameHold$ = "ALLFILES" OR _
	 ZFileNameHold$ = "PKZ102.EXE"  THEN _
	 CALL SkipLine(1) :_
	 CALL QuickTPut ("Downloading " +ZFileNameHold$ +" is NOT Charged Against your Stats!",2) :_
         CALL DelayTime (2) : _
         DownFiles = DownFiles - 1 :_
 IF DownFiles < 0 THEN_
 DownFiles = 0
 RETURN
'
'
' *****   TURN ON INTERMEDIATE ECHO   ****
'
'  (formerly line 50620 in RBBS-PC.BAS
21780 IF ZEchoer$ = "I" THEN _
         CALL SetEcho ("I")
'
' *  RESTORE COMMUNICATIONS AFTER Switch TO 8 BIT
'
'  (formerly between lines 50620 and 50630 in RBBS-PC.BAS
      IF SwitchToEight THEN _
         IF ZSwitchBack THEN _
            OUT ZLineCntlReg, PrevLineCntl : _
            CALL DelayTime (3) : _
            ZEightBit = ZFalse : _
            SwitchToEight = ZFalse
      RETURN
'
' *****  TURN OFF INTERMEDIATE ECHO  ****
'
'  (formerly line 50630 in RBBS-PC.BAS
21790 IF ZEchoer$ = "I" THEN _
         CALL SetEcho ("R")
      RETURN
'
' *****   DIRECTORY SEARCH   ****
'
'  (formerly lines 52900 to 52920 in RBBS-PC.BAS
21800 WasCK = 2
21810 ZOutTxt$ = "Text string to search for" + ZCrLf$  ' Bh
      ZOutTxt$ = ZOutTxt$ + "(wildcards allowed if it's a file name, [RETURN] to quit)"  ' Bh
      ZMacroMin = 99
      GOSUB 21668                                                    ' KG081201
      IF ZWasQ = 0 THEN _
         RETURN
21820 WasRS$ = ZUserIn$(ZAnsIndex)
      WildSearch = (INSTR(WasRS$,"*") > 0 OR INSTR(WasRS$,"?") > 0)
      CALL AllCaps (WasRS$)
      SearchString$ = WasRS$
      SearchDate$ = ""
      ZJumpSearching = ZFalse
      WasA1$ = WasRS$
      GOTO 21867
'
' *****  P - personal download  ****
'
'  (formerly lines 52950 to 52952 in RBBS-PC.BAS
21850 IF ZPersonalBegin < 1 OR ZPersonalLen < 1 THEN _
         RETURN
      DnldFlag = 0
      PersonalDnld = ZTrue
21852 CALL PersFile (MID$(ZUserRecord$,ZPersonalBegin,ZPersonalLen),_
                     DnldFlag)
      IF ZSubParm = -1 THEN _
         ZFileSysParm = 7: _
         RETURN
      IF ZLastIndex <= 0 THEN _
         GOTO 21854
      ZConcatFIles = ZPersonalConcat
      ZStopInterrupts = ZTrue
      TimeLockExempt = ZTrue
      GOSUB 20202
      IF ZFileSysParm > 1 THEN _
         GOTO 21854
      TimeLockExempt = ZFalse
      ZConcatFIles = ZFalse
      GOTO 21852
21854 PersonalDnld = ZFalse
      RETURN
'
' *  N - COMMAND FROM FILES MENU (DISPLAY NEW FILES SINCE Last DIR DISPLAY)
'
'  (formerly lines 53000 to 53070 in RBBS-PC.BAS
21860 WasCK = 1
21862 WasA1$ = RIGHT$(ZWasLM$,4) +_
            LEFT$(ZWasLM$,2)
      ZOutTxt$ = "Files on/after MMDDYY, [ENTER] = " + WasA1$
      GOSUB 21668
      CALL AllCaps (ZUserIn$(ZAnsIndex))
      IF ZWasQ = 0 OR ZUserIn$(ZAnsIndex) = "S" THEN _
         WasRS$ = ZWasLM$ : _
         GOTO 21866
21865 IF LEN(ZUserIn$(ZAnsIndex)) <> 6 THEN _
         GOTO 21862
      WasA1$ = ZUserIn$(ZAnsIndex)
      WasRS$ = RIGHT$(WasA1$,2) + _
            LEFT$(WasA1$,4)
21866 SearchDate$ = WasRS$            'Pe 03/18/90
      SearchString$ = ""
      ZJumpSearching = ZFalse
21867 CALL GetDirs (ZFalse)            'Pe 02/05/90
      IF ZWasQ = 0 THEN _
         RETURN
21871 CALL ConvertDir (ZAnsIndex)
      ZListDir = ZTrue
      ListNew = ZTrue
      ZSearchingAll = ZFalse
21875 ZWasZ$ = ZUserIn$(ZAnsIndex)
      IF NOT ZSearchingAll THEN _
         IF ZWasZ$ = "ALL" THEN _
            IF NOT ZLimitSearchToFMS THEN _
               GOSUB 21890
21880 WasQX = ZAnsIndex
      GOSUB 20157
      IF ZFileSysParm > 1 THEN _
         RETURN
      ZAnsIndex = ZAnsIndex + 1
      IF ZAnsIndex <= ZLastIndex THEN _
         GOTO 21875
      ListNew = ZFalse
      SearchString$ = ""
      SearchDate$ = ""
      RETURN
21890 WasG = ZAnsIndex
      CALL GetAll (ZUserIn$(),WasG)
      ZSearchingAll = ZTrue
      ZLastIndex = WasG
      ZAnsIndex = ZAnsIndex + 1
      RETURN
'
' *  MAIN FILE SYSTEM ERROR TRAP - ALL ERRORS PASS THROUGH THIS ROUTINE
'
'  (formerly lines 13000 to 13500 in RBBS-PC.BAS
21900 IF ZDebug THEN _
         ZOutTxt$ = "RBBSSUB5 DEBUG Error Trap Entry ERL=" + _
              STR$(ZWasEL) + _
              " ERR=" + _
              STR$(ZErrCode) : _
         IF ZPrinter THEN _
            CALL Printit(ZOutTxt$) _
         ELSE CALL LPrnt(ZOutTxt$,1)
      IF ZWasEL = 20126 AND ZErrCode = 53 THEN _
         GOTO 20142
      IF ZWasEL = 20242 AND ZErrCode = 62 THEN _
         CALL UpdtCalr (ZFileSecFile$ + " bad format!",2) : _
         GOTO 20247
      IF ZWasEL = 20263 THEN _
         ZOutTxt$ = "<Download aborted>" : _
         ZDnldCompleted = ZFalse : _     'Pe 02/05/90
         GOTO 20390
      IF ZWasEL = 20452 AND ZErrCode = 53 THEN _
         GOTO 20451
      IF ZWasEL = 20560 AND ZErrCode = 67 THEN _
         GOTO 20451
      IF ZWasEL = 20560 AND ZErrCode = 70 THEN _
         IF VAL(ZFreeSpace$) > 1999 THEN _
            GOTO 20610 _
         ELSE CALL QuickTPut1 ("No room for uploads. Try tomorrow.") : _
              GOTO 21700
      IF ZWasEL = 20620 THEN _
         GOTO 20670
      IF ZWasEL = 20650 THEN _
         GOTO 20670
      IF ZWasEL = 20736 AND ZErrCode = 53 THEN _
         GOTO 21700
      IF ZWasEL = 20900 AND ZErrCode = 75 THEN _
         GOTO 21230
      IF ZWasEL = 20900 AND ZErrCode = 70 THEN _
         CALL QuickTPut1 ("No room for uploads. Try tomorrow.") : _
         GOTO 21230
      IF ZWasEL = 21131 OR ZWasEL = 21220 THEN _
         ZErrCode = 0 : _
         GOTO 21230
      IF ZWasEL = 21480 THEN _
         CALL LogError : _
         IF ZErrCode = 57 THEN _
            CALL QuickTPut1 ("Error reading file.  Aborting download") : _
            ZDnldCompleted = ZFalse : _   'Pe 02/05/90
            GOTO 21230
21910 CALL LogError
      CALL QuickTPut1 (ZCallersRecord$)
      ZFileSysParm = 3
      RETURN
21920 ' EXIT RBBS-PC FILE SUBSYSTEM
      END SUB
63100 ' $SUBTITLE: 'DoorReturn - Subroutine to process requests from a door'
' $PAGE
'
'  NAME    -- DoorReturn
'
'  INPUTS  -- PARAMETER                      MEANING
'             DOUTx.DEF               File of requests
'
'  OUTPUTS -- ZUserSecLevel     Revised Security Level
'
'  PURPOSE -- To give Doors a stable way to make requests
'             to the host.
'
      SUB DoorReturn STATIC
      IF ZPrivateDoor OR NOT ZExitToDoors THEN _
         EXIT SUB
      ZFileName$ = "DOUT" + ZNodeID$ + ".DEF"
      CALL FindIt (ZFileName$)
      IF NOT ZOK THEN _
         EXIT SUB
63105 IF EOF(2) THEN _
         GOTO 63195
      CALL ReadParms (ZOutTxt$(),2,1)
      IF ZErrCode > 0 THEN _
         GOTO 63115
      IF LEN(ZOutTxt$(1)) < 2 THEN _
         EXIT SUB
      ZUserIn$ = LEFT$(ZOutTxt$(1),2) + ","
      WasX = INSTR("SL,UR,",ZUserIn$)
      IF WasX = 0 THEN _
         GOTO 63105
      WasX = WasX\3 + 1
      ON WasX GOTO 63110,63115
      GOTO 63105
63110 WasX$ = LEFT$(ZOutTxt$(2),1)         ' SL = Security Level
      CALL CheckInt (ZOutTxt$(2))
      IF ZErrCode > 0 THEN _
         GOTO 63105
      IF WasX$ = "+" OR WasX$ = "-" THEN _
         ZWasA = ZUserSecLevel + ZTestedIntValue _
      ELSE ZWasA = ZTestedIntValue
      IF ZWasA < ZSysopSecLevel THEN _
         ZAdjustedSecurity = (ZWasA <> ZUserSecLevel) : _
         IF ZAdjustedSecurity THEN _
            ZUserSecLevel = ZWasA : _
            MID$(ZUserRecord$,47,2) = MKI$(ZWasA) : _
            CALL QuickTPut1 ("Security changed to" + STR$(ZWasA)) : _
            CALL UpdtCalr ("Door reset security to "+STR$(ZWasA),2)
      GOTO 63105
63115 IF LEN(ZOutTxt$(1)) < 7 THEN _
         GOTO 63105
      IF MID$(ZOutTxt$(1),3,1) <> "(" THEN _
         GOTO 63105
      WasX = INSTR(4,ZOutTxt$(1),":")
      IF WasX < 1 THEN _
         GOTO 63105
      CALL CheckInt (MID$(ZOutTxt$(1),4,WasX-4))
      IF ZErrCode > 0 THEN _
         GOTO 63105
      IF ZTestedIntValue > 128 OR ZTestedIntValue < 1 THEN _
         GOTO 63105
      ZWasA = ZTestedIntValue
      CALL CheckInt (MID$(ZOutTxt$(1),WasX+1))
      IF ZErrCode > 0 OR ZTestedIntValue < 1 OR ZTestedIntValue > 128 THEN _
         GOTO 63105
      MID$(ZUserRecord$,ZWasA,ZTestedIntValue) = LEFT$(ZOutTxt$(2) + _
         SPACE$(ZTestedIntValue),ZTestedIntValue)
      CALL UpdtCalr ("Door set UR"+STR$(ZWasA)+":"+STR$(ZTestedIntValue)+" to <"+ZOutTxt$(2)+">",2)
      GOTO 63105
63195 CALL KillWork (ZFileName$)
      ZErrCode = 0
      END SUB
63200 ' $SUBTITLE: 'WildCard -- Matches string to a pattern'
' $PAGE
'  NAME    -- WildCard
'
'  INPUTS  -- PARAMETER             MEANING
'             Pattern$           PATTERN TO CHECK
'             Strng$             STRING TO FIE
'
'  OUTPUTS -- ZOK                True IF MATCH Found
'                                False IF No MATCH WAS Found
'
'  PURPOSE  Determine whether a string is an instance in a pattern
'           supported patterns are only "?" which requires a
'           character but can be any, and "*" which matches any-
'           thing, including a null string.  Anything else in a
'           sting must be an exact match.  Supports reverse
'           wildcards.
'
'
      SUB WildCard (Pattern$,Strng$) STATIC
63285 ZOK = ZTrue
      PatPos = 0
      StrPos = 0
      Inc = 1
      WasKT = 0
      WasP = LEN(Pattern$)
      WasL = LEN(Strng$)
63286 PatPos = PatPos + Inc
      StrPos = StrPos + Inc
      WasKT = WasKT + 1
      IF WasKT > WasL THEN _
         GOTO 63288
      ZUserIn$ = MID$(Pattern$,PatPos,1)
      IF ZUserIn$ = "*" THEN _
         GOTO 63289
63287 IF ZUserIn$ <> "?" AND MID$(Strng$,StrPos,1) <> ZUserIn$ THEN _
         ZOK = ZFalse : _
         EXIT SUB
      GOTO 63286
63288 IF PatPos >= LEN(Pattern$) OR PatPos < 1 THEN _
         EXIT SUB
      IF MID$(Pattern$,PatPos,1) <> "*" THEN _
         ZOK = ZFalse : _
         EXIT SUB
63289 IF PatPos <> WasP THEN _   ' Reverse search
         Inc = -1 : _
         WasP = PatPos : _
         PatPos = LEN(Pattern$) + 1 : _
         StrPos = LEN(Strng$) + 1 : _
         WasKT = 0 : _
         GOTO 63286
      END SUB
63300 ' $SUBTITLE: 'BreakFileName - sub to split file name into components'
' $PAGE
'
'  NAME    -- BreakFileName
'
'  INPUTS  -- PARAMETER                    MEANING
'             FileSpec$        FULL NAME OF FILE
'             ForJoining       True IF WANT PARTS FORMATTED FOR
'                                           FORMING FILE NAMES
'  OUTPUTS -- DrvPath$         DRIVE AND PATH
'             Prefix$          PREFIX OF FILE NAME
'             Extension$       EXTENSION OF FILE NAME
'
' (E.G. "C:\RBBS\ARCE.COM" HAS "C:\RBBS" AS DRIVE AND PATH,
'                              "ARCE"    AS PREFIX OF THE FILE NAME, AND
'                              "COM"     AS THE EXTENSION OF THE FILE NAME.
'
' JOINED FORMAT IS C:\RBBS\,ARCE,.COM
'
'  PURPOSE -- To break a file name into its component parts
'             of drive/path, prefix, and extension
'
'
      SUB BreakFileName (FileSpec$,DrvPath$,Prefix$,Extension$,ForJoining) STATIC
      CALL AllCaps (FileSpec$)
      DrvPath$ = ""
      Prefix$ = ""
      Extension$ = ""
      CALL TrimTrail (FileSpec$,"\")
      WasL = LEN(FileSpec$)
      IF WasL < 1 THEN _
         EXIT SUB
      CALL FindLast (FileSpec$,"\",WasX,WasY)
      IF WasX < 1 THEN _
         IF MID$(FileSpec$,2,1) = ":" THEN _
            DrvPath$ = LEFT$(FileSpec$,1) : _
            ZWasS = 3 _
         ELSE ZWasS = 1 _
      ELSE DrvPath$ = LEFT$(FileSpec$,WasX-1) : _
           ZWasS = WasX + 1 : _
           IF WasY = 1 THEN _
              DrvPath$ = DrvPath$ + "\"
      WasX = INSTR(FileSpec$ + ".",".")
      IF WasX < WasL THEN _
         Extension$ = MID$(FileSpec$,WasX + 1)
      IF ZWasS <= WasL THEN _
         IF WasX >= ZWasS THEN _
            Prefix$ = MID$(FileSpec$,ZWasS,WasX - ZWasS)
      IF NOT ForJoining THEN _
         EXIT SUB
      IF LEN(DrvPath$) = 1 THEN _
         IF DrvPath$ <> "\" THEN _
            DrvPath$ = DrvPath$ + _
                       ":"
      IF INSTR(DrvPath$,"\") > 0 AND RIGHT$(DrvPath$,1) <> "\" THEN _
         DrvPath$ = DrvPath$ + _
                    "\"
      IF LEN(Extension$) > 0 THEN _
         Extension$ = "." + _
                      Extension$
      END SUB
63310 ' $SUBTITLE: 'RestoreCom - sub to restore comm port'
' $PAGE
'
'  NAME    -- RestoreCom
'
'  INPUTS  -- none
'
'  OUTPUTS -- none
'
'  PURPOSE -- To restore communications port after an external
'             program may have left it in altered state
'
      SUB RestoreCom STATIC
      Parity$ = MID$(",N,8,1,E,7,1",7 + 6 * ZEightBit,6)
      IF ZLocalUser THEN _
         EXIT SUB
      CALL SetBaud
      CALL OpenCom(ZTalkToModemAt$,Parity$)
      END SUB
63320 ' $SUBTITLE: 'ShellExit - sub to shell out from RBBS'
' $PAGE
'
'  NAME    -- ShellExit
'
'  INPUTS  -- ShellTem$     String to invoke shell with
'
'  OUTPUTS -- none
'
'  PURPOSE -- Delay so that strings can finish printing.  Restore comm
'             port on return
'
      SUB ShellExit (ShellTem$) STATIC
      CALL DelayTime (8 + ZBPS)
      CLOSE 3
      IF NOT ZLocalUser THEN _
         OUT ZModemCntlReg,INP(ZModemCntlReg) OR 1 : _
         CLOSE 2
      CALL MetaGSR (ShellTem$,ZFalse)
      SHELL ShellTem$
      CALL DelayTime (2)
      CALL RestoreCom
      END SUB
63330 ' $SUBTITLE: 'ReadMacro - sub to read macro'
' $PAGE
'
'  NAME    -- ReadMacro
'
'  INPUTS  -- PARAMETER             MEANING
'
'  OUTPUTS -- ZOutTxt$               LINE TO PROCESS IN MACRO
'             ZMacroActive           FLAG WHETHER IN A MACRO
'
'  PURPOSE -- Reads in a line from macro file (#6) and processes
'             macro commands, which are:
'             *0 - display what follows, no carriage return
'             *1 - display what follows with carriage return
'             *B - display block that follows
'             *F - display File
'             WT - wait specified # of seconds
'             >> - append following block to specified file
'             ST - stack following (with carriage return)
'             ON - define case
'             == - case value that applies to following block
'             M! - execute following macro
'             M@ - abort macro processing
'             EY - Echo on (yes)
'             EN - Echo off (no)
'             /* - comment line skipped in processing
'             TK - Turbo key on (if user preference)
'             << - Read from file into a form
'             := - Assign value to work variable
'
      SUB ReadMacro STATIC
      IF ZMacroTemplate$ <> "" THEN _
         GOTO 63392
      IF ZDistantTGet = 2 THEN _
         GOTO 63349
63336 GOSUB 63395
      IF NOT ZMacroActive THEN _
         ZMacroEcho = ZTrue : _
         EXIT SUB
      IF LEN(ZOutTxt$) < 3 THEN _
         GOTO 63398
      WasX$ = RIGHT$(ZOutTxt$,LEN(ZOutTxt$)-3)
      IF CompareVar > 0 THEN _
         IF NOT CaseExecute THEN _
            IF LEFT$(ZOutTxt$,3) = ZSmartTextCode$+"==" THEN _
               GOTO 63370 _
            ELSE IF LEFT$(ZOutTxt$,7) = ZSmartTextCode$ + "END ON" THEN _
                    CompareVar = 0 : _
                    GOTO 63336 _
                  ELSE GOTO 63336
      IF LEFT$(ZOutTxt$,1) <> ZSmartTextCode$ THEN _
         GOTO 63398
      CALL CheckInt (MID$(ZOutTxt$,2))
      IF ZErrCode > 0 THEN _
         GOTO 63398
      IF ZTestedIntValue > 0 AND ZTestedIntValue <= ZMaxWorkVar THEN _
         ZOutTxt$ = WasX$ : _  ' Macro command ask
         ZForceKeyboard = ZTrue : _
         ZMacroSave = ZTestedIntValue : _
         ZLinesPrinted = 1 : _
         ZNonStop = (ZPageLength < 1) : _
         EXIT SUB
      ON (1+INSTR("*0*1*B*FWT>>STON==M!M@EYEN/*TK<<:=LVNVCVLO",MID$(ZOutTxt$,2,2)))\2 GOTO _
         63345, _  ' Display with no Carriage Return
         63347, _  ' Display with Carriage Return
         63340, _  ' Display Block
         63348, _  ' Display File
         63343, _  ' Wait # of seconds
         63350, _  ' Append to file
         63355, _  ' Stack
         63360, _  ' Case
         63370, _  ' Case Comparison
         63375, _  ' Macro execute
         63380, _  ' Macro Abort
         63383, _  ' Macro Echo on
         63385, _  ' Macro Echo off
         63336, _  ' Macro Comment
         63387, _  ' Turbo Key allowed
         63390, _  ' Form read
         63362, _  ' Assign value to work var
         63363, _  ' LV list verify
         63364, _  ' NV number verify
         63364, _  ' CV character verify
         63367     ' LO assign file location
      GOTO 63398
63338 ZOutTxt$ = WasX$
63339 ZSubParm = 4
      CALL TPut
      RETURN
63340 WasX$ = ZSmartTextCode$ + "END"  ' Print Block
      GOSUB 63395
      WHILE ZMacroActive AND LEFT$(ZOutTxt$,4) <> WasX$
         GOSUB 63339
         CALL SkipLine (1)
         GOSUB 63395
      WEND
      GOTO 63336
63343 CALL CheckInt (WasX$)      ' Delay
      IF ZErrCode = 0 THEN _
         CALL DelayTime (ZTestedIntValue)
      GOTO 63336
63345 GOSUB 63338               ' Print Line
      GOTO 63336
63347 GOSUB 63338
      CALL SkipLine (1)
      GOTO 63336
63348 CALL Trim (WasX$)            ' Print File
      CALL FINDITX (WasX$,7)
      IF NOT ZOK THEN _
         GOTO 63336
      ZLinesPrinted = 1
      ZNo = ZFalse
      ZNonStop = (ZNonStop OR ZPageLength < 1)
63349 WHILE (NOT EOF(7) AND (NOT ZNo) AND (ZNonStop OR (ZLinesPrinted < ZPageLength)) AND (ZSubParm > -1))
         CALL ReadDir (7,1)
         GOSUB 63396
         ZSubParm = 5
         CALL TPut
      WEND
      ZDistantTGet = 0
      IF ZSubParm < 0 THEN _
         EXIT SUB
      IF EOF(7) OR ZNo THEN _
         CLOSE 7 : _
         ZNo = ZFalse : _
         GOTO 63336
      ZDistantTGet = 2
      CALL PauseExit
      EXIT SUB
63350 ZWasEN$ = WasX$            ' Append to file
      WasX = INSTR(ZWasEN$," /FL")
      OverStrike = (WasX > 0)
      IF OverStrike THEN _
         ZWasEN$ = LEFT$(ZWasEN$,WasX-1) + RIGHT$(ZWasEN$,LEN(ZWasEN$)-WasX-3)
      CALL Trim (ZWasEN$)
      CALL LockAppend
      IF ZErrCode > 0 THEN _
         GOTO 63352
      GOSUB 63395
      WasX$ = ZSmartTextCode$ + "END"
      WHILE ZMacroActive AND LEFT$(ZOutTxt$,4) <> WasX$
         CALL PrintWorkA (ZOutTxt$)
         GOSUB 63395
      WEND
63352 CALL UnLockAppend
      OverStrike = ZFalse
      GOTO 63336
63355 ZCommPortStack$ = ZCommPortStack$ + WasX$ + ZCarriageReturn$  ' STack
      GOTO 63336
63360 CompareVar = VAL(WasX$)
      CALL AllCaps (WasX$)
      IF CompareVar < 1 OR CompareVar > ZMaxWorkVar THEN _
         CompareVar = 0
      GOTO 63336
63362 CALL Trim (WasX$)
      CALL CheckInt (WasX$)
      WasX = INSTR(WasX$," ")
      IF WasX > 0 AND ZTestedIntValue > 0 AND ZTestedIntValue <= ZMaxWorkVar THEN _
         ZGSRAra$(ZTestedIntValue) = RIGHT$(WasX$,LEN(WasX$)-WasX)
      GOTO 63336
63363 ZVerifyList$ = WasX$
      CALL Trim (ZVerifyList$)
      GOTO 63365
63364 CALL Trim (WasX$)
      WasX = INSTR(WasX$," ")
      IF WasX = 0 THEN _
         GOTO 63336
      ZVerifyLow$ = LEFT$(WasX$,WasX-1)
      ZVerifyHigh$ = RIGHT$(WasX$,LEN(WasX$)-WasX)
      CALL Trim (ZVerifyLow$)
      CALL Trim (ZVerifyHigh$)
      ZVerifyNumeric = (MID$(ZOutTxt$,2,1) = "N")
63365 ZVerifying = ZTrue
      GOTO 63336
63367 CALL TRIM (WasX$)
      ZFileLocation$ = WasX$
      GOTO 63336
63370 IF CompareVar = 0 THEN _     ' Compare Case
         GOTO 63336
      ZWasDF$ = ZGSRAra$(CompareVar)
      CALL AllCaps (ZWasDF$)
      CaseExecute = (WasX$ = ZWasDF$)
      GOTO 63336
63375 CALL Trim (WasX$)           ' Execute Macro
      CALL Macro (WasX$,WasX)
      GOTO 63336
63380 ZMacroActive = ZFalse     ' Abort Macro
      GOTO 63398
63383 ZMacroEcho = ZTrue
      GOTO 63336
63385 ZMacroEcho = ZFalse
      GOTO 63336
63387 ZTurboKey = -ZTurboKeyUser   'TK Turbo Key
      GOTO 63336
63390 ZUserIn$ = ZOutTxt$
      ZUserIn$(5) = ""
      ZUserIn$(6) = ""
      ZWasQ = 1
      ZStoreParseAt = 1
      CALL ParseIt
      IF ZWasQ < 4 THEN _
         GOTO 63336
      WasX$ = ZSmartTextCode$ + "END"
      GOSUB 63397
      ZMacroTemplate$ = ""
      WHILE ZMacroActive AND LEFT$(ZOutTxt$,4) <> WasX$
         ZMacroTemplate$ = ZMacroTemplate$ + ZOutTxt$ + ZCrLf$
         GOSUB 63397
      WEND
      WasX = VAL(ZUserIn$(4))
      VarLen = (ZUserIn$(3) <> "/F")
      CALL FindIt (ZUserIn$(2))
      IF (WasX < 1) OR (NOT ZOK) OR (VarLen AND WasX > ZMaxWorkVar) THEN _
         ZMacroTemplate$ = "" : _
         GOTO 63336
      PauseEachRec = (ZUserIn$(6) = "/1")
63392 CALL FormRead (ZMacroTemplate$,ZUserIn$(2),NOT VarLen,WasX,(ZUserIn$(5) = "/FL"),PauseEachRec)
      IF ZMacroTemplate$ <> "" THEN _
         EXIT SUB _
      ELSE GOTO 63336
63395 GOSUB 63397
      GOSUB 63396
      RETURN
63396 CALL SmartText (ZOutTxt$,ZFalse, OverStrike)
      CALL MetaGSR (ZOutTxt$,OverStrike)
      RETURN
63397 IF EOF(6) THEN _         ' Read next line in macro
         ZMacroActive = ZFalse _
      ELSE CALL ReadDir (6,1) : _
           ZMacroActive = (ZErrCode = 0)
      RETURN
63398 END SUB    ' Not Macro command - pass to normal processing
63400 ' $SUBTITLE: 'LockAppend - prepares for file append'
' $PAGE
'
'  NAME    -- LockAppend
'
'  INPUTS  -- ZWasEN$            Name of file to append to
'
'  OUTPUTS -- none
'
'  PURPOSE -- Locks and opens file to append to
'
      SUB LockAppend STATIC
      WasBX = &H4
      ZSubParm = 9
      CALL FileLock
      ZErrCode = 0
      CALL OpenWorkA (ZWasEN$)
      END SUB
63410 ' $SUBTITLE: 'UnLockAppend - cleans up after file append'
' $PAGE
'
'  NAME    -- UnLockAppend
'
'  INPUTS  -- none
'
'  OUTPUTS -- none
'
'  PURPOSE -- Unlocks and close file appending to
'
      SUB UnLockAppend STATIC
      WasBX = &H4
      ZSubParm = 10
      CALL FileLock
      CLOSE 2
      END SUB
63420 ' $SUBTITLE: 'FormRead - Reads from a file into a form'
' $PAGE
'
'  NAME    -- FormRead
'
'  INPUTS  -- Template$      Display formvoke shell with
'             FilName$       Data file to get values from
'             FixedLength    Whether file is fixed length
'             DataVar       # bytes data if fixed length; # fields
'                              if variable length
'             OverStrike     Whether typeover into form or insert
'             RecPause      Whether pause after every record displayed
'                               otherwise when screen fills
'  OUTPUTS -- (displays data base records)
'
'  PURPOSE -- Allows field oriented data base data to be displayed
'               in a human readable format by substituting field
'               data into template or form
'
      SUB FormRead (Template$,FilName$,FixedLength,DataVar,OverStrike,RecPause) STATIC
63422 IF EOF(2) OR ZNo OR (ZErrCode > 0) OR (ZSubParm < 0) THEN _
         Template$ = "" : _
         EXIT SUB
      IF FixedLength THEN _
         CALL ReadDir (2,1) : _
         ZGSRAra$(1) = ZOutTxt$ _
      ELSE CALL ReadParms (ZGSRAra$(),DataVar,1)
      WasX$ = Template$
      CALL SmartText (WasX$,ZTrue,OverStrike)
      CALL MetaGSR (WasX$,OverStrike)
      CALL BufAsUnit (WasX$)
      IF RecPause OR (ZPageLength > 0 AND (ZLinesPrinted >= ZPageLength-1)) THEN _
         CALL PauseExit : _
         EXIT SUB
      GOTO 63422
      END SUB
63440 ' $SUBTITLE: 'BufAsUnit - prints string with no pauses'
' $PAGE
'
'  NAME    -- BufAsUnit
'
'  INPUTS  -- Strng$     String to print
'
'  OUTPUTS -- none
'
'  PURPOSE -- Prints string with embedded carriage returns.
'             Will never pause.  Used to print when can't call TGet
'
      SUB BufAsUnit (Strng$) STATIC
      WasL = LEN(Strng$)
      IF WasL < 1 THEN _
         EXIT SUB
      StartByte = 1
63450 CRat = INSTR(StartByte,Strng$,ZCarriageReturn$)
      IF CRat > 0 AND CRat < WasL THEN _
         CRFound = (MID$(Strng$,CRat + 1,1) = ZLineFeed$) _
      ELSE CRFound = ZFalse
      EOLlen = -2 * CRFound
      IF CRFound THEN _
         EOD = CRat _
      ELSE EOD = WasL + 1
      NumBytes = EOD - StartByte
      ZOutTxt$ = MID$(Strng$,StartByte,NumBytes)
      ZSubParm = 4
      CALL TPut
      CALL SkipLine (-(CRFound))
      IF ZRet THEN _
         EXIT SUB
      StartByte = EOD + EOLlen
      IF StartByte <= WasL THEN _
         GOTO 63450
      END SUB
63460 ' Check if macro exists and execute if does
      SUB MacroExe (Strng$) STATIC
      CALL Trim (Strng$)
      CALL Macro (Strng$,Found)
      IF NOT Found THEN _
         EXIT SUB
      CALL FdMacExe
      END SUB
63462 ' Unconditionally executes a macro
      SUB FdMaCExe STATIC
      ZOutTxt$ = ""
      ZMacroEcho = ZFalse
      ZSubParm = 1
      CALL TGet
      END SUB
63465 ' Forces a keyboard pause inside a macro
      SUB PauseExit STATIC
      ZSubParm = 4
      ZTurboKey = -ZTurboKeyUser
      ZOutTxt$ = ZMorePrompt$ + ">" + MID$("? ! ",2*ZTurboKey+1,2)
      ZForceKeyboard = ZTrue
      ZNoAdvance = ZTrue
      CALL TPut
      ZLinesPrinted = 0
      ZUserIn$ = ""
      END SUB
63470 ' $SUBTITLE: 'SetPrompt - sub to set prompts based on user security'
' $PAGE
'
'  NAME    -- SetPrompt
'
'  INPUTS  -- PARAMETER           MEANING
'             ZBegMain          POSITION START OF MAIN CMDS
'             ZBegFile          POSITION START OF FILE CMDS
'             ZBegUtil          POSITION START OF UTIL CMDS
'             ZBegLibrary       POSITION START OF Library CMDS
'
'  OUTPUTS -- PRESENT.OPTS$         DISPLAY WHAT USER CAN DO (1st)
'             CALLERS.OPTS$         DISPLAY WHAT USER CAN DO (2nd)
'             ZMainOpts$            MAIN OPTS USER CAN DO
'             ZFileOpts$            FILE OPTS USER CAN DO
'             ZUtilOpts$            UTIL OPTS USER CAN DO
'             ZLibOpts$         Library OPTS USER CAN DO
'
'  PURPOSE -- Sets command line display of what user can do by
'             section and display of what all user can do
'
      SUB SetPrompt STATIC
      First = ZBegMain
      Last = ZBegFile - 1
      CALL SetOpts (ZMainOpts$,ZInvalidMainOpts$,First,Last)
      First = ZBegFile
      Last = ZBegUtil - 1
      CALL SetOpts (ZFileOpts$,ZInvalidFileOpts$,First,Last)
      First = ZBegUtil
      Last = ZBegLibrary - 1
      CALL SetOpts (ZUtilOpts$,ZInvalidUtilOpts$,First,Last)
      First = ZBegLibrary
      Last = ZBegLibrary + 6
      CALL SetOpts (ZLibOpts$,ZInvalidLibraryOpts$,First,Last)
      First = 50
      Last = 56
      CALL SetOpts (SysOpt$,ZInvalidSysOpts$,First,Last)
      First = 46
      Last = 49
      CALL SetOpts (GlobalOpts$,InvalidGlobalOpts$,First,Last)
      IF LEN(SysOpt$) > 0 THEN _
         ZSystemOpts$ = "Sysop: " + _
                        SysOpt$
      ZMainOpts$ = GlobalOpts$ + _
                   ZMainOpts$
      ZFileOpts$ = GlobalOpts$ + _
                   ZFileOpts$
      ZUtilOpts$ = GlobalOpts$ + _
                   ZUtilOpts$
      ZLibOpts$ = GlobalOpts$ + _
                      ZLibOpts$
      CALL SortString (SysOpt$)
      CALL SortString (ZMainOpts$)
      ZMainOpts$ = ZMainOpts$ + _
                   SysOpt$
      CALL SortString (ZFileOpts$)
      CALL SortString (ZUtilOpts$)
      CALL SortString (ZLibOpts$)
      CALL AddCommas (ZMainOpts$)
      CALL AddCommas (ZFileOpts$)
      CALL AddCommas (ZUtilOpts$)
      CALL AddCommas (ZLibOpts$)
      ZDirPrompt$ = "Which category(ies) (" + _                 ' Bh
        MID$("A for all, L to list them or [RETURN] to quit)",8 * (ZUserSecLevel => ZMinSecToView) + 9)  ' Bh
      ZQuitPromptExpert$ = "Quit C,S, or to F,[M],U,@"
      ZQuitPromptNovice$ = "Quit C)onference, S)ession or to section " + _
                            "F)ile, [M]ain, U)til or @)Library"
      ZQuitList$ = "FMUS@C"
      IF ZUserSecLevel < ZOptSec(18) THEN _
         ZQuitPromptExpert$ = LEFT$(ZQuitPromptExpert$,23) : _
         ZQuitPromptNovice$ = LEFT$(ZQuitPromptNovice$,61) : _
         MID$(ZQuitList$,5) = " "
      IF ZUserSecLevel < ZOptSec(15) THEN _
         ZQuitPromptExpert$ = LEFT$(ZQuitPromptExpert$,22) + _
                               MID$(ZQuitPromptExpert$,25) : _
         ZQuitPromptNovice$ = LEFT$(ZQuitPromptNovice$,56) + _
                               MID$(ZQuitPromptNovice$,63) : _
         MID$(ZQuitList$,3,1) = " "
      IF ZUserSecLevel < ZOptSec(6) THEN _
         ZQuitPromptExpert$ = LEFT$(ZQuitPromptExpert$,16) + _
                               MID$(ZQuitPromptExpert$,19) : _
         ZQuitPromptNovice$ = LEFT$(ZQuitPromptNovice$,41) + _
                               MID$(ZQuitPromptNovice$,49) : _
         MID$(ZQuitList$,1,1) = " "
      CALL SetSection
      END SUB
63480 ' $SUBTITLE: 'NoPath - detects whether string has path'
' $PAGE
'
'  NAME    -- NoPath
'
'  INPUTS  -- Strng$     String to check
'
'  OUTPUTS -- HAS.NONE   True if has no path
'
'  PURPOSE -- Detects whether have path.  Used when shouldn't
'             be any
'
      SUB NoPath (Strng$,HasPath) STATIC
      CALL BreakFileName (Strng$,DrvPath$,Prefix$,Ext$,ZFalse)
      HasPath = (DrvPath$ <> "")
      END SUB
63490 ' $SUBTITLE: 'FindIt - Determine whether file exists'
' $PAGE
'
'  NAME    -- FindIt
'
'  INPUTS  -- FilName$   File name to check
'
'  OUTPUTS -- ZOK         True if file exists.  Opened as #2 if does
'
'  PURPOSE -- Determine whether file exists and open as standard work
'             file if it does (#2)
'
      SUB FindIt (FilName$) STATIC
      CALL FindItX (FilName$,2)
      END SUB
63495 ' $SUBTITLE: 'TimeBack - Give time back to the user'
' $PAGE
'
'  NAME    -- TimeBack
'
'  INPUTS  -- Index    = 1    Set start of time (begin give back)
'                      = 2    Give back time from defined start
'
'  OUTPUTS -- ZTimeCredits!         Number of seconds to credit with
'             ZSecsPerSession!  Number of seconds in current session
'
'  PURPOSE -- Give time back to the user (e.g. sysop initiated chat)
'
      SUB TimeBack (Index) STATIC
      IF Index = 1 THEN _
         CALL TimeRemain (MinsRemaining) : _
         ZWasQ! = ZSecsUsedSession! : _
         EXIT SUB
      CALL TimeRemain (MinsRemaining)
      WasX! = (ZSecsUsedSession! - ZWasQ!)
      ZTimeCredits! = ZTimeCredits! + WasX!
      END SUB
63500 ' $SUBTITLE: 'CmdStackPushPop - Save/restore command stack'
' $PAGE
'
'  NAME    -- CmdStackPushPop
'
'  INPUTS  -- Index    = 1    Save command stack
'                      = 2    Restore command stack
'             ZAnsIndex
'             ZLastIndex
'             ZUserIn$()
'
'  OUTPUTS -- ZUserIn$()                  Stacked commands
'             ZAnsIndex
'             ZLastIndex
'
'  PURPOSE -- Save restore a command stack list when need to input
'             another list in middle of previous list processing
'
      SUB CmdStackPushPop (Index) STATIC
      IF Index = 1 THEN _
         OrigLastIndex = ZLastIndex : _  ' save
         OrigIndex = ZAnsIndex : _
         FOR WasI = 1 TO OrigLastIndex : _
             ZOutTxt$(WasI) = ZUserIn$(WasI) : _
         NEXT : _
         EXIT SUB
      ZLastIndex = OrigLastIndex        ' restore
      ZAnsIndex = OrigIndex
      FOR WasI = 1 TO OrigLastIndex
         ZUserIn$(WasI) = ZOutTxt$(WasI)
      NEXT
      END SUB
63510 ' $SUBTITLE: 'VerifyAns - edits an answer'
' $PAGE
'
'  NAME    -- VerifyAns
'                                  MEANING
'  INPUTS  -- ZVerifying      Whether verifying
'             ZUserIn$(1)     Response verifying
'             ZVerifyList$    List of appropriate answers.  1st
'                                char is what separates answers
'             ZVerifyNumeric     Verify that is a valid integer
'                                  if false, then verifying that
'                                  a string is between 2 values
'             ZVerifyLow$     Lowest ok value of string
'             ZVerifyHigh$    Highest ok value of string
'
'  OUTPUTS -- ZOK             Whether passes verification
'             ZVerifyList$    Empties if ok
'             ZVerifying      Sets false if ok
'             ZVerifyNumeric  Sets false if ok
'
'  PURPOSE -- Processes edits on a user input
'
      SUB VerifyAns STATIC
      ZOK = ZTrue
      IF NOT ZVerifying THEN _
         EXIT SUB
      Temp$ = ZUserIn$(1)
      CALL AllCaps (Temp$)
      IF ZVerifyList$ <> "" THEN _
         WasX$ = LEFT$(ZVerifyList$,1) : _
         ZOK = (INSTR (ZVerifyList$, WasX$+Temp$+WasX$) > 0) _
      ELSE IF ZVerifyNumeric THEN _
              CALL CheckInt (ZUserIn$) : _
              ZOK = (ZErrCode = 0 AND _
                    ZTestedIntValue >= VAL(ZVerifyLow$) AND _
                    ZTestedIntValue <= VAL(ZVerifyHigh$)) _
           ELSE ZOK = (Temp$ >= ZVerifyLow$ AND Temp$ <= ZVerifyHigh$)
      IF ZOK THEN _
         ZVerifyList$ = "" : _
         ZVerifying = ZFalse : _
         ZVerifyNumeric = ZFalse
      END SUB
63520 ' $SUBTITLE: 'BinSearch - binary search a file'
' $PAGE
'
'  NAME    -- BinSearch
'                                  MEANING
'  INPUTS  -- PassedSearchFor$  Value you are looking for
'             StartPos          Starting position of sort key
'             NumChars          # of characters in sort key
'             LenRec            Length of record of data file searching
'             High              Record # of last record
'             ZFastTabs$        In a binary integer subfield (2 bytes)
'                                  holds 1st record when might find
'                                  a key beginning with a particular
'                                  character (0-9,A-Z).   Empty if
'                                  no Fast Tab exists for the file.
'
'  OUTPUTS -- RecFoundAt        Record # value found at (0 if none)
'             RecFound$         Full data record when found
'
'  PURPOSE -- Binary searches work file #2 for a key value in a
'             data file that is sorted on a key field
'
      SUB BinSearch (PassedSearchFor$,StartPos, NumChars, LenRec, High, RecFoundAt, RecFound$) STATIC
      SearchFor$ = LEFT$(PassedSearchFor$,NumChars)
      SearchFor$ = SearchFor$ + SPACE$(NumChars-LEN(SearchFor$))
      FIELD #2, LenRec AS SearchRec$
      Low = 0
      IF LEN(ZFastTabs$) < 72 THEN _
         GOTO 63522
      WasX$ = LEFT$(SearchFor$,1)
      WasX = INSTR("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ",WasX$)
      IF WasX > 0 THEN _
         Low = CVI(MID$(ZFastTabs$,1+2*(WasX-1),2)) - 1
      IF WasX < 36 THEN _
         High = CVI(MID$(ZFastTabs$,1+2*WasX,2))
63522 RecFoundAt = 0
      WasX$ = SPACE$ (NumChars)
      Done = ZFalse
      WHILE NOT Done
         WasI = INT(((High + Low) / 2) + .5)
         GET 2, WasI
         LSET WasX$ = MID$(SearchRec$, StartPos, NumChars)
         IF WasX$ = SearchFor$ THEN _
            RecFound$ = SearchRec$: _
            RecFoundAt = WasI : _
            Done = ZTrue _
         ELSE IF (High - Low) < 2 THEN _
                 Done = ZTrue _
              ELSE IF WasX$ < SearchFor$ THEN _
                      Low = WasI _
                   ELSE IF WasX$ > SearchFor$ THEN _
                           High = WasI
      WEND
      END SUB
63530 ' Take modem offhook
      SUB TakeOffHook STATIC
      CALL ModemPut (ZModemGoOffHookCmd$)
      CALL DelayTime (3)
      END SUB
63540 ' Match Name to one in message file
      SUB MsgNameMatch (PrimeName$,AltName$,SearchPos,Found) STATIC
      WasX$ = LEFT$(PrimeName$+"  ",22-8*(SearchPos < 7))
      Found = (MID$(ZMsgRec$,SearchPos, LEN(WasX$)) = WasX$)
      IF NOT Found THEN _
         IF AltName$ <> "" THEN _
            WasX$ = LEFT$(AltName$ + "  ",22-8*(SearchPos < 7)) : _
            Found = (MID$(ZMsgRec$,SearchPos, LEN(WasX$)) = WasX$)
      END SUB
'
' CHat Mods begin here
'
'63550 ' $SUBTITLE: 'LOG.NEW.FOR.CHAT - Save user info for chat'
' $PAGE
'
'  NAME    -- LOG.NEW.FOR.CHAT
'
'  INPUTS  -- NODES.IN.SYSTEM
'
'  OUTPUTS -- Updates the node record in RBBSCHAT.DEF with this users
'             name and chat activity (always "I") when the user logs on.
'
'  PURPOSE -- See above OUTPUTS
'
'      SUB LogNewForChat(NodesInSystem) STATIC
'      FileName$ = "RBBSCHAT.DEF"
'      CALL FindItX (FileName$, 7)
'      REM ** IF "RBBSCHAT.DEF" DOES NOT EXIST, THEN CREATE IT **
'      IF NOT ZOK THEN
'         CALL OpenWrk7 (FileName$)
'         FIELD 7, 128 AS TempNode$
'         LSET TempNode$ = SPACE$(128)
'         FOR Index = 1 TO ZMaxNodes
'            CALL LockIt7 (Index, ZFalse)
'         NEXT
'      END IF
'      ChatIndex = ZNodeRecIndex - 1
'      CLOSE 7
'      CALL OpenWrk7 (FileName$)
'      FIELD 7, 1 AS ChatActivity$, _
'               2 AS PagingNode$,   _
'               2 AS PrivateFor$,   _
'              72 AS ChatInput$,    _
'              31 AS ChatName$,     _
'               1 AS InTrueChat$
'      CALL LockIt7 (ChatIndex, ZTrue)
'      LSET ChatActivity$ = "I"    ' I means inactive
'      LSET PagingNode$ = MKI$(0)
'      LSET ChatName$ = SPACE$(31)
'      IF ZActiveUserName$ = ZSysopPswd1$ + " " + ZSysopPswd2$ THEN
'         LSET ChatName$ = "SYSOP"
'       ELSE
'         LSET ChatName$ = ZActiveUserName$
'      END IF
'      LSET ChatInput$ = SPACE$(72)
'      LSET PrivateFor$ = MKI$(0)
'      LSET InTrueChat$ = "I"
'      CALL LockIt7 (ChatIndex, ZFalse)
'      CLOSE 7
'      END SUB

'63560 ' $SUBTITLE: 'CBCHECK - Check for a page attempt'
' $PAGE
'
'  NAME    -- CBCHECK
'
'  INPUTS  -- NONE
'
'  OUTPUTS -- ChatActivity$   Changed to reflect whether or not they
'                              are going to chat
'
'  PURPOSE -- Check to see if we have been paged from another node
'
'      SUB CBCHECK STATIC
'      ZOutTxt$ = ""
'      DoTrueChat = ZFalse
'      FileName$ = "RBBSCHAT.DEF"
'      CALL FindItX (FileName$, 7)
'      IF ZOK THEN
'         ChatIndex = ZNodeRecIndex - 1
'         CLOSE 7
'         CALL OpenWrk7 (FileName$)
'         FIELD 7, 1 AS ChatActivity$, _
'                  2 AS PagingNode$,   _
'                  2 AS PrivateFor$,   _
'                 72 AS ChatInput$,    _
'                 31 AS ChatName$,     _
'                  1 AS InTrueChat$
'         CALL LockIt7 (ChatIndex, ZTrue)
'         IF ChatActivity$ = "R" THEN   'R means request for chat
'            PagerIndex = CVI(PagingNode$)
'            CALL RingCaller
'            CALL LockIt7 (PagerIndex, ZTrue)
'            ZOutTxt$ = ChatName$
'            DoTrueChat = (InTrueChat$ = "A")
'            CALL TrimTrail (ZOutTxt$, " ")
'            CALL QuickTPut( ZOutTxt$ + " is requesting that you join the CB simulator!", 1)
'            ZOutTxt$ = "Do you plan to join the CB simulator (Y/[N])"
'            ZSubParm = 1
'            CALL TGet
'            CALL LockIt7 (ChatIndex, ZTrue)
'            IF ZNo OR (ZWasQ = 0) THEN
'               LSET ChatActivity$ = "N"   'NO I WON'T BE CHATTING
'             ELSE
'               LSET ChatActivity$ = "Y"   'YEAH I'LL BE CHATTING
'               CALL QuickTPut("Use the C)hat Command to enter Chat", 2)
'            END IF
'            IF DoTrueChat THEN
'               LSET InTrueChat$ = "Y"
'             ELSE
'               LSET InTrueChat$ = "I"
'            END IF
'            CALL LockIt7 (ChatIndex, ZFalse)
'            CALL UpdtCalr("Paged from CB sim by node" + STR$(PagerIndex), 1)
'         END IF
'         CLOSE 7
'      END IF
'      END SUB

'63570 ' $SUBTITLE: 'CBCHAT - This is the actual chat code'
' $PAGE
'
'  NAME    -- CBCHAT
'
'  INPUTS  -- NODES.IN.SYSTEM
'
'  INTERNAL - NodesToSquelch$     STRING OF NODES NOT TO RECEIVE TEXT FROM
'             HasPaged             NODE (IF ANY) THAT THIS USER PAGED
'             CurrentNodeIndex    NODE RECORD IN "RBBSCHAT.DEF"
'             ChatActivity$        CURRENT STATUS OF EACH NODE   (RBBSCHAT.DEF)
'             PagingNode$          NODE WHICH HAS PAGED THIS ONE (RBBSCHAT.DEF)
'             PrivateFor$          THIS IS TURNED ON FOR PRIVATE MSG
'             ChatInput$           CURRENT TEXT INPUT BY USER FOR CHATTING
'             ChatName$            NAME OF USER ON EACH NODE (NOT ALWAYS USED)
'             SquelchIt            BOOLEAN - MEANS NODE IS IGNORED
'             ZOutTxt$(0)                 THIS IS TEXT TYPED BY -THIS- NODE
'             ZUserIn$()                  USED TO SAVE CURRENT STATUS OF EACH NODE
'                                   THIS INFO IS LATER COMPARED, AND IF THAT
'                                   STATUS IS CHANGED, THEN THE USER IS NOTIFIED
'             ChatHold$()          USED TO SAVE CURRENT TEXT INPUT BY EACH USER
'             DoTrueChat          MEANS OTHER USER HAS PAGED FROM TRUECH@
'                                   MODE, SO CBCHAT DROPS TO 'SUB TRUECHAT'
'                                   THEN EXITS AFTERWARDS.
'
'
'  OUTPUTS -- NONE
'
'  PURPOSE -- To allow users to chat between nodes in several different
'             ways.
'
'      SUB CBCHAT(NodesInSystem) STATIC
'      DoTrueChat = ZFalse
'      NodesToSquelch$ = ""                      'NODES TO SQUELCH (OBVIOUSLY)
'      HasPaged = 0
'      FileName$ = "RBBSCHAT.DEF"
'      CALL FindItX (FileName$, 7)
'      IF ZOK THEN
'         HasPaged = 0
'         CurrentNodeIndex = ZNodeRecIndex - 1
'         CLOSE 7
'         CALL OpenWrk7 (FileName$)
'         FIELD 7, 1 AS ChatActivity$, _
'                  2 AS PagingNode$,   _
'                  2 AS PrivateFor$,   _
'                 72 AS ChatInput$,    _
'                 31 AS ChatName$,     _
'                  1 AS InTrueChat$
'
'         CALL UpdtCalr("Entered CB sim at " + TIME$, 1)
'         CALL QuickTPut("Type Ctrl-T to Enter TrueCh@,  Type ? for help!,", 1)
'         CALL QuickTPut("     Ctrl-W to see Who else is on, Ctrl-P for another node", 1)
'         CALL QuickTPut("Hit ESC to exit chat!", 2)
'         REDIM ChatHold$(NodesInSystem)
'
'         CALL LockIt7 (CurrentNodeIndex, ZTrue)
'         DoTrueChat = (InTrueChat$ = "Y")
'         LSET ChatActivity$ = "A"
'         LSET PrivateFor$ = MKI$(0)
'         CALL LockIt7 (CurrentNodeIndex, ZFalse)
'
'         REM ** LOAD IN CURRENT NODAL STATUS FOR LATER COMPARISON **
'         FOR LineIndex = 1 TO NodesInSystem
'            CALL LockIt7 (LineIndex, ZTrue)
'            ZUserIn$(LineIndex) = ChatActivity$
'         NEXT
'
'         ReadyToEnter = ZFalse
'         ZAutoLogoff! = TIMER + ZWaitBeforeDisconnect
'
'         WasA1$ = ZActiveMessageFile$
'         ZActiveMessageFile$ = ZOrigMsgFile$
'         CALL OpenMsg
'         FIELD 1, 128 AS ZMsgRec$
'
'         DO
'
'            IF DoTrueChat THEN
'               CALL TrueChat(CurrentNodeIndex, HasPaged, NodesInSystem)
'               EXIT DO
'            END IF
'REM **************************************************************************
'REM ******Check for answer to page, or text from other users in chat *********
'REM **************************************************************************
'            FOR LineIndex = 1 TO NodesInSystem
'
'               SquelchIt = ZFalse
'               IF LineIndex <> CurrentNodeIndex THEN
'
'                  CALL LockIt7 (LineIndex, ZTrue)
'                  Index$ = MID$(STR$(LineIndex), 2, 1)
'
'                  REM ** CHECK TO SEE IF THIS NODE HAS BEEN SQUELCHED **
'                  IF NodesToSquelch$ <> "" THEN
'                     SquelchIt = (INSTR(NodesToSquelch$, Index$) > 0)
'                  END IF
'                  REM ** CHECK TO SEE IF OTHER NODE IN TRUE CHAT **
'                  IF NOT SquelchIt THEN
'                     SquelchIt = (InTrueChat$ = "A")
'                  END IF
'
'                  REM ** CHECK FOR ANSWER TO PAGE (IF A PAGE WAS DONE) **
'                  IF HasPaged = LineIndex THEN
'                     IF ChatActivity$ <> "R" THEN
'                        IF ChatActivity$ = "N" THEN
'                           CALL QuickTPut("Paged user probably will not enter chat mode!", 1)
'                           HasPaged = 0
'                         ELSEIF ChatActivity$ = "Y" THEN
'                           CALL QuickTPut("Paged user should be joining momentarily!", 1)
'                           HasPaged = 0
'                        END IF
'                     END IF
'                  END IF
'
'                  ChatTemp$ = ""
'                  NameTemp$ = ""
'
'                  REM ** CHECK FOR CHANGE IN NODAL ACTIVITY             **
'                  REM ** IN THIS CASE, SEE IF SOMEONE HAS LEFT THE CHAT **
'                  REM ** NODE MUST NOT BE SQUELCHED                     **
'                  IF NOT SquelchIt THEN
'                     IF (ZUserIn$(LineIndex) = "A") AND (ChatActivity$ = "I") THEN
'                        CALL QuickTPut("Node " + Index$ + " has exited chat mode!", 1)
'                     END IF
'                  REM ** OR, IF SOMEONE HAS JOINED THE CHAT **
'                     IF (ZUserIn$(LineIndex) <> "A") AND (ChatActivity$ = "A") THEN
'                        CALL QuickTPut("Node " + Index$ + " has entered the chat!", 1)
'                     END IF
'                  END IF
'
'                  REM ** SAVE NEW NODE STATUS (IF ANY) **
'                  ZUserIn$(LineIndex) = ChatActivity$
'
'                  REM ** IF OTHER NODE IS ACTIVE (& NOT SQUELCHED) CHECK IT **
'                  IF (ChatActivity$ = "A") AND (NOT SquelchIt) THEN
'
'                     GET 1, (LineIndex + 1)
'                     IF MID$(MESSAGE.RECORD$, 55, 2) = "-1" AND NOT ZSysop THEN
'                        NameTemp$ = "SYSOP"
'                      ELSE
'                        NameTemp$ = MID$(MESSAGE.RECORD$,1,26)
'                     END IF
'
'                     ChatTemp$ = ChatInput$
'                     CALL TrimTrail (ChatTemp$, " ")
'                     CALL TrimTrail (ChatHold$(LineIndex), " ")
'                     REM ** IF TEXT HAS CHANGED AND TEXT IS NOT A NULL STRING
'                     IF (ChatTemp$ <> ChatHold$(LineIndex)) AND ChatTemp$ <> "" THEN
'                        REM ** IF PUBLIC OR PRIVATE AND TO THIS NODE
'                        IF (CVI(PrivateFor$) = 0) OR (CVI(PrivateFor$) = CurrentNodeIndex) THEN
'                           CALL TrimTrail(NameTemp$, " ")
'                           ZOutTxt$ = "<" + Index$ + ">" + _
'                                      NameTemp$ + ": " + ChatTemp$
'                           CALL QuickTPut(ZOutTxt$, 1)
'                           ChatHold$(LineIndex) = ChatTemp$
'                        END IF
'                     END IF
'                  END IF
'               END IF
'            NEXT
'
'REM **************************************************************************
'REM *******Get text from local user (local, as in, this node of RBBS)*********
'REM **************************************************************************
'            ZOutTxt$(0) = ""                   'chat work string
'            ReadyToEnter = ZFalse
'            IF NOT ZLocalUser THEN
'               CALL EOFComm (ZChar%)
'              ELSE
'               ZChar% = -1
'            END IF
'            IF ZChar% <> -1 THEN          'if remote key in then get complete
'               CALL GetCom(Key$)
'             ELSE
'               Key$ = INKEY$             'else check for local
'            END IF
'            IF Key$ <> "" THEN
'               IF LEN(Key$) = 1 THEN
'                  IF Key$ = ZEscape$ THEN
'                     EXIT DO
'                   ELSEIF Key$ = CHR$(13) THEN
'                     ZOutTxt$(0) = ""
'                   ELSEIF Key$ = CHR$(16) THEN
'                     CALL PageEm(CurrentNodeIndex, HasPaged, NodesInSystem, 0)
'                     IF HasPaged = -1 THEN
'                        EXIT DO
'                     END IF
'                   ELSEIF Key$ = CHR$(20) THEN
'                     CALL TrueChat(CurrentNodeIndex, HasPaged, NodesInSystem)
'                     EXIT DO
'                   ELSEIF Key$ = CHR$(23) THEN
'                     CALL PageEm(CurrentNodeIndex, HasPaged, NodesInSystem, -1)
'                   ELSEIF Key$ = CHR$(63) THEN
'                     CALL BufFile ("CHATHELP", X)
'                   ELSE
'                     ZOutTxt$(0) = Key$
'                     ReadyToEnter = ZTrue
'                  END IF
'               END IF
'            END IF
'            IF ReadyToEnter THEN
'               CALL QuickTPut("> " + ZOutTxt$(0), 0)
'               CALL LineEdit (0, 64)
'               ReadyToEnter = ZFalse
'               ZAutoLogoff! = TIMER + ZWaitBeforeDisconnect
'            END IF
'
'            IF ZOutTxt$(0) <> "" THEN
'               PrivateMessage = 0
'               IF LEFT$(ZOutTxt$(0), 1) = "*" THEN
'                  PrivateMessage = VAL(MID$(ZOutTxt$(0), 2))
'                  REM ********************************************************
'                  REM ** CHECK HERE TO SEE IF PRIVATE NODE WAS SQUELCHED    **
'                  REM ** IF SO, UNSQUELCH IT.. IE: PRIVATE MSG UNSQUELCHES  **
'                  REM ** (SO TO SPEAK).                                     **
'                  REM ********************************************************
'                  IF NodesToSquelch$ <> "" THEN
'                     Squelched = INSTR(NodesToSquelch$, MID$(ZOutTxt$(0), 2, 1))
'                     IF Squelched = 1 THEN
'                        IF LEN(NodesToSquelch$) = 1 THEN
'                           NodesToSquelch$ = ""
'                         ELSE
'                           NodesToSquelch$ = MID$ (NodesToSquelch$, Squelched + 1)
'                        END IF
'                     ELSEIF Squelched > 1 THEN
'                        NodesToSquelch$ = LEFT$(NodesToSquelch$, Squelched - 1) + _
'                                            MID$ (NodesToSquelch$, Squelched + 1)
'                     END IF
'                     IF Squelched > 0 THEN
'                        CALL QuickTPut("Node " + MID$(ZOutTxt$(0), 2, 1) + " has been UNsquelched!", 1)
'                     END IF
'                  END IF
'                  IF LEN(ZOutTxt$(0)) > 2 THEN
'                     ZOutTxt$(0) = MID$(ZOutTxt$(0), 3)
'                   ELSE
'                     ZOutTxt$(0) = ""
'                  END IF
'                REM ** ADD NODE TO SQUELCH LIST **
'                ELSEIF LEFT$(ZOutTxt$(0), 1) = "!" THEN
'                  NodesToSquelch$ = NodesToSquelch$ + MID$(ZOutTxt$(0), 2, 1)
'                  CALL QuickTPut("Node " + MID$(ZOutTxt$(0), 2, 1) + " has been squelched!", 1)
'                  IF LEN(ZOutTxt$(0)) > 2 THEN
'                     ZOutTxt$(0) = MID$(ZOutTxt$(0), 3)
'                   ELSE
'                     ZOutTxt$(0) = ""
'                  END IF
'               END IF
'               ChatHold$(CurrentNodeIndex) = ZOutTxt$(0) + SPACE$(72 - LEN(ZOutTxt$(0)))
'               CALL LockIt7 (CurrentNodeIndex, ZTrue)
'               LSET ChatInput$ = ChatHold$(CurrentNodeIndex)
'               IF PrivateMessage THEN
'                  LSET PrivateFor$ = MKI$(PrivateMessage)  'PRIVATE
'                ELSE
'                  LSET PrivateFor$ = MKI$(0)  'PUBLIC
'               END IF
'               CALL LockIt7 (CurrentNodeIndex, ZFalse)
'            END IF
'
'            CALL CheckCarrier
'            IF ZSubParm = -1 THEN
'               EXIT DO
'            END IF
'            CALL CheckTimeRemain(MinsRemaining)
'            IF ZSubParm = -1 THEN
'               EXIT DO
'            END IF
'            CALL CheckTime(ZAutoLogoff!, TempElapsed!, 1)
'            IF TempElapsed! <=0 THEN
'               ZWaitExpired = ZTrue
'               EXIT DO
'            END IF
'
'         LOOP
'         CALL LockIt7 (CurrentNodeIndex, ZTrue)
'         LSET ChatInput$ = SPACE$(72)
'         LSET ChatActivity$ = "I"
'         CALL LockIt7 (CurrentNodeIndex, ZFalse)
'         CLOSE 7
'      END IF
'      ZActiveMessageFile$ = WasA1$
'      END SUB
'
'63580 ' $SUBTITLE: 'PageEm - attempt to page another user to chat'
' $PAGE
'
'  NAME    -- PageEm
'
'  INPUTS  -- SHOW.ONLY        Show whos is on the other nodes only
'             NodesInSystem  Number of nodes in this system
'
'  OUTPUTS -- HasPaged        -1 exit chat mode
'                               0 don't check for reply to page
'                               1 - NodesInSystem check for page reply
'
'  PURPOSE -- Page another user on the system and set up for a reply
'             from the other user
'
'      SUB PageEm(CurrentNodeIndex, HasPaged, NodesInSystem, ShowOnly) STATIC
'      CALL WhosOn (NodesInSystem)
'      CALL SkipLine(1)
'      IF ShowOnly THEN
'         EXIT SUB
'      END IF
'      ZOutTxt$ = "Which node do you wish to page (1 -" + STR$(NodesInSystem) + ")" + PRESS.ENTER$
'      ZSubParm = 1
'      CALL TGet
'      IF ZWasQ = 0 THEN
'         HasPaged = -1
'         EXIT SUB
'      END IF
'      CALL CheckInt(ZUserIn$(1))
'      FIELD 7, 1 AS ChatActivity$, _
'               2 AS PagingNode$,   _
'               2 AS PrivateFor$,   _
'              72 AS ChatInput$,    _
'              31 AS ChatName$,     _
'               1 AS InTrueChat$
'      IF ZTestedIntValue > 0 AND ZTestedIntValue <= NodesInSystem AND _
'         ZTestedIntValue <> CurrentNodeIndex THEN
'         CALL QuickTPut("Hang on,  I'll let them know you wanna chat", 1)
'         CALL QuickTPut("If you don't get an answer within a couple minutes,", 1)
'         CALL QuickTPut("then you probably won't get an a answer", 1)
'         CALL LockIt7 (ZTestedIntValue, ZTrue)
'         IF ChatActivity$ = "A" THEN        'if other node already
'            IF InTrueChat$ = "A" THEN         'can't page 'em if in true chat
'               CALL QuickTPut("The node you requested is in a private chat!", 1)
'               HasPaged = -1
'             ELSE
'               HasPaged = 0
'            END IF
'            EXIT SUB
'         END IF
'         LSET ChatActivity$ = "R"           'R means Request
'         LSET PagingNode$ = MKI$(CurrentNodeIndex)
'         HasPaged = ZTestedIntValue
'         CALL LockIt7 (ZTestedIntValue, ZFalse)
'       ELSE
'         HasPaged = -1
'      END IF
'      END SUB
'
'63590 ' $SUBTITLE: 'TrueChat - internode normal chat emulator'
' $PAGE
'
'  NAME    -- TrueChat
'
'  INPUTS  -- NodesInSystem  Number of nodes in this system
'
'  OUTPUTS -- HasPaged         -1 exit chat mode
'                               0 don't check for reply to page
'                               1 > NodesInSystem check for page reply
'
'  PURPOSE -- Page another user on the system and set up for a reply
'             from the other user
'
'      SUB TrueChat(CurrentNodeIndex, HasPaged, NodesInSystem) STATIC
'      PrivateFrom = 0
'      OtherNodeStatus$ = "I"
'      TrueChatIndexSave! = 0
'      OtherNodeInput$ = ""
'      FIELD 7, 1 AS ChatActivity$, _
'               2 AS PagingNode$,   _
'               2 AS PrivateFor$,   _
'              72 AS ChatInput$,    _
'              31 AS ChatName$,     _
'               1 AS InTrueChat$,   _
'               4 AS TrueChatIndex$
'      CALL LockIt7 (CurrentNodeIndex, ZTrue)
'      REM ** IF NOT ANSWERING A PAGE THEN... **
'      IF InTrueChat$ <> "Y" THEN
'         CALL PageEm(CurrentNodeIndex, HasPaged, NodesInSystem, 0)
'         IF HasPaged < 1 THEN
'            EXIT SUB
'         END IF
'       ELSE
'         HasPaged = CVI(PagingNode$)
'      END IF
'      CALL QuickTPut("TRUECh@ (TrueChat) mode!", 1)
'      CALL LockIt7 (CurrentNodeIndex, ZTrue)
'      LSET InTrueChat$ = "A"                     'TRUE CHAT MODE.. 2 NODES ONLY
'      LSET TrueChatIndex$ = MKS$(0)
'      CALL LockIt7 (CurrentNodeIndex, ZFalse)
'      PrivateFrom = HasPaged
'      ZCol = 0
'      SendRemote = ZRemoteEcho
'
'      DO
'
'         CALL LockIt7 (PrivateFrom, ZTrue)
'
'         IF HasPaged = PrivateFrom THEN
'            IF ChatActivity$ <> "R" THEN
'               IF ChatActivity$ = "N" THEN
'                  CALL QuickTPut("Paged user will probably NOT enter TRUECh@!", 1)
'                  HasPaged = 0
'                ELSEIF ChatActivity$ = "Y" THEN
'                  CALL QuickTPut("Paged user should be TRUECh@ing momentarily!", 1)
'                  HasPaged = 0
'               END IF
'            END IF
'         END IF
'
'         REM ** CHECK TO SEE IF THE OTHER GUY HAS ENTERED TRUECH@ **
'         IF OtherNodeStatus$ <> "A" AND InTrueChat$ = "A" THEN
'            CALL QuickTPut("The other user has joined TRUECh@!", 1)
'         END IF
'
'         REM ** SINCE ITS A PRIVATE CHAT. WE'LL EXIT ALONG WITH OTHER DUDE **
'         IF OtherNodeStatus$ = "A" AND InTrueChat$ = "I" THEN
'            CALL QuickTPut("The other user has exited TRUECh@!", 1)
'            EXIT DO
'         END IF
'
'         OtherNodeStatus$ = InTrueChat$
'         OtherNodeInput$  = LEFT$(ChatInput$, 1)
'
'         IF (CVS(TrueChatIndex$) > TrueChatIndexSave!) AND _
'            OtherNodeStatus$ = "A" THEN
'            IF OtherNodeInput$ = CHR$(8) THEN
'               CALL LPrnt(ZLocalBkSp$, 0)
'               IF SendRemote THEN
'                  CALL PutCom (ZBackSpace$)
'               END IF
'               ZCol = ZCol - 1
'             ELSEIF OtherNodeInput$ = ZCarriageReturn$ THEN
'               IF SendRemote THEN
'                  CALL PutCom(ZCarriageReturn$)
'               END IF
'               IF SendRemote AND ZLineFeeds THEN
'                  CALL PutCom(ZLineFeed$)
'               END IF
'               CALL LPrnt(ZCarriageReturn$, 0)
'               ZCol = 1
'             ELSE
'               IF SendRemote THEN
'                  CALL PutCom(OtherNodeInput$)
'               END IF
'               CALL LPrnt (OtherNodeInput$, 0)
'               ZCol = ZCol + 1
'            END IF
'            TrueChatIndexSave! = CVS(TrueChatIndex$)
'          ELSE
'            Key$ = ""
'            IF NOT ZLocalUser THEN
'               CALL EOFComm (ZChar%)
'              ELSE
'               ZChar% = -1
'            END IF
'            IF ZChar% <> -1 THEN          'if remote key in then get complete
'               CALL GetCom(Key$)
'              ELSE
'               Key$ = INKEY$
'            END IF
'            IF Key$ <> "" THEN
'               IF LEN(Key$) = 1 THEN
'                  IF Key$ = ZEscape$ THEN
'                     EXIT DO
'                   ELSE
'                     CALL LockIt7(CurrentNodeIndex, ZTrue)
'                     LSET ChatInput$ = Key$
'                     LSET TrueChatIndex$ = MKS$(CVS(TrueChatIndex$) + 1)
'                     CALL LockIt7(CurrentNodeIndex, ZFalse)
'                     IF Key$ <> CHR$(8) THEN
'                        CALL QuickTPut(Key$, 0)
'                      ELSE
'                        CALL LPrnt(ZLocalBkSp$, 0)
'                        IF (NOT ZLocalUser) AND SendRemote THEN
'                           CALL PutCom (ZBackSpace$)
'                        END IF
'                        ZCol = ZCol - 2
'                     END IF
'                     IF Key$ = ZCarriageReturn$ THEN
'                        IF SendRemote AND ZLineFeeds THEN
'                           CALL PutCom(ZLineFeed$)
'                        END IF
'                        ZCol = 0
'                     END IF
'                     ZCol = ZCol + 1
'                  END IF
'               END IF
'            END IF
'         END IF
'
'         IF ZCol > 72 THEN
'            CALL QuickTPut(ZCarriageReturn$, 0)
'            ZCol = 1
'         END IF
'
'      LOOP
'
'      CALL LockIt7 (CurrentNodeIndex, ZTrue)
'      LSET InTrueChat$ = "I"
'      LSET ChatInput$ = SPACE$(72)
'      CALL LockIt7 (CurrentNodeIndex, ZFalse)
'
'      END SUB
'
'
'
'******************** INSERTED AutoLogoff here ******************
'
' $SUBTITLE: 'AutoLogOff - Subroutine to  to log off after transfer'
' $PAGE
'
  SUB AutoLogOff STATIC
 ZAutoEnd = 0
  IF ZGetExtDesc = ZTrue THEN _
    EXIT SUB
 ZSubParm = 1
   ZOutTxt$ = CHR$(7)+ZFG1$+"Auto-"+_
        ZFG3$+"LogOff"+ZFG1$+" after the transfer "+ZEmphasizeOff$ +CHR$(7)
CALL QuickTPut(ZOutTxt$,0)
    ZOutTxt$ = "(Y,[N])"
    ZTurboKey = -ZTurboKeyUser
      CALL TGet
       IF NOT ZYes THEN _
     CALL SkipLine (1) : _
     EXIT SUB 
 ZAutoEnd = 1
 CALL SkipLine (1)
END SUB
