' $TITLE:    'ADDUSERS -- Copyright 1989, W. F. Muldrow'
'             Add users in the main user's file to other conferences
'             for which they have the appropriate security level
'
1010  DEF SEG
      WIDTH 80,25
      SCREEN 0,0,0
      KEY OFF
      DEFINT A-Z
      PRINT
      PRINT "ADD-USERS -- RBBS user file maintenance routine by Warren Muldrow"
      PRINT
1020  ON ERROR GOTO 9900
'
'     Read the RBBS-PC configuration file to find the main message/user files
'
1030  GOSUB 4000
      IF EC > 0 THEN _
         GOTO 1999
'
'     The ADDUSERS.DEF file will contain a list of conferences to which
'     users should be added
'
1040  OPEN "ADDUSERS.DEF" FOR INPUT SHARED AS 1
      IF EC > 0 THEN _
         GOTO 1999
'
'     Open the main users file as file # 3
'     Use it's drive and path as default for other user files
'
1050  GOSUB 9300
      IF EC > 0 THEN _
         GOTO 1999
      CALL BRKFNAME (MAIN.USER.FILE$, MAIN.DR$, NM$, X$, TRUE)
'
'     Read conference names from the ADDUSERS.DEF file until end of file
'
1100  IF EOF (1) THEN _
         GOTO 1999
'
'     Convert the conference name to file names for messages and users
'
1110  INPUT #1,CONF.NAME$
      CALL BRKFNAME (CONF.NAME$,DR$,NM$,X$,TRUE)
      IF DR$ = "" THEN _
         ACTIVE.MESSAGE.FILE$ = MAIN.DR$ + NM$ + "M" + X$ : _
         ACTIVE.USER.FILE$    = MAIN.DR$ + NM$ + "U" + X$ _
      ELSE _
         ACTIVE.MESSAGE.FILE$ = DR$ + NM$ + "M" + X$ : _
         ACTIVE.USER.FILE$    = DR$ + NM$ + "U" + X$
'
'     Open the conference message file and read the checkpoint record for:
'         Minimum security level for auto-add and
'         Number of active user records
'
1120  GOSUB 9200
1130  IF EC > 0 THEN _
         CALL BRKFNAME (ACTIVE.MESSAGE.FILE$, DR$, NM$, X$, TRUE) : _
         ACTIVE.MESSAGE.FILE$ = DR$ + NM$ + ".DEF" : _
         GOSUB 9200 : _
         IF EC > 0 THEN _
            PRINT "Unable to open message file for " + CONF.NAME$ : _
            GOTO 1100
1140  GET 2,1
1150  ACTIVE.USER.COUNT = VAL (MID$ (MESSAGE.RECORD$, 57, 5))
1160  ACTIVE.SEC.LEVEL  = CVI (MID$ (MESSAGE.RECORD$, 9, 2))
'
'     Open the conference user's file as file # 4
'     Determine the maximum number of users from the file size
'
1170  GOSUB 9400
1180  IF EC > 0 THEN _
         CALL BRKFNAME (ACTIVE.USER.FILE$, DR$, NM$, X$, TRUE) : _
         ACTIVE.USER.FILE$ = DR$ + NM$ + ".DEF" : _
         GOSUB 9400 : _
         IF EC > 0 THEN _
            PRINT "Unable to open user file for " + CONF.NAME$ : _
            CLOSE 2 : _
            GOTO 1100
1190  ACTIVE.USER.LIMIT = INT (ACTIVE.USER.SIZE * .95)
'
'     Display current activity to the viewer to prevent boredom
'
      PRINT
      PRINT CONF.NAME$ + "     " + ACTIVE.MESSAGE.FILE$ + "     " + _
            ACTIVE.USER.FILE$ + "     Minimum security"; ACTIVE.SEC.LEVEL
      PRINT
'
'     Read all user records from the main user file
'     Empty records begin with a space or null (CHR$(32) or CHR$(0))
'     Skip empty records, and users with security level below the
'         minimum for auto-add
'
1200  FOR I = 1 TO MAIN.USER.SIZE
1210  GET 3,I
1220  IF ASC(MAIN.USER.NAME$) <= ASC(" ") THEN _
         GOTO 1310
      IF ACTIVE.SEC.LEVEL > CVI (MAIN.SECURITY.LEVEL$) THEN _
         GOTO 1310
'
'     Look for user in current conference.
'     Skip if found, or if an invalid record number is returned
'     Skip if the conference has become full
'     Otherwise add the record to the conference user file
'     Keep track of active user count for the message file checkpoint record
'
1230  GOSUB 2000
1240  IF FOUND OR USER.INDEX = 0 THEN _
         GOTO 1310
      NAME$ = MAIN.USER.NAME$
      CALL TRIMTRAIL (NAME$, " ")
1250  IF ACTIVE.USER.COUNT > ACTIVE.USER.LIMIT THEN _
         PRINT "No room to add " + NAME$ + " to " + CONF.NAME$ : _
         GOTO 1310
1260  LSET USER.RECORD$ = MAIN.USER.RECORD$
1270  LSET LAST.MESSAGE$ = MKI$ (0)
1280  PUT 4,USER.INDEX
1290  ACTIVE.USER.COUNT = ACTIVE.USER.COUNT + 1
1300  PRINT "     " + NAME$ + " security level"; _
            CVI (MAIN.SECURITY.LEVEL$); "added to " + CONF.NAME$
1310  NEXT I
'
'     Put the updated user count into the message file checkpoint record
'         and update the message file
'
1320  MID$ (MESSAGE.RECORD$, 57, 5) = STR$ (ACTIVE.USER.COUNT)
1330  PUT 2,1
1340  CLOSE 2, 4
      PRINT
1350  GOTO 1100
'
'     That's all, Folks
'
1999  PRINT "Processing ended normally."
      CLOSE 1, 2, 3, 4
      END
'
' FINDUSER - subroutine to search users file for a name
'            (stolen from RBBS-PC source)
'
2000  EC = 0
      FOUND = 0
      HASH.VALUE$ = SPACE$ (LEN.HASH)
      INDIV.VALUE$ = SPACE$ (LEN.INDIV)
      EMPTY.REC$ = HASH.VALUE$
      NEWUSER$ = LEFT$("NEWUSER  ",LEN.HASH + 2)
      IF START.HASH > 0 THEN _
         HASH.VALUE$ = MID$(MAIN.USER.RECORD$,START.HASH,LEN.HASH)
      IF START.INDIV > 0 THEN _
         INDIV.VALUE$ = MID$(MAIN.USER.RECORD$,START.INDIV,LEN.INDIV)
      IF HASH.VALUE$ = SPACE$(LEN(HASH.VALUE$)) THEN _
         RETURN
      X$ = HASH.VALUE$
      Y$ = INDIV.VALUE$
      CALL TRIMTRAIL (HASH.VALUE$, " ")
      CALL TRIMTRAIL (INDIV.VALUE$, " ")
2004  GOSUB 3000
      HASH.VALUE$ = X$
      INDIV.VALUE$ = Y$
      X$ = SPACE$ (LEN.HASH)
      Y$ = SPACE$ (LEN.INDIV)
      REUSE.INDEX = 0
      USER.INDEX = PRIME.HASH
2010  GET 4,USER.INDEX
2011  IF EC > 0 THEN _
         IF EC = 63 THEN _
            EC = 0 : _
            GOTO 2021 _
         ELSE _
            EC = 0 : _
            GOTO 2020
2012  IF START.HASH > 0 THEN _
         X$ = MID$(USER.RECORD$, START.HASH,  LEN.HASH)
2013  IF START.INDIV > 0 THEN _
         Y$ = MID$(USER.RECORD$, START.INDIV, LEN.INDIV)
2015  IF X$ = HASH.VALUE$ THEN _
         IF START.INDIV < 1 THEN _
            FOUND = TRUE : _
            GOTO 2022 _
         ELSE IF INSTR (Y$, INDIV.VALUE$) > 0 OR ASC(Y$) = ASC(" ") THEN _
            FOUND = TRUE : _
            GOTO 2022
2016  IF X$ = EMPTY.REC$ THEN _
         USER.INDEX = REUSE.INDEX - (REUSE.INDEX = 0) * USER.INDEX : _
         FOUND = FALSE : _
         GOTO 2022
2017  IF ASC(X$) = 0 OR INSTR(X$, NEWUSER$) > 1 THEN _
         IF REUSE.INDEX = 0 THEN _
            REUSE.INDEX = USER.INDEX
2020  USER.INDEX = USER.INDEX + SECOND.HASH
      IF USER.INDEX > ACTIVE.USER.SIZE - 1 THEN _
         USER.INDEX = USER.INDEX - ACTIVE.USER.SIZE
      GOTO 2010
2021  IF REUSE.INDEX = 0 THEN _
         REUSE.INDEX = USER.INDEX
      GOTO 2020
2022  RETURN
'
' HASHRBBS - subroutine to determine where to look for user
'            (Stolen from RBBS-PC)
'
3000  SECOND.HASH = (ASC (MID$ (HASH.VALUE$, 2, 1)) * 10 + 7) MOD _
                    ACTIVE.USER.SIZE
3010  PRIME.HASH = ((ASC (HASH.VALUE$) * 100 + _
                    ASC (MID$ (HASH.VALUE$, (LEN (HASH.VALUE$) / 2) + .1, 1)) _
                    * 10 + ASC (RIGHT$ (HASH.VALUE$, 1))) _
                    MOD ACTIVE.USER.SIZE) + 1
3020  RETURN
'
'     Program Initialization Routine
'            (Stolen from RBBS-PC)
'
4000  CRLF$ = CHR$(13) + CHR$(10)
      VERSION.ID$ = "CPC17.1D"
      TRUE = (1 = 1)
      FALSE = NOT TRUE
      CONFIG.FILENAME$ = "RBBS-PC.DEF"  ' Try config file for single node
      GOSUB 5000
      IF EC < 1 THEN _
         GOTO 4010
      CONFIG.FILENAME$ = "RBBS1PC.DEF"  ' Try config file for node 1
      GOSUB 5000
      IF EC > 0 THEN _
         PRINT "Unable to read RBBS-PC configuration file." : _
         EC = 999 : _
         GOTO 4020
4010  ACTIVE.MESSAGE.FILE$ = MAIN.MESSAGE.FILE$
      GOSUB 9200
      IF EC > 0 THEN _
         PRINT "Unable to open main message file " + MAIN.MESSAGE.FILE$ : _
         EC = 999 : _
         GOTO 4020
      CLOSE 2
4020  RETURN

'
' READDEF - subroutine to read RBBS-PC.DEF file
'            (Stolen from RBBS-PC)
'
5000  GOSUB 9100
      IF EC > 0 THEN _
         RETURN
5002  INPUT #2,DF$, _
               DOWNLOAD.DRIVES$, _
               SYSOP.PASSWORD.1$, _
               SYSOP.PASSWORD.2$, _
               SYSOP.FIRST.NAME$, _
               SYSOP.LAST.NAME$, _
               REQUIRED.RINGS, _
               START.OFFICE.HOURS, _
               END.OFFICE.HOURS, _
               MINUTES.PER.SESSION!, _
               DF, _
               DF, _
               UPLOAD.DIRECTORY$, _
               EXPERT.USER, _
               ACTIVE.BULLETINS, _
               PROMPT.BELL, _
               DF, _
               MENUS.CAN.PAUSE, _
               MENU$, _
               MENU$, _
               MENU$, _
               MENU$, _
               MENU$, _
               MENU$, _
               CONFERENCE.MENU$, _
               DF, _
               WELCOME.INTERRUPTABLE, _
               REMIND.FILE.TRANSFERS, _
               PAGE.LENGTH, _
               MAX.MESSAGE.LINES.DEF, _
               DOORS.AVAILABLE, _
               DF$, _
               MAIN.MESSAGE.FILE$, _
               MAIN.MESSAGE.BACKUP$
5003  INPUT #2,X$, _
               COMMENTS.FILE$, _
               MAIN.USER.FILE$, _
               WELCOME.FILE$, _
               NEWUSER.FILE$, _
               MAIN.DIRECTORY.EXTENTION$
5004  CALL BRKFNAME (X$,Y$,DF$,Z$,FALSE)
5005  IF DF$ <> "" THEN _
         CALLERS.FILE$ = X$
5006  INPUT #2,COM.PORT$, _
               BULLETINS.OPTIONAL, _
               MODEM.INIT.COMMAND$, _
               RTS$, _
               DF, _
               FG, _
               BG, _
               BORDER, _
               RBBS.BAT$ , _
               RCTTY.BAT$, _
               OMIT.MAIN.DIRECTORY$, _
               FIRST.NAME.PROMPT$, _
               HELP$, _
               HELP$, _
               HELP$, _
               HELP$, _
               BULLETIN.MENU$, _
               BULLETIN.PREFIX$, _
               DF$, _
               MESSAGE.REMINDER, _
               REQUIRE.NON.ASCII, _
               ASK.EXTENDED.DESC, _
               MAXIMUM.NUMBER.OF.NODES, _
               NETWORK.TYPE, _
               RECYCLE.TO.DOS, _
               DF, _
               DF, _
               TRASHCAN.FILE$
5007  INPUT #2,MINIMUM.LOGON.SECURITY, _
               DEFAULT.SECURITY.LEVEL, _
               SYSOP.SECURITY.LEVEL, _
               FILESEC.FILE$, _
               SYSOP.MENU.SECURITY.LEVEL, _
               CONFMAIL.LIST$, _
               MAXIMUM.VIOLATIONS, _
               OPT.SEC, _
               OPT.SEC, _
               OPT.SEC, _
               OPT.SEC, _
               OPT.SEC, _
               OPT.SEC, _
               OPT.SEC, _
               PASSWORDS.FILE$, _
               MAXIMUM.PASSWORD.CHANGES, _
               MINIMUM.SECURITY.FOR.TEMP.PASSWORD, _
               OVERWRITE.SECURITY.LEVEL, _
               DOORS.TERMINAL.TYPE, _
               MAX.PER.DAY
5008  INPUT #2,OPT.SEC, _
               OPT.SEC, _
               OPT.SEC, _
               OPT.SEC, _
               OPT.SEC, _
               OPT.SEC, _
               OPT.SEC, _
               OPT.SEC, _
               OPT.SEC, _
               OPT.SEC, _
               OPT.SEC, _
               OPT.SEC, _
               OPT.SEC, _
               OPT.SEC, _
               OPT.SEC, _
               OPT.SEC, _
               OPT.SEC, _
               OPT.SEC, _
               MIN.NEWCALLER.BAUD, _
               WAIT.BEFORE.DISCONNECT
5009  INPUT #2,OPT.SEC, _
               OPT.SEC, _
               OPT.SEC, _
               OPT.SEC, _
               OPT.SEC, _
               OPT.SEC, _
               OPT.SEC, _
               OPT.SEC, _
               OPT.SEC, _
               OPT.SEC, _
               OPT.SEC, _
               OPT.SEC, _
               OPT.SEC, _
               OPT.SEC, _
               OPT.SEC, _
               OPT.SEC, _
               OPT.SEC, _
               OPT.SEC, _
               OPT.SEC, _
               OPT.SEC, _
               OPT.SEC, _
               OPT.SEC, _
               OPT.SEC, _
               OPT.SEC, _
               UPLOAD.TIME.FACTOR!, _
               COMPUTER.TYPE, _
               REMIND.PROFILE, _
               RBBS.NAME$, _
               COMMANDS.BETWEEN.RINGS, _
               MNP.SUPPORT, _
               PAGING.PRINTER.SUPPORT$, _
               MODEM.INIT.BAUD$
5010  IF EC > 0 THEN _
         RETURN
5011  INPUT #2,TURN.PRINTER.OFF,_
               DIRECTORY.PATH$, _
               MIN.SEC.TO.VIEW, _
               LIMIT.SEARCH.TO.FMS, _
               DEFAULT.CATEGORY.CODE$, _
               DIR.CATEGORY.FILE$, _
               NEW.FILES.CHECK, _
               MAX.DESC.LEN, _
               SHOW.SECTION, _
               COMMANDS.IN.PROMPT, _
               NEWUSER.SETS.DEFAULTS, _
               HELP.PATH$, _
               HELP.EXTENSION$, _
               MAIN.COMMANDS$, _
               FILE.COMMANDS$, _
               UTIL.COMMANDS$, _
               GLOBAL.COMMANDS$, _
               SYSOP.COMMANDS$
5012  INPUT #2,RECYCLE.WAIT, _
               OPT.SEC, _
               OPT.SEC, _
               OPT.SEC, _
               OPT.SEC, _
               OPT.SEC, _
               OPT.SEC, _
               OPT.SEC, _
               LIBRARY.DRIVE$, _
               LIBRARY.DIRECTORY.PATH$, _
               LIBRARY.DIRECTORY.EXTENTION$, _
               LIBRARY.WORK.DISK.PATH$, _
               LIBRARY.MAX.DISK, _
               LIBRARY.MAX.DIRECTORY, _
               LIBRARY.MAX.SUBDIR, _
               LIBRARY.SUBDIR.PREFIX$, _
               LIBRARY.ARCHIVE.PATH$, _
               LIBRARY.ARCHIVE.PROGRAM$, _
               LIBRARY.COMMANDS$
5013  INPUT #2,UPLOAD.PATH$, _
               MAIN.FMS.DIRECTORY$, _
               ANS.MENU$, _
               REQUIRED.QUESTIONNAIRE$,_
               REMEMBER.NEW.USERS,_
               SURVIVE.NOUSER.ROOM,_
               PROMPT.HASH$,_
               START.HASH,_
               LEN.HASH,_
               PROMPT.INDIV$,_
               START.INDIV,_
               LEN.INDIV
5014  INPUT #2,BYPASS.MSGS, _
               MUSIC, _
               RESTRICT.BY.DATE, _
               DAYS.TO.WARN, _
               DAYS.IN.REGISTRATION.PERIOD, _
               CALLBACK.VERIFICATION, _
               RESTRICT.VALID.CMDS, _
               NEW.USER.DEFAULT.MODE, _
               NEW.USER.LINE.FEEDS, _
               NEW.USER.NULLS, _
               NEW.USER.BELL, _
               NEW.USER.CASE, _
               NEW.USER.MARGINS, _
               WRAP.CALLERS.FILE$, _
               REDIRECT.IO.METHOD, _
               GO.TO.SHELL, _
               HALT.ON.ERROR, _
               NEW.PUBLIC.MSGS.SECURITY, _
               NEW.PRIVATE.MSGS.SECURITY, _
               SECURITY.NEEDED.TO.CHANGE.MSGS, _
               SL.CATEGORIZE.UPLOADS, _
               BAUDOT, _
               TIME.TO.DROP.TO.DOS, _
               EXPIRED.SECURITY, _
               DTR.DROP.DELAY, _
               ASK.IDENTITY, _
               USE.EXTERNAL.XMODEM, _
               BUFFER.SIZE, _
               MLCOM, _
               SHOOT.YOURSELF, _
               F7.MESSAGE$, _
               NEW.USER.DEFAULT.PROTOCOL$, _
               NEW.USER.GRAPHICS$, _
               NET.MAIL$, _
               MAIN.DIRECTORY.NAME$, _
               PROTO.DEF$, _
               UPCAT.HELP$, _
               ALWAYS.STREW.TO$, _
               LAST.NAME.PROMPT$
5015  INPUT #2,PERSONAL.DRVPATH$, _
               PERSONAL.DIR$, _
               PERSONAL.BEGIN, _
               PERSONAL.LEN, _
               PERSONAL.PROTOCOL$, _
               PERSONAL.CONCAT , _
               PRIVATE.READ.SEC, _
               PUBLIC.READ.SEC, _
               SEC.CHANGE.MSG, _
               KEEP.INIT.BAUD, _
               MAIN.PUI$
5016  INPUT #2,DEFAULT.ECHOER$, _
               HOST.ECHO.ON$, _
               HOST.ECHO.OFF$
5017  INPUT #2,SWITCH.BACK, _
               DEFAULT.LINE.ACK$, _
               ALTDIR.EXTENSION$, _
               DIRECTORY.PREFIX$
5018  INPUT #2,DF,_
               MODEM.INIT.WAIT.TIME, _
               MODEM.COMMAND.DELAY.TIME
5019  INPUT #2,TURBO.RBBS, _
               SUBDIR.COUNT, _
               DF, _
               UPLOAD.TO.SUBDIR, _
               DF, _
               UPLOAD.SUBDIR$, _
               MIN.OLDCALLER.BAUD, _
               USE.EXTERNAL.YMODEM, _
               DISKFULL.GO.OFFLINE, _
               EXTENDED.LOGGING
5020  INPUT #2,MODEM.RESET.COMMAND$, _
               MODEM.COUNT.RINGS.COMMAND$, _
               MODEM.ANSWER.COMMAND$, _
               MODEM.GO.OFFHOOK.COMMAND$
5021  INPUT #2,DISK.FOR.DOS$, _
               DUMB.MODEM, _
               COMMENTS.AS.MESSAGES
5022  INPUT #2,LSB,_
               MSB,_
               LINE.CONTROL.REGISTER,_
               MODEM.CONTROL.REGISTER,_
               LINE.STATUS.REGISTER,_
               MODEM.STATUS.REGISTER
5023  INPUT #2,KEEP.TIME.CREDITS, _
               XON.XOFF, _
               ALLOW.CALLER.TURBO, _
               USE.DEVICE.DRIVER$, _
               PRELOG$, _
               NEW.USER.QUESTIONNAIRE$, _
               EPILOG$, _
               REGISTRATION.PROGRAM$, _
               QUES.PATH$, _
               USER.LOCATION$, _
               DF$, _
               DF$, _
               DF$, _
               ENFORCE.UPLOAD.DOWNLOAD.RATIOS, _
               SIZE.OF.STACK, _
               SECURITY.EXEMPT.FROM.EPILOG, _
               USE.BASIC.WRITES, _
               DOSANSI, _
               ESCAPE.INSECURE, _
               USE.DIR.ORDER, _
               ADD.DIR.SECURITY, _
               MAX.EXTENDED.LINES, _
               ORIG.COMMANDS$
5024  INPUT #2,LOGON.MAIL.LEVEL$, _
               MACRO.DRVPATH$, _
               MACRO.EXTENSION$, _
               EMPHASIZE.ON.DEF$, _
               EMPHASIZE.OFF.DEF$, _
               FG.1.DEF$, _
               FG.2.DEF$, _
               FG.3.DEF$, _
               FG.4.DEF$, _
               SECVIO.HLP$
5025  INPUT #2,FOSSIL
5026  INPUT #2,MAX.CARRIER.WAIT, _
               DF, _
               SMART.TEXT, _
               TIME.LOCK, _
               WRITE.BUF.DEF, _
               DF, _
               DF, _
               DF, _
               AUTOPAGE.DEF$
5029  CLOSE 2
      RETURN
'
' OPENWORK - subroutine to open RBBS-PC's work file (2)
'            (Stolen from RBBS-PC)
'
9100  CLOSE 2
      EC = 0
9110  OPEN CONFIG.FILENAME$ FOR INPUT ACCESS READ SHARED AS 2
9120  RETURN
'
'     Open a message file as file number 2
'            (Stolen from RBBS-PC)
'
9200  CLOSE 2
      EC = 0
9210  OPEN ACTIVE.MESSAGE.FILE$ FOR RANDOM _
           ACCESS READ WRITE _
           LOCK WRITE AS #2 LEN = 128
      IF EC > 0 THEN _
         GOTO 9240
9220  FIELD 2,128 AS MESSAGE.RECORD$
9230  IF LOF(2) = 0 THEN _
         EC = 999 : _
         CLOSE 2 : _
         KILL ACTIVE.MESSAGE.FILE$
9240  RETURN
'
'     OPENMASTER - subroutine to open the users file as #3
'            (Stolen from RBBS-PC)
'
9300  CLOSE 3
      EC = 0
9310  OPEN MAIN.USER.FILE$ FOR RANDOM _
           ACCESS READ _
           SHARED _
           AS 3 LEN = 128
9320  IF EC > 0 THEN _
         GOTO 9370
9330  I# = LOF(3)
9340  MAIN.USER.SIZE = FIX(I#/128)
9350  FIELD 3, 31 AS MAIN.USER.NAME$, _
               15 AS MAIN.PASSWORD$, _
                2 AS MAIN.SECURITY.LEVEL$, _
               14 AS MAIN.USER.OPTIONS$,  _
               24 AS MAIN.CITY.STATE$, _
                3 AS MAIN.MACHINE.TYPE$, _
                4 AS MAIN.TODAY.DL$, _
                4 AS MAIN.TODAY.BYTES$, _
                4 AS MAIN.DL.BYTES$, _
                4 AS MAIN.UL.BYTES$, _
               14 AS MAIN.LAST.DATE.TIME.ON$, _
                3 AS MAIN.LIST.NEW.DATE$, _
                2 AS MAIN.USER.DOWNLOADS$, _
                2 AS MAIN.USER.UPLOADS$, _
                2 AS MAIN.ELAPSED.TIME$
9360  FIELD 3,128 AS MAIN.USER.RECORD$
9370  RETURN
'
'     OPENUSER - subroutine to open the users file as #4
'            (Stolen from RBBS-PC)
'
9400  CLOSE 4
      EC = 0
9410  OPEN ACTIVE.USER.FILE$ FOR RANDOM _
           ACCESS READ WRITE _
           LOCK WRITE _
           AS 4 LEN = 128
9420  IF EC > 0 THEN _
         GOTO 9470
9430  I# = LOF(4)
9440  ACTIVE.USER.SIZE = FIX(I#/128)
9450  FIELD 4, 31 AS USER.NAME$, _
               15 AS PASSWORD$, _
                2 AS SECURITY.LEVEL$, _
                2 AS TIMES.ON$, _
                2 AS LAST.MESSAGE$, _
                1 AS PROTOCOL$, _
                1 AS GRAPHIC.PREF$, _
                2 AS MARGIN.LENGTH$, _
                2 AS BIT.FLAGS$, _
                2 AS SUBSCRIPTION.BEGAN$, _
                1 AS PAGE.LENGTH$, _
                1 AS RESERVED.USE$, _
               24 AS CITY.STATE$, _
                3 AS MACHINE.TYPE$, _
                4 AS TODAY.DL$, _
                4 AS TODAY.BYTES$, _
                4 AS DL.BYTES$, _
                4 AS UL.BYTES$, _
               14 AS LAST.DATE.TIME.ON$, _
                3 AS LIST.NEW.DATE$, _
                2 AS USER.DOWNLOADS$, _
                2 AS USER.UPLOADS$, _
                2 AS ELAPSED.TIME$
9460  FIELD 4,128 AS USER.RECORD$
      IF LOF(4) = 0 THEN _
         EC = 999 : _
         CLOSE 4 : _
         KILL ACTIVE.USER.FILE$
9470   RETURN
'
' *****************************************************************************
' *  Error handling for the separately compiled subroutines of RBBS-PC        *
' *****************************************************************************
'
9900  EC = ERR
      IF ERL < 9100 OR ERL > 9499 THEN _
         PRINT "Trapped error";EC;"at line";ERL
      RESUME NEXT
'
' BRKFNAME - subroutine to split file name into components
'            (Stolen from RBBS-PC)
'
      SUB BRKFNAME (FILENAME$,DRVPATH$,PREFIX$,EXTENSION$,FOR.JOINING) STATIC
60000 CALL ALLCAPS (FILENAME$)
      DRVPATH$ = ""
      PREFIX$ = ""
      EXTENSION$ = ""
60100 CALL TRIMTRAIL (FILENAME$,"\")
      L = LEN(FILENAME$)
      IF L < 1 THEN _
         EXIT SUB
60200 CALL FINDLAST (FILENAME$,"\",X,Y)
      IF X < 1 THEN _
         IF MID$(FILENAME$,2,1) = ":" THEN _
            DRVPATH$ = LEFT$(FILENAME$,1) : _
            S = 3 _
         ELSE _
            S = 1 _
      ELSE _
         DRVPATH$ = LEFT$(FILENAME$,X-1) : _
         S = X + 1
60300 X = INSTR(FILENAME$ + ".",".")
      IF X < L THEN _
         EXTENSION$ = MID$(FILENAME$,X + 1,3)
      IF S <= L THEN _
         IF X >= S THEN _
            PREFIX$ = MID$(FILENAME$,S,X - S)
60400 IF NOT FOR.JOINING THEN _
         EXIT SUB
60500 IF LEN(DRVPATH$) = 1 THEN _
         DRVPATH$ = DRVPATH$ + ":"
60600 IF INSTR(DRVPATH$,"\") > 0 THEN _
         DRVPATH$ = DRVPATH$ + "\"
60700 IF LEN(EXTENSION$) > 0 THEN _
         EXTENSION$ = "." + EXTENSION$
      END SUB
'
'  TRIMTRAIL - subroutine to trim off trailing characters
'            (Stolen from RBBS-PC)
'
      SUB TRIMTRAIL (TRIM.PARM$,TRIM.THIS$) STATIC
70000 WHILE RIGHT$(TRIM.PARM$,1) = TRIM.THIS$
         TRIM.PARM$ = LEFT$(TRIM.PARM$,LEN(TRIM.PARM$) - 1)
      WEND
      END SUB
'
' ALLCAPS - subroutine to convert string to upper case
'            (Stolen from RBBS-PC)
'
      SUB ALLCAPS (CONVERT.FIELD$) STATIC
80000 FOR Z = 1 TO LEN (CONVERT.FIELD$)
         Z.MID = ASC (MID$ (CONVERT.FIELD$, Z, 1))
         IF Z.MID > 96 AND Z.MID < 123 THEN _
            MID$ (CONVERT.FIELD$, Z, 1) = CHR$ (Z.MID - 32)
      NEXT
      END SUB
'
' FINDLAST - subroutine to find last occurence of a string
'            (Stolen from RBBS-PC)
'
      SUB FINDLAST (LOOK.IN$,LOOK.FOR$,WHERE.FOUND,NUM.FINDS) STATIC
90000 WHERE.FOUND = INSTR(LOOK.IN$,LOOK.FOR$)
      NUM.FINDS = -(WHERE.FOUND > 0)
      NEXT.FOUND = INSTR(WHERE.FOUND + 1,LOOK.IN$,LOOK.FOR$)
90100 WHILE NEXT.FOUND > 0
         NUM.FINDS = NUM.FINDS + 1
         WHERE.FOUND = NEXT.FOUND
         NEXT.FOUND = INSTR(WHERE.FOUND + 1,LOOK.IN$,LOOK.FOR$)
      WEND
      END SUB
