' $linesize:132
' $title: 'RBBSSUB5.BAS CPC17-1A, Copyright 1986 - 88 by D. Thomas Mack'
'  Copyright 1987 by D. Thomas Mack, all rights reserved.
'  Name ...............: RBBSSUB5.BAS
'  Written by .........: D. Thomas Mack
'  First Released .....: September 18, 1988
'  Subsequent Releases.:
'  Copyright ..........: 1986, 1987, 1988
'  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 RBBSSUB2.BAS, RBBSSUB3.BAS,
'                        RBBSSUB4.BAS and RBBSSUB5.BAS 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
'  FILESYS    20100   File System for RBBS-PC
'
'  $INCLUDE: 'RBBS-VAR.BAS'
'
' $SUBTITLE: 'FILESYS -- subroutine for RBBS-PC's file system'
' $PAGE
'
' SUBROUTINE NAME    -- FILESYS
'
' INPUT PARAMETERS   --       PARAMETER                 MEANING
'                       FILESYS.PARAMETER = 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
'
' OUTPUT PARAMETERS  -- FILESYS.PARAMETER = 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)
'
' SUBROUTINE PURPOSE -- TO HANDLE THE RBBS-PC FILE SYSTEM COMMANDS
'
      SUB FILESYS STATIC
      FF = FILESYS.PARAMETER
      FILESYS.PARAMETER = 1
      ON FF GOSUB 20119, _  ' HANDLER TO LIST COMMENTS TO SYSOP
                  20150, _  ' L)IST DIRECTORY COMMAND HANDLER
                  20180, _  ' D)OWNLOAD COMMAND HANDLER
                  20262, _  ' 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
      ON FILESYS.PARAMETER GOTO 21920, _ ' NORMAL EXIT
                                21570, _ ' RECYCLE TO TOP OR RBBS-PC
                                21580, _ ' PROCESS NEXT COMMAND
                                21590, _ ' DENY USER ACCESS
                                21600, _ ' HANDLE EXTENDED DESCRIPTIONS
                                21610, _ ' USER'S TIME EXCEEDED
                                21620    ' CARRIER DROPPED
20119 EC = 0
      GOTO 20122
'
' *****  SCAN DIRECTORIES (PRINT TEXT)  *****
'
'  (formerly lines 7000 to 7260 in RBBS-PC.BAS CPC16-1A
20120 A$ = "Scanning Directory " + _
           FILE.NAME.HOLD$ + _
           " for " + _
           RS$
      GOSUB 21650
      IF FILESYS.PARAMETER > 1 THEN _
         RETURN
      PG = TRUE
20122 CALL OPENWORK (FILE.NAME$)
      IF EC = 53 THEN _
         CALL UPDTCALR ("Missing File " + FILE.NAME$,2) : _
         A$ = "Missing file " + _
              FILE.NAME$ + _
              ". Please tell SYSOP" : _
         GOSUB 21650 : _
         RETURN
20124 CALL CARRIER
      IF EOF(2) OR _
         (SUBROUTINE.PARAMETER AND NOT LOCAL.USER) THEN _
         GOTO 20142
20126 CALL READDIR (1)
     IF EC <> 0 THEN _
        EL = 20126 : _
        GOTO 21900
     IF CK = 0 THEN _
        GOTO 20140
     IF LEN(A$) > 0 THEN IF ASC(A$) = 32 THEN _
        IF LAST.OK AND NOT EXTENDED.OFF THEN _
           GOTO 20140 _
        ELSE GOTO 20124
     LAST.OK = FALSE
20128 IF CK > 1 THEN _
         IF WILD.SEARCH THEN _
            A = INSTR(A$," ") : _
            IF A = 0 THEN _
               GOTO 20124 _
            ELSE Z$ = LEFT$(A$,A - 1) : _
                 CALL WILDFILE (RS$,Z$,XXX) : _
                 GOTO 20136_
         ELSE Z$ = A$ : _
              CALL ALLCAPS (Z$) : _
              XXX = (INSTR(Z$,RS$) = 0) : _
              GOTO 20136
20130 A = INSTR(9,MID$(A$,1,32),"/")
      IF A = 0 THEN _
         A = INSTR(9,MID$(A$,1,32),"-")
20132 IF A < 3 THEN _
         GOTO 20124
      IF INSTR("0123456789",MID$(A$,A - 1,1)) = 0 THEN _
         GOTO 20124
      A = A - 2
      WK$ = RIGHT$(MID$(A$,A,8),2) + _
            LEFT$(MID$(A$,A,8),2) + _
            MID$(MID$(A$,A,8),4,2)
      IF MID$(WK$,3,1) = " " THEN _
         MID$(WK$,3,1) = "0"
      IF MID$(WK$,5,1) = " " THEN _
         MID$(WK$,5,1) = "0"
20134 XXX = (WK$ < RS$)
20136 IF XXX THEN _
         GOTO 20124
      IF PG THEN _
         PG = FALSE : _
         CALL OPENWORK (FILE.NAME$) : _
         Q = 0 : _
         GOTO 20124
20138 IF PG THEN _
         GOTO 20124
20140 LAST.OK = TRUE
      GOSUB 21650
      IF FILESYS.PARAMETER > 1 THEN _
         RETURN
      CALL ASKMORE ("",TRUE,TRUE,LIST.INDEX,FALSE)
      IF NO THEN _
         EC = 0 : _
         RETURN
      IF NOT RET THEN _
         GOTO 20124
20142 Q = 0
      CLOSE 2
      CALL CARRIER
      IF SUBROUTINE.PARAMETER = -1 THEN _
         FILESYS.PARAMETER = 7
      RETURN
'
' *  L - COMMAND FROM FILES MENU (LIST DIRECTORY)                             *
'
20150 LIST.DIRECTORY = TRUE
      LIST.NEW = FALSE
      SEARCH.DATE$ = ""
      SEARCH.STRING$ = ""
      SEARCHING.ALL = FALSE
      SHOW.DIR.OF.DIR = NOT EXPERT.USER
      CK = 0
      IF Q > 1 THEN _
         CALL ALLCAPS (B$(2)) : _
         IF B$(2) = "L" THEN _
            SHOW.DIR.OF.DIR = TRUE _
         ELSE LIST.INDEX = 2 : _
              GOTO 20159
20158 IF LIST.NEW OR LIST.INDEX > 255 THEN _
         LIST.INDEX = 0 : _
         RETURN
      LIST.INDEX = 1
      CALL GETDIRS (SHOW.DIR.OF.DIR)
      IF Q = 0 THEN _
         RETURN
      SHOW.DIR.OF.DIR = FALSE
20159 CALL CONVDIRS (LIST.INDEX)
      QX = Q
20160 CALL CARRIER
      IF SUBROUTINE.PARAMETER = -1 THEN _
         FILESYS.PARAMETER = 7 : _
         RETURN
      IF LIST.INDEX <= QX THEN _
         GOTO 20161
      IF NO OR (FILE.NAME.HOLD$ = DIRECTORY.PREFIX$) THEN _
         REDIM A$(ADIM) : _
         REDIM B$(ADIM) : _
         GOTO 20158
      CALL QTPUT (EMPHASIZE.OFF$,0)
      A$ = "End list.  R)elist, [Q]uit, or download what"
      GOSUB 21660
      IF FILESYS.PARAMETER > 1 THEN _
         RETURN
      CALL ALLCAPS (B$(1))
      IF B$(1) = "R" THEN _
         LIST.INDEX = LIST.INDEX - 1 : _
         B$(LIST.INDEX) = A1$ : _
         GOTO 20161
      IF LEN(B$(1)) > 1 AND _
         USER.SECURITY.LEVEL >= OPT.SEC(19 - 20 * (MENU.INDEX = 6)) THEN _
         B = 1 : _
         GOSUB 20202 : _
         IF FILESYS.PARAMETER > 1 THEN _
            RETURN _
         ELSE CALL LINE25
      GOTO 20158
20161 IF INSTR(B$(LIST.INDEX),".") THEN _
         GOTO 20172
      VIOLATION$ = "List Dir. "
      Z$ = B$(LIST.INDEX)
      A = INSTR("E+E-E",Z$)
      IF A > 0 THEN _
         IF A = 5 THEN _
            EXTENDED.OFF = NOT EXTENDED.OFF : _
            GOTO 20175 _
         ELSE EXTENDED.OFF = (A > 2) : _
              GOTO 20175
      CALL ALLCAPS(Z$)
      FILE.NAME.HOLD$ = Z$
      A1$ = Z$
      IF Z$ = DIRECTORY.PREFIX$ THEN _
         GOTO 20164
      IN.FMS = FALSE
20162 FOR I = 2 TO QX
         A$(I) = B$(I)
      NEXT
      CALL FMS (Z$,SEARCH.STRING$,SEARCH.DATE$,IN.FMS, _
                CATEGORY.NAME$(),CATEGORY.CODE$(),CATEGORY.DESC$(),_
                DOWNLOAD.FLAG,CAT.FOUND,LIST.INDEX)
      WHILE DOWNLOAD.FLAG > 0 AND SUBROUTINE.PARAMETER > -1
         B = 1
         GOSUB 20202
         IF FILESYS.PARAMETER > 1 THEN _
            RETURN
         X$ = CATEGORY.CODE$(CAT.FOUND)
         CALL DISUPDIR (X$,SEARCH.STRING$,SEARCH.DATE$,DOWNLOAD.FLAG,LIST.INDEX)
         CALL CHKTREMAIN (TIME.REMAINING!)
         IF SUBROUTINE.PARAMETER = -1 THEN _
            FILESYS.PARAMETER = 6 : _
            RETURN
         CALL CARRIER
      WEND
      IF SUBROUTINE.PARAMETER = -1 THEN _
         FILESYS.PARAMETER = 7 : _
         RETURN
      FOR I = 2 TO QX
         B$(I) = A$(I)
      NEXT
      ACTIVE.FMS.DIRECTORY$ = ""
      IF IN.FMS THEN _
         GOTO 20175
      IF USER.SECURITY.LEVEL < MIN.SEC.TO.VIEW THEN _
         IF FILE.NAME.HOLD$ = UPLOAD.DIR.CHECK$ THEN _
            FILE.NAME.HOLD$ = "of uploads" : _
            GOTO 20172
      FILE.NAME.HOLD$ = B$(LIST.INDEX)
      IF LIMIT.SEARCH.TO.FMS THEN _
         GOTO 20166
      IF FILE.NAME.HOLD$ = "ALL" OR FILE.NAME.HOLD$ = "A" THEN _
         SEARCHING.ALL = TRUE : _
         DIR.INDEX = LIST.INDEX : _
         GOTO 21890
      CALL BADFILE (FILE.NAME.HOLD$,BAD.FILE.NAME.INDEX)
      ON BAD.FILE.NAME.INDEX GOTO 20163,20172,20176
20163 FILE.NAME$ = FILE.NAME.HOLD$
      CALL BADNAME (BAD.FILE.NAME.INDEX)
      ON BAD.FILE.NAME.INDEX GOTO 20164,20176
20164 IF FILE.NAME$ = UPLOAD.DIR.CHECK$ AND _
         USER.SECURITY.LEVEL >= MIN.SEC.TO.VIEW THEN _
            FILE.NAME$ = UPLOAD.PATH$ _
      ELSE FILE.NAME$ = DIRECTORY.PATH$
      FILE.NAME$ = FILE.NAME$ + _
                   FILE.NAME.HOLD$ + _
                   "." + _
                   DIRECTORY.EXTENTION$
      CALL GRAPHIC (USER.GRAPHIC.DEFAULT$)
20165 IF OK THEN _
         CALL READDIR (1) : _
         IF EC = 0 THEN _
            IF LEFT$(A$,4) = "\FMS" THEN _
               IN.FMS = TRUE : _
               ACTIVE.FMS.DIRECTORY$ = FILE.NAME$ : _
               GOTO 20162 _
            ELSE GOTO 20167
20166 FILE.NAME$ = DIRECTORY.PATH$ + _
                   FILE.NAME.HOLD$ + ".MNU"
      CALL FINDIT (FILE.NAME$)
      IF OK THEN _
         CALL BUFFILE (FILE.NAME$,LIST.INDEX) : _
         GOTO 20158
      IF ALTDIR.EXTENSION$ = "" THEN _
         GOTO 20172
      FILE.NAME$ = DIRECTORY.PATH$ + _
                   FILE.NAME.HOLD$ + _
                   "." + _
                   ALTDIR.EXTENSION$
      CALL GRAPHIC (USER.GRAPHIC.DEFAULT$)
      IF NOT OK THEN _
         GOTO 20172
20167 B$(0) = B$(LIST.INDEX)
      IF NOT LIST.NEW THEN _
         GOTO 20168
      GOSUB 20120
      IF FILESYS.PARAMETER > 1 THEN _
         RETURN
      GOTO 20170
20168 CALL BUFFILE(FILE.NAME$,LIST.INDEX)
      CALL CARRIER
      IF SUBROUTINE.PARAMETER = -1 THEN _
         FILESYS.PARAMETER = 7 : _
         RETURN
20170 IF LIST.INDEX > 255 THEN _
         LIST.INDEX = 0 : _
         RETURN
      B$(LIST.INDEX) = B$(0)
      GOTO 20175
20172 IF NOT SEARCHING.ALL THEN _
         A$ = "Directory " + _
              FILE.NAME.HOLD$ + _
              " not found!" : _
         GOSUB 21640 : _
         NO = TRUE : _
         IF FILESYS.PARAMETER > 1 THEN _
            RETURN
20175 LIST.INDEX = LIST.INDEX + 1
      GOTO 20160
20176 CALL SVIOLATION
      IF DENY.ACCESS THEN _
         FILESYS.PARAMETER = 4 : _
         RETURN
      GOTO 20172
'
' *  D - COMMAND FROM FILES MENU (SEARCH FOR FILE TO DOWNLOAD)                *
'
20180 IF Q > 1 THEN _
         B = 2 : _
         GOTO 20202
20200 A$ = "Download what file(s)"
      GOSUB 21660
      IF FILESYS.PARAMETER > 1 THEN _
         RETURN
      B = 1
      IF Q = 0 THEN _
         RETURN
20202 IF (TIME.LOCK AND 2) AND NOT TIME.LOCK.EXEMPT THEN _
         CALL TIMELOCK : _
         IF NOT OK THEN _
            RETURN
      LAST.DOWNLOAD = Q
      FIRST.DOWNLOAD = B
      COMMAND.TRANSFER$ = ""
      IF AUTODOWNLOAD.AVAILABLE THEN _
         COMMAND.TRANSFER$ = "X"
      AUTODOWNLOAD.IN.PROGRESS = AUTODOWNLOAD.AVAILABLE
      IF LAST.DOWNLOAD > FIRST.DOWNLOAD THEN _
         Z$ = B$(LAST.DOWNLOAD) : _
         CALL ALLCAPS(Z$) : _
         IF LEN (Z$) = 1 AND INSTR(LEFT$(DFLTXFER$,LEN(DFLTXFER$)-1),Z$) > 0 THEN _
            LAST.DOWNLOAD = LAST.DOWNLOAD - 1 : _
            COMMAND.TRANSFER$ = Z$ : _
            AUTODOWNLOAD.IN.PROGRESS = FALSE
      BATCH.BYTES# = 0
      BATCH.BLOCKS# = 0
      CALL KILLWORK (NODE.WORK.FILE$)
      EC = 0
      FOR DWN.INDEX = FIRST.DOWNLOAD TO LAST.DOWNLOAD
         GOSUB 20205
         IF FILESYS.PARAMETER > 1 THEN _
            DWN.INDEX = LAST.DOWNLOAD + 1
20203 NEXT
      IF FILESYS.PARAMETER > 1 THEN _
         RETURN
      BATCH.TRANSFER = FALSE
      COMMAND.TRANSFER$ = ""
      RETURN
20205 MARK.TIME = (DWN.INDEX = FIRST.DOWNLOAD OR NOT CONCAT.FILES)
      FILE.NAME$ = B$(DWN.INDEX)
      VIOLATION$ = "Download "
      IF PERSONAL.DOWNLOAD THEN _
         CALL BRKFNAME (FILE.NAME$,DR$,Y$,X$,TRUE) : _
         FILE.NAME.HOLD$ = Y$ + _
                           X$ : _
         GOTO 20235
      FILE.NAME.HOLD$ = FILE.NAME$
      CALL BADFILE (FILE.NAME$,BAD.FILE.NAME.INDEX)
      ON BAD.FILE.NAME.INDEX GOTO 20220,20231,20233
20220 CALL ROTORSDIR (FILE.NAME$,SUBDIR$(),SUBDIR.COUNT + _
                      ((USER.SECURITY.LEVEL < MIN.SEC.TO.VIEW) OR _
                       NOT CAN.DOWNLOAD.FROM.UP),MARK.TIME)
20225 IF OK THEN _
         GOTO 20235
20231 A$ = FILE.NAME.HOLD$ + _
           " not found!"
      CALL UPDTCALR (A$,2)
      IF AUTODOWNLOAD.IN.PROGRESS THEN _
         A$ = A$ + _
              " during AUTODOWNLOAD" : _
         GOSUB 21640 : _
         RETURN
      A$ = A$ + _
           " Correct name"+PRESS.ENTER.EXPERT$
      GOSUB 21660
      IF FILESYS.PARAMETER > 1 THEN _
         RETURN
      IF Q=0 THEN _
         RETURN
      B$(DWN.INDEX) = B$(1)
      GOTO 20205
20233 CALL SVIOLATION
      IF DENY.ACCESS THEN _
         FILESYS.PARAMETER = 4 : _
         RETURN
      GOTO 20231
20235 CALL BADNAME (BAD.FILE.NAME.INDEX)
      ON BAD.FILE.NAME.INDEX GOTO  20236,20245
20236 LINE.25$ = "(D) " + _
                 Z$
      IF AUTODOWNLOAD.IN.PROGRESS THEN _
         MID$(LINE.25$,2,1) = "A"
'
' *  TEST FOR DOWNLOAD SECURITY                                               *
'
      CALL OPENWORK (FILESEC.FILE$)
      IF EC = 53 THEN _
         CALL UPDTCALR ("Missing file " + FILESEC.FILE$,2) : _
         GOTO 20247
20242 IF EOF(2) THEN _
         GOTO 20247
      CALL READPARMS (WORK.ARA$(),3,1)
      IF EC <> 0 THEN _
         EL = 20242 : _
         GOTO 21900
20243 CALL WILDFILE (WORK.ARA$(1),Z$,OK)
      IF NOT OK THEN _
         GOTO 20242
20244 IF USER.SECURITY.LEVEL < VAL(WORK.ARA$(2)) THEN _
         GOTO 20245
      FILE.PASSWORD$ = WORK.ARA$(3)
      IF FILE.PASSWORD$ = "" THEN _
         GOTO 20247
      CALL ALLCAPS (FILE.PASSWORD$)
      IF FILE.PASSWORD$ = PASSWORD$ THEN _
         GOTO 20247
      A$ = "Enter PASSWORD to download " + _
           FILE.NAME$
      GOSUB 21660
      IF FILESYS.PARAMETER > 1 THEN _
         RETURN
      IF Q = 0 THEN _
         RETURN
      CALL ALLCAPS (B$(1))
      IF B$(1) = FILE.PASSWORD$ THEN _
         GOTO 20247
20245 VIOLATION$ = "DownLoad " + _
                   FILE.NAME$
20246 CALL SVIOLATION
      IF DENY.ACCESS THEN _
         FILESYS.PARAMETER = 4
      RETURN
20247 DF = 0
      CALL BRKFNAME (FILE.NAME$,DR$,X$,EXTENTION$,FALSE)
      IF AUTODOWNLOAD.IN.PROGRESS THEN _
         A$ = "Transferring -- " + _
              B$(DWN.INDEX) : _
         GOSUB 21640 : _
         IF FILESYS.PARAMETER > 1 THEN _
            RETURN
      IF EXTENTION$ = "" OR RELIABLE.MODE OR _
         COMMAND.TRANSFER$ > "A" OR (USER.TRANSFER.DEFAULT$ > "A" AND _
         INTERNAL.PROTO$ <> "N") THEN _
            GOTO 20248
      IF INSTR(".WRK.FW .ARC.EXE.COM.OBJ.WKS.LBR",EXTENTION$) OR _
         MID$(EXTENTION$,2,1) = "Q" OR _
         (REQUIRE.NON.ASCII AND EXTENTION$ = "BAS") THEN _
         CALL QTPUT ("Non-ASCII required for " + FILE.NAME.HOLD$,1) : _
         DF = TRUE
20248 A$ = ""
      IF BATCH.TRANSFER THEN _
         IF DWN.INDEX < LAST.DOWNLOAD THEN _
            GOTO 20260
      CALL XFERTYPE (2,TRUE)
      IF FF THEN _
         GOTO 20260
      CALL XFERTYPE (1,TRUE)
      IF SUBROUTINE.PARAMETER = -1 THEN _
         RETURN
20260 TRANSFER.FUNCTION = 1
      GOSUB 21790
      IF FILESYS.PARAMETER > 1 THEN _
         RETURN
      BATCH.TRANSFER = (BATCH.PROTO AND (LAST.DOWNLOAD > FIRST.DOWNLOAD))
      IF BATCH.TRANSFER AND COMMAND.TRANSFER$ = "" THEN _
         COMMAND.TRANSFER$ = FT$
      ON INSTR("AXCYN",INTERNAL.PROTO$) GOTO _
         20340, _              ' ASCII DOWNLOAD
         20290, _              ' XMODEM
         20290, _              ' XMODEM CRC
         20270, _              ' YMODEM
         21700                 ' NONE - CANCEL
'
' *  EXTERNAL PROTOCOL DOWNLOADS/UPLOADS                           *
'
20261 IF REQ.8.BIT THEN _
         IF NOT EIGHT.BIT THEN _
            GOSUB 20318 : _
            IF FILESYS.PARAMETER > 1 THEN _                          ' DTM0828
               RETURN _                                              ' DTM0828
            ELSE GOSUB 20992 : _                                     ' DTM0828
                 IF FILESYS.PARAMETER > 1 THEN _
                    RETURN
      IF TRANSFER.FUNCTION = 1 THEN _
         GOSUB 20750 : _
         CLOSE 2 : _                                                 ' DTM0828
         IF FILESYS.PARAMETER > 1 OR NOT OK THEN _
            RETURN                                                   ' DTM0828
      IF BATCH.TRANSFER THEN _
         IF DWN.INDEX < LAST.DOWNLOAD THEN _
            RETURN _
         ELSE BLOCKS.IN.FILE# = BATCH.BLOCKS# : _
              BYTES.IN.FILE# = BATCH.BYTES# : _
              NUM.DNLD.BYTS! = BATCH.BYTES# : _                      ' DTM0828
              GOSUB 20780 : _
              IF FILESYS.PARAMETER > 1 OR NOT OK THEN _
                RETURN                                               ' DTM0828
      IF AUTODOWNLOAD.IN.PROGRESS THEN _
         CALL SENDNAME : _
         IF ABORT THEN _
            DOWNLOAD.COMPLETED = FALSE : _
            GOSUB 21760 : _                                          ' DTM0828
            RETURN
      CALL TRANSFER
20262 CALL CARRIER
      IF SUBROUTINE.PARAMETER = -1 THEN _
         A$ = FAILURE.STRING$ : _
         GOTO 20264
      IF PRIVATE.DOOR THEN _
         COMMAND.TRANSFER$ = FT$ : _
         CALL XFERTYPE (2,TRUE) : _
         COMMAND.TRANSFER$ = ""
      CALL OPENWORK ("XFER-" + NODE.ID$ + ".DEF")
      IF EC <> 0 THEN _
         GOTO 20267
      CALL READPARMS (WORK.ARA$(), FAILURE.PARM, 1)
      IF EC <> 0 THEN _
         GOTO 20267
      CALL KILLWORK ("XFER-" + NODE.ID$ + ".DEF")
20264 IF PRIVATE.DOOR THEN _
         PRIVATE.DOOR = FALSE : _
         FILE.NAME$ = WORK.ARA$(1) : _
         CALL BRKFNAME (FILE.NAME$,X$,FILE.NAME.HOLD$,Y$,TRUE) : _
         FILE.NAME.HOLD$ = FILE.NAME.HOLD$ + _
                           Y$ : _
         SIZE.ONLY = TRUE : _
         CALL OPENWORK (FILE.NAME$) : _
         GOSUB 20760 : _
         IF FILESYS.PARAMETER > 1 THEN _
            RETURN
20265 IF TRANSFER.FUNCTION = 2 THEN _
         IF INSTR(WORK.ARA$(FAILURE.PARM),FAILURE.STRING$) <> 1 THEN _
            GOTO 20700 _
         ELSE GOTO 20730
      IF TRANSFER.FUNCTION = 1 THEN _
         DOWNLOAD.COMPLETED = (INSTR(WORK.ARA$(FAILURE.PARM),FAILURE.STRING$) <> 1)
      GOSUB 21760
      RETURN
'
' *  XFER FILE NOT FOUND                                                      *
'
20267 EL = 20262
      GOTO 21900

'
' *  YMODEM DOWNLOAD DRIVER                                                   *
'
20270 GOTO 20292
'
' *  XMODEM DOWNLOAD DRIVER                                                   *
'
20290 '
20292 GOSUB 20750
      IF FILESYS.PARAMETER > 1 OR NOT OK THEN _
         RETURN
      A1$ = "SEND"
      GOSUB 20320
      IF FILESYS.PARAMETER > 1 THEN _
         RETURN
      IF LOCAL.USER THEN _
         CALL QTPUT ("Protocol not available in local mode",1) : _
         RETURN
      IF AUTODOWNLOAD.IN.PROGRESS THEN _
         GOSUB 20294 : _
         IF ABORT THEN _
            RETURN
      GOSUB 21300
      IF FILESYS.PARAMETER > 1 THEN _
         RETURN
      A$ = ""
      GOTO 20390
20294 CALL SENDNAME
      RETURN
20318 A$ = "Please SWITCH to N,8,1 for binary transfer"
      GOSUB 21630
      IF FILESYS.PARAMETER > 1 THEN _
         RETURN
      CALL DELAYIT (3)
      RETURN
20320 IF NOT EIGHT.BIT THEN _
         GOSUB 20318 : _
         IF FILESYS.PARAMETER > 1 THEN _
            RETURN
20325 IF CHECKSUM THEN _
         NEGATIVE.ACKNOWLEDGE$ = CHR$(21) : _
         SOL = 132 _
      ELSE NEGATIVE.ACKNOWLEDGE$ = "C" : _
           SOL = 133
20330 IF AUTODOWNLOAD.IN.PROGRESS THEN _
         RETURN
      A$ = PROTO.PROMPT$ + _
            " " + A1$ + _
            " of " + _
            FILE.NAME.HOLD$ + _
            " ready.  <Ctrl X> aborts"
      GOSUB 21650
      RETURN
'
' *  ASCII DOWNLOAD DRIVER                                                    *
'
20340 IF DF THEN _
         A$ = "Switch to a non-ascii protocol" : _
         GOSUB 21650 : _
         RETURN
      GOSUB 20750
      IF FILESYS.PARAMETER > 1 OR NOT OK THEN _
         RETURN
      CALL OPENWORK (FILE.NAME$)
      IF (DWN.INDEX = FIRST.DOWNLOAD OR NOT CONCAT.FILES) THEN _
         A$ = "^X aborts.  ^S suspends ^Q resumes" : _
         GOSUB 21640 : _
         IF FILESYS.PARAMETER > 1 THEN _
            RETURN _
         ELSE A$ = PROTO.PROMPT$ + " SEND of " + _
              FILE.NAME.HOLD$ + _
              " ready. Press Any Key to start" : _
         TURBO.KEY = 2 : _
         GOSUB 21660 : _
         IF FILESYS.PARAMETER > 1 THEN _
            RETURN
20380 STOP.INTERRUPTS = FALSE
      TU = 0
      SWAP TU,PAGE.LENGTH
      CALL BUFFILE (FILE.NAME$,X)
      SWAP TU,PAGE.LENGTH
      NON.STOP = (PAGE.LENGTH < 1)
      IF STOP.FILE THEN _
         DOWNLOAD.COMPLETED = FALSE : _
         GOTO 20390
20381 IF (DWN.INDEX = LAST.DOWNLOAD OR NOT CONCAT.FILES) THEN _
         CALL QTPUT (CHR$(26),0) : _
         IF NOT LOCAL.USER AND SUBROUTINE.PARAMETER = 0 THEN _
            FOR X = 1 TO 5 : _
               CALL PUTCOM (CHR$(7)) : _
               CALL DELAYIT (3) : _
            NEXT
20385 DOWNLOAD.COMPLETED = TRUE
20390 GOTO 21760
'
' *  U - COMMAND FROM FILES MENU (UPLOAD)                                     *
'
20395 GOSUB 21640
      IF FILESYS.PARAMETER > 1 THEN _
         RETURN
      A$ = "Correct name of file to upload" + _
           PRESS.ENTER.EXPERT$
      GOSUB 21660
      IF FILESYS.PARAMETER > 1 THEN _
         RETURN
      IF Q = 0 THEN _
         RETURN
      B$(ANS.INDEX) = B$(1)
      GOTO 20435
20400 CALL TIMEREMAIN (TIME.REMAINING!)
      Q! = TCA!
      FIRST.UPLOAD = 1
      IF Q > 1 THEN _
         FIRST.UPLOAD = 2 : _
         GOTO 20430
      GOSUB 20420
      GOTO 20430
20420 A$ = "Upload what file(s)"
      GOSUB 21660
      IF FILESYS.PARAMETER > 1 THEN _
         RETURN
      IF Q = 0 THEN _
         RETURN
      RETURN
'
' *  SEARCH FOR DUPLICATE FILENAME                                            *
'
20430 LAST.UPLOAD = Q
      Z$ = B$(LAST.UPLOAD)
      IF LEN(Z$) = 1 THEN _
         CALL ALLCAPS (Z$) : _
         IF INSTR(DFLTXFER$,Z$) > 0 THEN _
            LAST.UPLOAD = LAST.UPLOAD - 1 : _
            COMMAND.TRANSFER$ = Z$
      FOR ANS.INDEX = FIRST.UPLOAD TO LAST.UPLOAD
         GOSUB 20435
         IF FILESYS.PARAMETER > 1 THEN _
            ANS.INDEX = LAST.UPLOAD + 1
      NEXT
      COMMAND.TRANSFER$ = ""
      RETURN
20435 FILE.NAME.HOLD$ = B$(ANS.INDEX)
      CALL ALLCAPS(FILE.NAME.HOLD$)
      FILE.NAME$ = FILE.NAME.HOLD$
      VIOLATION$ = "Upload "
      IF INSTR(FILE.NAME$,":") OR _
         INSTR(FILE.NAME$,"\") OR _
         INSTR(FILE.NAME$,"/") THEN _
         GOTO 20451
      CALL BADFILE (FILE.NAME$,BAD.FILE.NAME.INDEX)
      ON BAD.FILE.NAME.INDEX GOTO 20440,20451,20515
20440 CALL ROTORSDIR (FILE.NAME$,SUBDIR$(),SUBDIR.COUNT,TRUE)
20450 IF OK THEN _
         GOTO 20452
      GOTO 20475
20451 A$ = "Invalid file name"
      GOTO 20395
20452 IF USER.SECURITY.LEVEL < OVERWRITE.SECURITY.LEVEL THEN _
         GOTO 20453
      A$ = "Overwrite file (Y,[N])"
      GOSUB 21660
      IF FILESYS.PARAMETER > 1 THEN _
         RETURN
      IF NOT YES THEN _
         GOTO 20453
      Z$ = FILE.NAME$
      CALL KILLWORK (FILE.NAME$)
      IF EC <> 0 THEN _
         EL = 20452 : _
         GOTO 21900
      GOTO 20475
20453 CLOSE 2
      IF USER.SECURITY.LEVEL < ADD.DIR.SECURITY THEN _
         CALL QTPUT ("Thanks, but we already have " + FILE.NAME.HOLD$,1) : _
         CALL UPDTCALR ("Upload duplicate " + FILE.NAME.HOLD$,1) : _
         RETURN
      A$ = "Add new directory entry (Y,[N])"
      TURBO.KEY = - TURBO.KEY.USER
      GOSUB 21660
      IF FILESYS.PARAMETER > 1 THEN _
         RETURN
      IF NOT YES THEN _
         RETURN
      ADDING.DESC.ONLY = TRUE
      GOSUB 20702
      RETURN
20475 Z$ = UPLOAD.DRIVE.FILE$
      CALL FINDFREE
      IF VAL(FREE.SPACE$) < 4096 THEN _
         CALL QTPUT ("No room for uploads.  Try tomorrow.",1) : _
         ANS.INDEX = LAST.UPLOAD + 1 : _
         RETURN
      A$ = "Upload disk has" + _
           FREE.SPACE$
      GOSUB 21640
      IF FILESYS.PARAMETER > 1 THEN _
         RETURN
      LINE.25$ = "(U) " + _
                 FILE.NAME.HOLD$
      SUBROUTINE.PARAMETER = 2
      CALL LINE25
      A$ = ""
      OK = TRUE
20477 CALL XFERTYPE (2,TRUE)
      IF FF THEN _
         GOTO 20500
      CALL XFERTYPE (1,TRUE)
      IF SUBROUTINE.PARAMETER = -1 THEN _
         RETURN
20500 TRANSFER.FUNCTION = 2
      AUTODOWNLOAD.IN.PROGRESS = FALSE
      GOSUB 21790
      IF FILESYS.PARAMETER > 1 THEN _
         RETURN
      ON INSTR("AXCYN",INTERNAL.PROTO$) GOTO _
         20560, _         ' ASCII UPLOAD
         20542, _         ' XMODEM
         20542, _         ' XMODEM CRC
         20542, _         ' YMODEM
         20735            ' NONE - CANCEL
      GOTO 20261
20510 D$ = "<Esc> by SYSOP aborts"
      GOSUB 21710
      RETURN
20515 CALL SVIOLATION
      IF DENY.ACCESS THEN _
         FILESYS.PARAMETER = 4 : _
         RETURN
      GOTO 20420
'
' *  XMODEM/YMODEM UPLOAD DRIVER
'
20542 A1$ = "RECEIVE"
      GOSUB 20320
      IF FILESYS.PARAMETER > 1 THEN _
         RETURN
      OK = TRUE
      GOSUB 20860
      IF FILESYS.PARAMETER > 1 THEN _
         RETURN
      IF OK THEN _
         GOTO 20700
      GOTO 20730
'
' *  ASCII UPLOAD                                                             *
'
20560 LINE.ACK = (DEFAULT.LINE.ACK$ <> "")
      IF LINE.ACK THEN _
         A$ = "Acknowledge each line ([Y],N)" : _
         TURBO.KEY = - TURBO.KEY.USER : _
         GOSUB 21660 : _
         LINE.ACK = NOT NO : _
         IF FILESYS.PARAMETER > 1 THEN _
            RETURN
      CALL QTPUT("Transfer MUST end with a <Ctrl-K>",1)
      CALL QTPUT(PROTO.PROMPT$+" RECEIVE of " + FILE.NAME.HOLD$ + " ready",1)
      OK = FALSE
      XOFF = FALSE
      CALL OPENOUTW(FILE.NAME$)
      IF EC <> 0 AND EC <> 53 THEN _
         EL = 20560 : _
         GOTO 21900
      GOSUB 20510
      IF FILESYS.PARAMETER > 1 THEN _
         RETURN
20600 CALL EOFCOMM (CHAR%)
      WHILE CHAR% <> -1
         CALL CARRIER
         IF SUBROUTINE.PARAMETER THEN _
            FILESYS.PARAMETER = 7 : _
            RETURN
         IF NOT FOSSIL THEN _
            IF LOF(3) < 512 THEN _
               CALL PUTCOM(XOFF$) : _
               XOFF = TRUE
20610    CALL FLUSHCOM (X$)
         IF SUBROUTINE.PARAMETER = -1 THEN _
            RETURN
         IF INSTR(X$,CHR$(11)) THEN _
            GOTO 20650
         OK = TRUE
20620    CALL PRINTWRK (X$)
         IF LINE.ACK THEN _
            IF INSTR(X$,CHR$(10)) > 0 THEN _
               CALL PUTCOM (DEFAULT.LINE.ACK$)
         IF EC <> 0 THEN _
            EL = 20620 : _
            GOTO 21900
         D$ = X$
         NUM.RETURNS = 0
         GOSUB 21720
         IF FILESYS.PARAMETER > 1 THEN _
            RETURN
20621    CALL FINDFUNC
         IF SUBROUTINE.PARAMETER < 0 THEN _
            FILESYS.PARAMETER = 2 : _
            RETURN
         IF KEY.PRESSED$ = ESCAPE$ THEN _
            GOTO 20745
         IF NOT OK THEN _
            GOTO 20670
      CALL EOFCOMM (CHAR%)
20630 WEND
      CALL CARRIER
      IF SUBROUTINE.PARAMETER THEN _
         FILESYS.PARAMETER = 7 : _
         RETURN
      IF XOFF THEN _
         XOFF = FALSE : _
         CALL PUTCOM (XON$) : _
         IF EC <> 0 THEN _
            EL = 20630 : _
            GOTO 21900
      GOTO 20600
20650 X = INSTR(X$,CHR$(11))
      IF X = 1 THEN _
         IF NOT OK THEN _
            GOTO 20730 _
         ELSE GOTO 20700
      CALL PRNTWRKA (LEFT$(X$,X-1))
      IF EC <> 0 THEN _
         EL = 20650 : _
         GOTO 21900
      GOTO 20700
20670 A$ = XOFF$ + _
           "System error! Upload aborted <Ctrl-K> continues"
20675 GOSUB 21650
      IF FILESYS.PARAMETER > 1 THEN _
         RETURN
      CALL DELAYIT (3)
      CALL PUTCOM(XON$)
20680 CALL EOFCOMM (CHAR%)
      WHILE CHAR% <> -1
         CALL FLUSHCOM(X$)
         IF INSTR(X$,CHR$(11)) THEN _
            GOTO 20730
20685    CALL CARRIER
         IF SUBROUTINE.PARAMETER = -1 THEN _
            FILESYS.PARAMETER = 7 : _
            RETURN
      CALL EOFCOMM (CHAR%)
      WEND
      GOTO 20680
'
' *  UPDATE UPLOAD DIRECTORY                                                  *
'
20700 GOSUB 21780
      IF FILESYS.PARAMETER > 1 THEN _
         RETURN
20702 CALL UPDTUPLOAD (CATEGORY.NAME$(),CATEGORY.CODE$(), LINES.IN.MESSAGE)
      IF NOT GET.EXT.DESC THEN _
         GOTO 20710
      FT$ = "Extended Description for " + FILE.NAME.HOLD$
      SYSOP.COMMENT = TRUE
      MAX.MESSAGE.LINES = MAX.EXTENDED.LINES
      LL = RIGHT.MARGIN : _
      RIGHT.MARGIN = 30 + MAX.DESC.LEN : _
      GOTO 21600
20705 MAX.MESSAGE.LINES = MAX.MESSAGE.LINES.DEF
      RIGHT.MARGIN = LL
      GOTO 20702
20710 IF ADDING.DESC.ONLY THEN _
         ADDING.DESC.ONLY = FALSE : _
         RETURN
      IF BYTES.IN.FILE# > 0.0 THEN _
         GOTO 21770
20730 GOSUB 21780
      CALL QTPUT ("Upload aborted",1)
20735 CALL KILLWORK (FILE.NAME$)
      IF EC <>0 THEN _
         EL = 20736 : _
         GOTO 21900
      RETURN
'
' *  SYSOP ABORTED UPLOAD                                                     *
'
20745 A$ = XOFF$ + _
           "SYSOP aborted upload. Stop tranfer. <Ctrl-K> continues"
      GOTO 20675
'
' *  CALCULATE DOWNLOAD TIME ESTIMATE                                         *
'
20750 START.OF.HEADER$ = CHR$(1 - (INTERNAL.PROTO$ = "Y"))
      CALL OPENRSEQ (FILE.NAME$,MAX.BLOCK,DF,FLEN)
20760 BYTES.IN.FILE# = LOF(2)
      NUM.DNLD.BYTS! = LOF(2)
      OK = TRUE
      IF SIZE.ONLY THEN _
         SIZE.ONLY = FALSE : _
         RETURN
      BLOCKS.IN.FILE# = MAX.BLOCK
      IF BATCH.TRANSFER THEN _
         BATCH.BYTES# = BATCH.BYTES# + BYTES.IN.FILE# : _
         BATCH.BLOCKS# = BATCH.BLOCKS# + BLOCKS.IN.FILE# : _
         CALL OPENWRKA (NODE.WORK.FILE$) : _
         CALL PRNTWRKA (FILE.NAME$) : _
         RETURN
20780 A$ = "File Size    :"
      OK = TRUE
      IF BLOCK.SIZE > 0 THEN _
         A$ = A$ + _
              STR$(FIX(BLOCKS.IN.FILE#)) + _
              " blocks "
20785 BLOCKS.IN.FILE# = BLOCKS.IN.FILE# / _
                        VAL(MID$("0000030004501200240048009601920", -4 * BPS, 4))
      BLOCKS.IN.FILE# = BLOCKS.IN.FILE# * FLEN / SPEED.FACTOR!
      IF (DWN.INDEX > 1 AND CONCAT.FILES) THEN _
         RETURN
      A$ = A$ + _
           STR$(BYTES.IN.FILE#) + _
           " bytes"
      GOSUB 21650
      IF FILESYS.PARAMETER > 1 THEN _
         RETURN
      IF BYTES.IN.FILE# < 1 THEN _
         RETURN
20790 SUBROUTINE.PARAMETER = 2
      CALL LINE25
      A$ = "Transfer Time:" + _
         STR$(INT(BLOCKS.IN.FILE# / 60)) + _
         " min," + _
         STR$(INT(BLOCKS.IN.FILE# - (INT(BLOCKS.IN.FILE# / 60) * 60))) + _
         " sec (approx)"
      GOSUB 21650
      IF FILESYS.PARAMETER > 1 THEN _
         RETURN
20791 IF PERSONAL.DOWNLOAD THEN _
         RETURN
      CALL CHKTREMAIN (TIME.REMAINING!)
      IF SUBROUTINE.PARAMETER = -1 THEN _
         FILESYS.PARAMETER = 6 : _
         RETURN
      OK = TRUE
      IF (INT(BLOCKS.IN.FILE# / 60) + 1) > INT(TIME.REMAINING!) THEN _
         A$ = "Not enough time left!" : _
         CALL UPDTCALR (FILE.NAME$ + " " + A$,2) : _
         CALL QTPUT (A$,1): _
         A$ = "" : _
         OK = FALSE : _
         RETURN
      CALL CHECKRATIO (TRUE)
      RETURN
20810 CALL SETABORT (DELAY!,6)
20840 CALL EOFCOMM (CHAR%)
      IF CHAR% = -1 THEN _
         GOTO 20850
      CALL FLUSHCOM(Y$)
      RETURN
20850 CALL CHECKTIM (DELAY!)
      ON SUBROUTINE.PARAMETER GOTO 20840,20851
20851 Y$ = ""
      CALL CARRIER
      IF SUBROUTINE.PARAMETER = -1 THEN _
         FILESYS.PARAMETER = 7 : _
         RETURN
      RETURN
'
' *  XMODEM/YMODEM UPLOAD                                                     *
'
20860 GOSUB 20992
      IF FILESYS.PARAMETER > 1 THEN _
         RETURN
      IF NOT EIGHT.BIT THEN _
         GOSUB 21280 : _
         IF FILESYS.PARAMETER > 1 THEN _
            RETURN
20900 X$ = ""
      SEC = 1
      'CALL OPENOUTW (FILE.NAME$)
      IF FLEN > WRITE.BUF.DEF THEN _
         WRITE.BUF = FLEN _
      ELSE WRITE.BUF = WRITE.BUF.DEF
      CALL OPENRSEQ (FILE.NAME$,Y,DF,WRITE.BUF)
      IF EC <> 0 AND EC <> 53 THEN _
         EL = 20900 : _
         GOTO 21900
      FIELD #2, WRITE.BUF AS UPLOAD.RECORD$
      RECS.WRIT = 0
      NUM.IN.BUFF = 0
      CALL SETABORT (TRANSFER.ABORT!,WAIT.BEFORE.DISCONNECT)
      YY$ = " " + _
            CHR$(1) + _
            CHR$(2) + _
            END.TRANSMISSION$ + _
            CANCEL$
20903 CALL PUTCOM (NEGATIVE.ACKNOWLEDGE$)
20920 X = 1
20922 CALL CARRIER
      IF SUBROUTINE.PARAMETER < 0 THEN _
         FILESYS.PARAMETER = 7 : _
         RETURN
      CALL FINDFUNC
      IF KEY.PRESSED$ = ESCAPE$ THEN _
         GOSUB 20510 :_
         IF FILESYS.PARAMETER > 1 THEN _
            RETURN _
         ELSE GOTO 21240
      GOSUB 20810
      IF FILESYS.PARAMETER > 1 THEN _
         RETURN
20930 J = INSTR(YY$,LEFT$(Y$,1))
      ON J GOTO 20960,20999,20999,21220,21230
20960 IF Y$ <> "" THEN _
         GOSUB 21280 : _
         IF FILESYS.PARAMETER > 1 THEN _
            RETURN _
         ELSE CALL CHECKTIM (TRANSFER.ABORT!) : _
         ON SUBROUTINE.PARAMETER GOTO 20920,21230
20970 X = X + 1
      CALL DELAYIT (1)
      CALL PUTCOM (NEGATIVE.ACKNOWLEDGE$)
      IF X < 6 THEN _
         GOTO 20922
      D$ = "Upload Timeout"
      GOSUB 21710
      IF FILESYS.PARAMETER > 1 THEN _
         RETURN
      CALL CHECKTIM (TRANSFER.ABORT!)
      ON SUBROUTINE.PARAMETER GOTO 20990,21230
20990 GOTO 20920
'
' *  CHANGE TO 8 BIT FOR XMODEM                                               *
'
20992 GOSUB 20510
      IF FILESYS.PARAMETER > 1 THEN _
         FILESYS.PARAMETER = 2 : _
         RETURN
      IF NOT EIGHT.BIT THEN _
         PREV.LINE.CONTROL = INP (LINE.CONTROL.REGISTER) : _
         CALL DELAYIT (3) : _
         SWITCHED.TO.EIGHT = TRUE : _
         OUT LINE.CONTROL.REGISTER,3
20996 SO = 0
      RETURN
'
' *  EXPECTED BLOCK LENGTH. 132 FOR CHECKSUM, 133 FOR CRC, 1029 FOR YMODEM    *
'
20999 SOL = 896 * J - 1659 + CHECKSUM
      DATA.SOL = 128 - (SOL > 1024)*896
      GOTO 21020
'
' *  XMODEM/YMODEM UPLOAD                                                     *
'
21000 GOSUB 20810
      IF FILESYS.PARAMETER > 1 THEN _
         RETURN
      IF Y$ = "" THEN _
         D$ = "Upload Timeout" : _
         GOSUB 21710 : _
         IF FILESYS.PARAMETER > 1 THEN _
            RETURN _
         ELSE GOTO 21040
21020 X$ = X$ + _
           Y$
      IF LEN(X$) < SOL THEN _
         GOTO 21000
21040 IF LEN(X$) = SOL THEN _
         GOTO 21090
21050 IF LEN(X$) > SOL THEN _
         GOTO 21180
21060 IF X$ = END.TRANSMISSION$ THEN _
         GOTO 21220
21070 IF X$ = CANCEL$ THEN _
         GOTO 21230
21080 GOTO 21170
21090 JX = ASC(MID$(X$,2,1))
      IF SEC = JX THEN _
         GOTO 21100
      IF SEC > JX THEN _
         CALL PUTCOM (ACKNOWLEDGE$) : _ 'RIGHT$(ACKC$,1 - (JX = 0))) : _
         GOTO 21150
      GOTO 21200
21100 IF (SEC XOR 255) <> ASC(MID$(X$,3,1)) THEN _
         GOTO 21210
21110 IF CHECKSUM THEN _
         WK$ = MID$(X$,4,128) : _
         GOSUB 21750 : _
         IF FILESYS.PARAMETER > 1 THEN _
            RETURN _
         ELSE IF XMODEM.CHECKSUM <> ASC(MID$(X$,132,1)) THEN _
            GOTO 21190 _
         ELSE GOTO 21120
      WK$ = MID$(X$,4)
      GOSUB 21750
      IF FILESYS.PARAMETER > 1 THEN _
         RETURN
21113 IF CRC.VALUE <> 0 THEN _
         GOTO 21191
21120 SO = SO + 1
      CALL PUTCOM (ACKNOWLEDGE$)
21131 IF NUM.IN.BUFF >= WRITE.BUF THEN _
         NUM.IN.BUFF = 0 : _
         CALL PUTWORK (UPLOAD.RECORD$,RECS.WRIT,WRITE.BUF) : _
         IF EC <> 0 THEN _
            EL = 21131 : _
            GOTO 21900
      MID$(UPLOAD.RECORD$,NUM.IN.BUFF+1,DATA.SOL) = WK$
      NUM.IN.BUFF = NUM.IN.BUFF + DATA.SOL
21145 SEC = 255 AND (SEC + 1)
      CALL QLPRNT ("OK Rec Blk #",SO)
21150 X$ = ""
      XMODEM.CHECKSUM = 0
      CALL SETABORT(TRANSFER.ABORT!,45)
      GOTO 20920
21170 A$ = "Short Blk #"
      GOTO 21212
21180 A$ = "Long Blk #"
      GOTO 21212
21190 A$ = "Chksum Error #"
      GOTO 21212
21191 A$ = "CRC Error"
      GOTO 21212
21200 A$ = "Blk # Error in #"
      JX = ASC(MID$(X$,2,1))
      IF SEC < JX THEN _
         GOTO 21212
      CALL PUTCOM (ACKNOWLEDGE$) ' RIGHT$(ACKC$,1 - (JX = 0)))
      GOTO 21150
21210 A$ = "Complement Error in #"
21212 GOSUB 21280
      IF FILESYS.PARAMETER > 1 THEN _
         RETURN
      CALL PUTCOM (NEGATIVE.ACKNOWLEDGE$)
      CALL LPRNT(LINE.FEED$ + A$ + STR$(SO + 1),0)
      GOTO 21150
21220 IF NUM.IN.BUFF < 1 THEN _
         GOTO 21225
      WK$ = LEFT$(UPLOAD.RECORD$,NUM.IN.BUFF)
      CALL OPENRSEQ (FILE.NAME$,MAX.BLOCK,DF,128)
      FIELD #2, 128 AS UPLOAD.RECORD$
      MAX.BLOCK = CDBL(RECS.WRIT) * WRITE.BUF / 128
      FOR I = 1 TO NUM.IN.BUFF/128
         CALL PUTWORK (MID$(WK$,128*I-127,128),MAX.BLOCK,128)
         IF EC > 0 THEN _
            EL = 21220 : _
            GOTO 21900
      NEXT
      CLOSE 2
21225 CALL PUTCOM (ACKNOWLEDGE$)
      GOTO 21250
21230 D$ = LINE.FEED$ + _
           "Transfer Aborted"
      GOSUB 21710
      IF FILESYS.PARAMETER > 1 THEN _
         RETURN
21240 CALL EOFCOMM (CHAR%)
      IF CHAR% <> -1 THEN _
         GOSUB 21280 : _
         IF FILESYS.PARAMETER > 1 THEN _
            RETURN _
         ELSE CALL DELAYIT (1) : _
         GOTO 21240
      CALL PUTCOM (CANCEL$ + CANCEL$)
      CALL DELAYIT (1)
      CALL EOFCOMM (CHAR%)
      IF CHAR% <> -1 THEN _
         GOTO 21240
      OK = FALSE
21250 EIGHT.BIT = TRUE
      RETURN
'
' *  CLEAR GARBAGE OUT OF COMMUNICATIONS BUFFER                               *
'
21280 CALL CARRIER
      IF SUBROUTINE.PARAMETER = -1 THEN _
         FILESYS.PARAMETER = 7 : _
         RETURN
      CALL EOFCOMM (CHAR%)
      IF CHAR% = -1 THEN _
         RETURN
21281 CALL FLUSHCOM(DF$)
      IF SUBROUTINE.PARAMETER = -1 THEN _
         RETURN
      GOTO 21280
'
' *  XMODEM/YMODEM DOWNLOAD
'
21300 GOSUB 20992
      IF FILESYS.PARAMETER > 1 THEN _
         RETURN
      SEC = 0
      GOSUB 21280
      IF FILESYS.PARAMETER > 1 THEN _
         RETURN
      NEGATIVE.ACKNOWLEDGE$ = CHR$(21)
      CALL SETABORT (TRANSFER.ABORT!,WAIT.BEFORE.DISCONNECT)
21303 FIELD 2,FLEN AS DOWNLOAD.RECORD$
'
' *  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(Y$)
         IF Y$ = CANCEL$ THEN _
            GOTO 21560
21380    CHECKSUM = (Y$ = NEGATIVE.ACKNOWLEDGE$)
         IF CHECKSUM THEN _
            FF = INSTR(INTERNAL.EQUIV$,"X") : _
            IF FF > 0 THEN _
               FT$ = MID$(DFLTXFER$,FF,1) : _
               GOTO 21480 _
            ELSE FT$ = "X" : _
                 GOTO 21480 _
         ELSE IF Y$ = "C" THEN _
                 GOTO 21480
         CALL EOFCOMM (CHAR%)
21390 WEND
      GOSUB 21460
      IF FILESYS.PARAMETER > 1 THEN _
         RETURN
      IF KEY.PRESSED$ = ESCAPE$ THEN _
         RETURN
      CALL CHECKTIM (TRANSFER.ABORT!)
      ON SUBROUTINE.PARAMETER GOTO 21350,21455
21410 CALL SETABORT (TRANSFER.ABORT!, WAIT.BEFORE.DISCONNECT)
'
' *  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 FILESYS.PARAMETER > 1 THEN _
         RETURN
      IF KEY.PRESSED$ = ESCAPE$ THEN _
         RETURN
      CALL CHECKTIM (TRANSFER.ABORT!)
      ON SUBROUTINE.PARAMETER GOTO 21415,21455
21420 CALL GETCOM(Y$)
      IF Y$ = ACKNOWLEDGE$ THEN _
         GOTO 21470
21440 IF Y$ <> NEGATIVE.ACKNOWLEDGE$ THEN _
         GOTO 21450
21443 D$ = LINE.FEED$ + _
         "Error -> retrans #" + _
         STR$(SO)
      GOSUB 21710
      IF FILESYS.PARAMETER > 1 THEN _
         RETURN
21445 SO = SO - 1
      GOTO 21490
21450 IF Y$ = CANCEL$ THEN _
         IF HAVE.A.CANCEL THEN _
            GOTO 21560 _
         ELSE HAVE.A.CANCEL = TRUE
      CALL CHECKTIM (TRANSFER.ABORT!)
      ON SUBROUTINE.PARAMETER GOTO 21415,21455
21455 D$ = "Download timeout"
      GOSUB 21710
      IF FILESYS.PARAMETER > 1 THEN _
         RETURN
      GOTO 21560
21460 CALL CARRIER
      CALL FINDFUNC
      IF SUBROUTINE.PARAMETER < 0 THEN _
         FILESYS.PARAMETER = 7 : _
         RETURN
      IF KEY.PRESSED$ = ESCAPE$ THEN _
         GOTO 21540
      RETURN
'
' *  DISPLAY BLOCK SENT OK AND THEN READ IN NEXT RECORD FROM DISK TO DOWNLOAD *
'
21470 CALL QLPRNT ("OK Sent Blk #",SO)
21480 IF LOC(2) => MAX.BLOCK THEN _
         GOTO 21530
      CALL GETWORK (FLEN)
      IF EC <> 0 THEN _
         EL = 21480 : _
         GOTO 21900
      SEC = 255 AND (SEC + 1)
      GOTO 21490
'
' *  ROUTINE TO WRITE OUT AN "XMODEM" OR "YMODEM" RECORD TO THE COMM. PORT    *
'
21490 SO = SO + 1
      CALL PUTCOM (START.OF.HEADER$ + CHR$(SEC) + CHR$(SEC XOR 255))
      CALL PUTCOM (DOWNLOAD.RECORD$)
      HAVE.A.CANCEL = FALSE
21503 WK$ = DOWNLOAD.RECORD$
21504 GOSUB 21750
      IF FILESYS.PARAMETER > 1 THEN _
         RETURN
21510 IF CHECKSUM THEN _
         CALL PUTCOM(CHR$(XMODEM.CHECKSUM)) _
      ELSE CALL PUTCOM(CHR$(CRC.HIGH) + CHR$(CRC.LOW))
      GOSUB 21280
      IF FILESYS.PARAMETER > 1 THEN _
         RETURN
      GOTO 21410
'
' *  END-OF-FILE FOR XMODEM DOWNLOADS -- 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 (END.TRANSMISSION$)
      X = 1
21531 GOSUB 20810
      IF FILESYS.PARAMETER > 1 THEN _
         RETURN
      IF INSTR(Y$,ACKNOWLEDGE$) THEN _
         GOTO 21550
      CALL FINDFUNC
      IF SUBROUTINE.PARAMETER < 0 THEN _
         FILESYS.PARAMETER = 2 : _
         RETURN
      IF KEY.PRESSED$ = ESCAPE$ THEN _
         GOSUB 21540 : _
         GOTO 21545
      IF X < 10 THEN _
         X = X + 1 : _
         GOTO 21531
      DOWNLOAD.COMPLETED = FALSE
      GOTO 21230
21540 GOSUB 20510
      IF FILESYS.PARAMETER > 1 THEN _
         RETURN
      RETURN
21545 Y$ = CANCEL$
      CALL PUTCOM (CANCEL$ + CANCEL$ + CANCEL$)
      DOWNLOAD.COMPLETED = FALSE
      GOTO 21250
21550 DOWNLOAD.COMPLETED = TRUE
      GOTO 21250
21560 DOWNLOAD.COMPLETED = FALSE
      D$ = LINE.FEED$ + _
           "Caller aborted trans"
      GOSUB 21710
      IF FILESYS.PARAMETER > 1 THEN _
         RETURN
      GOTO 21545
'
' Exit to main-line RBBS-PC and go to handle exit (line  202)
'
21570 FILESYS.PARAMETER = 2
      GOTO 21920
'
' Exit to main-line RBBS-PC and go to command processing (line 1200)
'
21580 FILESYS.PARAMETER = 3
      GOTO 21920
'
' Exit to main-line RBBS-PC and deny the user access (line 1380)
'
21590 FILESYS.PARAMETER = 4
      GOTO 21920
'
' Exit to put in extended description and then return (line 2008)
'
21600 FILESYS.PARAMETER = 5
      GOTO 21920
'
' Exit to main-line RBBS-PC because time limit exceeded (line 10553)
'
21610 FILESYS.PARAMETER = 6
      GOTO 21920
'
' Exit to main-line RBBS-PC because loss of carrier (line 10595)
'
21620 FILESYS.PARAMETER = 7
      GOTO 21920
'
' STANDARD ENTRY FOR RBBS-PC'S COMMON TERMINAL OUTPUT ROUTIN
'
' Modeled on lines 12975 to 12983 in RBBS-PC.BAS
21630 SUBROUTINE.PARAMETER = 1
      GOTO 21655
21640 SUBROUTINE.PARAMETER = 3
      GOTO 21655
21650 SUBROUTINE.PARAMETER = 5
21655 CALL TPUT
      IF SUBROUTINE.PARAMETER < 0 THEN _
         FILESYS.PARAMETER = 2 : _
         RETURN
      IF SUBROUTINE.PARAMETER = 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 SUBROUTINE.PARAMETER = 1
      CALL TGET
      IF SUBROUTINE.PARAMETER < 0 THEN _
         FILESYS.PARAMETER = 2
      RETURN
21700 EC = 0
      RETURN
'
' **** COMMON LOCAL DISPLAY PRINT ****
'
'  (formerly lines 1315 to 1320 in RBBS-PC.BAS CPC16-1A
21710 NUM.RETURNS = 1
21720 CALL LPRNT (D$,NUM.RETURNS)
      RETURN
'
' *  XMODEM / CRC INTERFACE                                                   *
'
'  (formerly line 46000 in RBBS-PC.BAS CPC16-1A
21750 XMODEM.CHECKSUM = 0
      CRC.VALUE = 0
      CALL XMODEM(WK$,XMODEM.CHECKSUM,CRC.VALUE,CRC.HIGH,CRC.LOW)
      RETURN
'
' * UPDATE DOWNLOAD STATISTICS                                                *
'
'  (formerly lines 50600 to 50614 in RBBS-PC.BAS CPC16-1A
21760 GOSUB 21780
      IF FILESYS.PARAMETER > 1 THEN _
         RETURN
      IF NOT DOWNLOAD.COMPLETED THEN _
         DF$ = " Aborted" _
      ELSE CALL LOGDOWN (PERSONAL.DOWNLOAD,DWN.INDEX) : _
           DOWNLOADS = DOWNLOADS + 1 : _
           DLBYTES! = DLBYTES! + NUM.DNLD.BYTS! : _
           DL.TODAY! = DL.TODAY! + 1 : _
           BYTES.TODAY! = BYTES.TODAY! + NUM.DNLD.BYTS! : _
           NUM.DNLD.BYTS! = 0 : _
           CALL MUZAK (6) : _
           DF$ = " Downloaded" : _
           IF (DWN.INDEX = LAST.DOWNLOAD OR NOT CONCAT.FILES) THEN _
              CALL SKIPLINE (1) : _
              CALL QTPUT ("Download successful",1)
      IF AUTODOWNLOAD.IN.PROGRESS THEN _
         DF$ = " AUTO" + _
              MID$(N$,2)
      IF INSTR(N$,"Aborted") THEN _
         AUTODOWNLOAD.IN.PROGRESS = 0
      A$ = ""
21770 SUBROUTINE.PARAMETER = 2
      CALL AMORPM
      IF NOT BATCH.TRANSFER THEN _
         GOTO 21773
      CALL OPENWORK (NODE.WORK.FILE$)
      IF EC > 0 THEN _
         RETURN
      Q = 0
      WHILE NOT EOF(2)
         CALL READANY
         Q = Q + 1
         B$(Q) = A$
      WEND
21772 IF Q < 1 THEN _                                                ' DTM0828
         BATCH.TRANSFER = FALSE : _
         RETURN
      CALL OPENWORK (B$(Q))
      IF EC > 0 THEN _
         EC = 0 : _
         Q = Q - 1 : _
         GOTO 21772
      BYTES.IN.FILE# = LOF(2)
      FILE.NAME$ = B$(Q)
21773 CALL BRKFNAME (FILE.NAME$,DR$,X$,EXTENTION$,TRUE)
      Z$ = X$ + _
           EXTENTION$ + _
           DF$ + _
           " at " + _
           TIM$ + _
           " using " + _
           FT$ + _
           STR$(BYTES.IN.FILE#)
      CALL UPDTCALR (Z$,2)
      CALL CHECKRATIO (FALSE)
      IF BATCH.TRANSFER THEN _
         Q = Q - 1 : _
         GOTO 21772
21774 IF MENU.INDEX = 6 THEN _
         IF DOWNLOAD.COMPLETED THEN _
            A$ = X$ : _
            SUBROUTINE.PARAMETER = 5 : _
            CALL LIBRARY
      RETURN
'
' *****   TURN ON INTERMEDIATE ECHO   *****
'
'  (formerly line 50620 in RBBS-PC.BAS CPC16-1A
21780 IF ECHOER$ = "I" THEN _
         CALL SETECHO ("I")
'
' *  RESTORE COMMUNICATIONS AFTER SWITCH TO 8 BIT                             *
'
'  (formerly between lines 50620 and 50630 in RBBS-PC.BAS CPC16-1A
      IF SWITCHED.TO.EIGHT THEN _
         IF SWITCH.BACK THEN _
            OUT LINE.CONTROL.REGISTER, PREV.LINE.CONTROL : _
            CALL DELAYIT (3) : _
            EIGHT.BIT = FALSE : _
            SWITCHED.TO.EIGHT = FALSE
      RETURN
'
' *****  TURN OFF INTERMEDIATE ECHO  *****
'
'  (formerly line 50630 in RBBS-PC.BAS CPC16-1A
21790 IF ECHOER$ = "I" THEN _
         CALL SETECHO ("R")
      RETURN
'
' *****   DIRECTORY SEARCH   *****
'
'  (formerly lines 52900 to 52920 in RBBS-PC.BAS CPC16-1A
21800 CK = 2
      IF Q > 1 THEN _
         GOTO 21820
21810 A$ = "Search for (in file name/desc, wildcards name only, [ENTER] quits)"
      GOSUB 21660
      IF FILESYS.PARAMETER > 1 THEN _
         RETURN
      IF Q = 0 THEN _
         RETURN
      B$(2) = B$(1)
21820 RS$ = B$(2)
      WILD.SEARCH = (INSTR(RS$,"*") > 0 OR INSTR(RS$,"?") > 0)
      CALL ALLCAPS (RS$)
      SEARCH.STRING$ = RS$
      SEARCH.DATE$ = ""
      A1$ = RS$
      GOTO 21867
'
' *****  P - personal download  *****
'
'  (formerly lines 52950 to 52952 in RBBS-PC.BAS CPC16-1A
21850 IF PERSONAL.BEGIN < 1 OR PERSONAL.LEN < 1 THEN _
         RETURN
      DOWNLOAD.FLAG = 0
      PERSONAL.DOWNLOAD = TRUE
21852 CALL PERSFILE (MID$(USER.RECORD$,PERSONAL.BEGIN,PERSONAL.LEN),_
                     DOWNLOAD.FLAG)
      IF SUBROUTINE.PARAMETER = -1 THEN _
         RETURN
      IF Q <= 0 THEN _
         GOTO 21854
      CONCAT.FILES = PERSONAL.CONCAT
      STOP.INTERRUPTS = TRUE
      TIME.LOCK.EXEMPT = TRUE
      GOSUB 20202
      IF FILESYS.PARAMETER > 1 THEN _
         GOTO 21854
      TIME.LOCK.EXEMPT = FALSE
      CONCAT.FILES = FALSE
      GOTO 21852
21854 PERSONAL.DOWNLOAD = FALSE
      RETURN
'
' *  N - COMMAND FROM FILES MENU (DISPLAY NEW FILES SINCE LAST DIR DISPLAY)   *
'
'  (formerly lines 53000 to 53070 in RBBS-PC.BAS CPC16-1A
21860 CK = 1
      IF Q > 1 THEN _
         GOTO 21865
21862 A1$ = RIGHT$(LM$,4) +_
            LEFT$(LM$,2)
      A$ = "Files on/after (MMDDYY, [ENTER] = last on " + _
           A1$ + _
           ")"
      GOSUB 21660
      IF FILESYS.PARAMETER > 1 THEN _
         RETURN
      IF Q = 0 THEN _
         RS$ = LM$ : _
         GOTO 21866
      B$(2) = B$(1)
21865 IF LEN(B$(2)) <> 6 THEN _
         GOTO 21862
      A1$ = B$(2)
      RS$ = RIGHT$(A1$,2) + _
            LEFT$(A1$,4)
21866 SEARCH.DATE$ = RS$
      SEARCH.STRING$ = ""
21867 IF Q > 2 THEN _
         DIR.INDEX = 3 : _
         GOTO 21871
21870 CALL GETDIRS (NOT EXPERT.USER)
      IF Q = 0 THEN _
         RETURN
      DIR.INDEX = 1
21871 CALL CONVDIRS (DIR.INDEX)
      LAST.DIR.POS = Q
      LIST.DIRECTORY = TRUE
      LIST.NEW = TRUE
21875 Z$ = B$(DIR.INDEX)
      IF Z$ = "ALL" THEN _
         IF NOT LIMIT.SEARCH.TO.FMS THEN _
            GOTO 21890
21880 LIST.INDEX = DIR.INDEX
      QX = LIST.INDEX
      GOSUB 20160
      IF FILESYS.PARAMETER > 1 THEN _
         RETURN
      DIR.INDEX = DIR.INDEX + 1
      IF DIR.INDEX <= LAST.DIR.POS THEN _
         GOTO 21875
      LIST.NEW = FALSE
      SEARCH.STRING$ = ""
      SEARCH.DATE$ = ""
      RETURN
21890 G = DIR.INDEX
      LIST.INDEX = DIRECTORY.INDEX + 1
      CALL GETALL (DIRECTORY.PATH$ + DIRECTORY.PREFIX$ + "." + DIRECTORY.EXTENTION$,B$(),DIRECTORY.EXTENTION$,G)
      SEARCHING.ALL = TRUE
      QX = G
      LIST.INDEX = DIR.INDEX + 1
      GOTO 20160
'
' *  MAIN FILE SYSTEM ERROR TRAP - ALL ERRORS PASS THROUGH THIS ROUTINE
'
'  (formerly lines 13000 to 13500 in RBBS-PC.BAS CPC16-1A
21900 IF DEBUG THEN _
         A$ = "RBBSSUB5 DEBUG Error Trap Entry ERL=" + _
              STR$(EL) + _
              " ERR=" + _
              STR$(EC) : _
         IF PRINTER THEN _
            CALL PRINTIT(A$) _
         ELSE CALL LPRNT(A$,1)
      IF EL = 20126 AND EC = 53 THEN _
         GOTO 20142
      IF EL = 20242 AND EC = 62 THEN _
         CALL UPDTCALR (FILESEC.FILE$ + " bad format!",2) : _
         GOTO 20247
      IF EL = 20262 THEN _
         A$ = "<Download aborted>" : _
         DOWNLOAD.COMPLETED = FALSE : _
         GOTO 20390
      IF EL = 20452 AND EC = 53 THEN _
         GOTO 20451
      IF EL = 20560 AND EC = 67 THEN _
         GOTO 20451
      IF EL = 20560 AND EC = 70 THEN _
         IF VAL(FREE.SPACE$) > 1999 THEN _
            GOTO 20610 _
         ELSE CALL QTPUT ("No room for uploads. Try tomorrow.",1) : _
              GOTO 21700
      IF EL = 20620 THEN _
         GOTO 20670
      IF EL = 20650 THEN _
         GOTO 20670
      IF EL = 20736 AND EC = 53 THEN _
         GOTO 21700
      IF EL = 20900 AND EC = 75 THEN _
         GOTO 21230
      IF EL = 20900 AND EC = 70 THEN _
         CALL QTPUT ("No room for uploads. Try tomorrow.",1) : _
         GOTO 21230
      IF EL = 21131 OR EL = 21220 THEN _
         EC = 0 : _
         GOTO 21230
      IF EL = 21480 THEN _
         CALL LOGERROR : _
         IF EC = 57 THEN _
            CALL QTPUT("Error reading file.  Aborting download",1) : _
            DOWNLOAD.COMPLETED = FALSE : _
            GOTO 21230
21910 CALL LOGERROR
      CALL QTPUT (CALLERS.RECORD$,1)
      FILESYS.PARAMETER = 3
      RETURN
21920 ' EXIT RBBS-PC FILE SUBSYSTEM
      END SUB
