PAGE 75,128 TITLE SYSOP - CCBBS Sysop Utility Routines PAGE .XLIST INCLUDE CCBBS.MAC INCLUDE CCBBS.DEF .LIST ;----------------------------------------------- ;SYSTEM DATA SEGMENT ;----------------------------------------------- SYSDATA SEGMENT PARA PUBLIC 'DATA' EXTRN CALLRN:BYTE,ABORT:BYTE,SHUTFLG:BYTE EXTRN MSGFILN:byte,MSGTFIN:byte,RETCODE:BYTE EXTRN MSSGN:BYTE,MSSGH:WORD,TESTF:byte EXTRN MSGINX1:WORD,MSGINX2:WORD EXTRN MSGUCNT:WORD,USERH:WORD,EMIXF:WORD EXTRN USERN:BYTE,USRCNT:WORD,USRLOCK:WORD EXTRN USRINXA:WORD,USRINXL:WORD,ADDCNT:WORD EXTRN FDIRH:WORD,DIRCNT:WORD,FDIRN:BYTE,MSGSEG:WORD FNCNT DB 9 ;MAX VALID VALUE FNTBL DW WHODAT ;F1 DW DSPC00 ;F2 DW SHUTDN ;F3 DW FNCHAT ;F4 DW FNLOFF ;F5 DW DEBUG ;F6 DW FNPFLG ;F7 DW FLINET ;F8 DW FSNOOP ;F9 DW FNCLRS ;F10 ;USER RECORD MAINTENANCE CTBLS1 DB 'ADFGKMNLPRSTUV' JTBLS1 DW USER80 ;AUTHORIZE MESSAGE SECTIONS DW USER64 ;DELETE DW USE140 ;FLAGS (SECURITY) DW USER70 ;GROUP ID DW USE150 ;KEEP USER DW USER90 ;MENU DW USER68 ;NEW PASSWORD DW USER66 ;LOCKOUT DW USER62 ;PRINT DW USE110 ;REJECT REGISTRATION DW USER74 ;SYSOP AUTHORITY DW USE120 ;TIME LIMIT DW USE130 ;USER PARMS DW USE100 ;VALIDATE REGISTRATION ;FILE DIRECTORY MAINTENANCE CTBLS2 DB 'DCSMERPAF' JTBLS2 DW FDIR64 ;DELETE DW FDIR70 ;CLASS DW FDIR80 ;SECTION DW FDIR90 ;MENU DW FDIRA0 ;EDIT FILE DESCRIPTION DW FDIRB0 ;RENAME FILE DW FDIRC0 ;CHANGE PATH DW FDIRD0 ;ARCHIVE FILE DW FDIRE0 ;STATUS FLAGS CTBLS3 DB 'PNVSCUOAF' JTBLS3 DW STSY50 ;PUBLIC SECTIONS DW STSY40 ;NEW USER SECTIONS DW STSY60 ;VALIDATION OPTION DW STS100 ;DEFAULT FILE SECTION DW STS200 ;DEFAULT FILE CLASS DW STS300 ;DEFAULT UPLOAD PATH DW STS400 ;MESSAGE OWNERSHIP DW STS500 ;EXTENDED ASCII DW STS600 ;DEFAULT FILE STATUS CTBLS4 DB 'PWSFCP' JTBLS4 DW STSY65 ;PASSWORD REQMT DW STS700 ;SIGOP FLAGS DW STS800 ;CALL PROGRESS LOGGING CTBLD1 DB 'DISQT?' JTBLD1 DW HEXDSP ;HEX MEMORY DISPLAY DW IOPDSP ;I/O PORT DISPLAY DW LSTBUF ;STRING HEADERS DW DBEXIT ;EXIT DW WHAT ;TASK STATUS DW DBMENU ;FULL MENU HEXTBL DB '0123456789ABCDEF' CALOFN DB 'CCALOG.FIL',0 ;ARCHIEVED CALLERS FILE MAILOFN DB 'CCEMAIL.BAK',0 ;old mail file MAILTFN DB 'CCEMAIL.$$$',0 ;TEMPORARY USERS FILE USROFN DB 'CCUSERS.BAK',0 ;old users file usrtfn db 'CCUSERS.$$$',0 ;temporary users file DIROFN DB 'CCFILDIR.BAK',0 ;OLD DIRECTORY FILE msgofn db 'CCMSG.BAK',0 ;old message file msgotn db 'CCMSGTST.BAK',0 ;old test msg file ;SPECIAL STRING TABLE FOR SYSMSG SYTBL1 DB 13,10,12,27,34 ;CONTROL CHARS SYTBL2 DW STR02 ;SUBSTITUTION STRINGS DW STR03 DW STR04 DW STR05 DW STR06 ;MESSAGE STRINGS DW STR02-STR01-2 STR01 DB 'MSG' DW STR03-STR02-2 STR02 DB 'CR' DW STR04-STR03-2 STR03 DB 'LF' DW STR05-STR04-2 STR04 DB 'FF' DW STR06-STR05-2 STR05 DB 'ESC' DW STR07-STR06-2 STR06 DB 'QM' DW STR99-STR07 str07 db 'DB' STR99 EQU $ ;DOS CONTROL BLOCK FOR FIND COMMAND FINDCTL DB 21 DUP (0) FFATR DB 0 ;ATTRIBUTE BYTE FFTIME DW 0 ;CREATE TIME FFDATE DW 0 ;CREATE DATE FFSIZE DW 0 ;LSW FILE SIZE FFSIZM DW 0 ;MSW FILE SIZE FFNAME DB 13 DUP (' ') ;FILE NAME AND EXTENSION SYSDATA ENDS ;----------------------------------------------- ;CODE SEGMENT ;----------------------------------------------- CSEG SEGMENT PARA PUBLIC 'CODE' EXTRN TAYSOP:NEAR,MMENU1:NEAR,MMENU2:NEAR EXTRN SNDCF:NEAR,NOTYET:NEAR,TSYSOP:NEAR,TSIGOP:NEAR EXTRN ERROR:NEAR,GETBUF:NEAR,FREBUF:NEAR EXTRN QUERY:NEAR,DQCMD:NEAR,XLATE:NEAR EXTRN PADB:NEAR,MOVSTL:NEAR,APPBYT:NEAR EXTRN ILINEB:NEAR,MOVSTR:NEAR,WRMSG:NEAR EXTRN FRELBF:NEAR,QYES:NEAR,BINASP:NEAR,FEOF:NEAR EXTRN BINASC:NEAR,STRIP:NEAR,ASCBIN:NEAR EXTRN HAYIN:NEAR,INITLN:NEAR,CONR:NEAR,CONW:NEAR EXTRN DOSDAT:NEAR,READM:NEAR,WRITM:NEAR,PKINX:NEAR EXTRN DTEASC:NEAR,TIMHM:NEAR,USRCNV:NEAR EXTRN CRCCLC:NEAR,CLEAR:NEAR,MSFCNV:NEAR EXTRN BINASD:NEAR,BLANKF:NEAR,WMSGNO:NEAR EXTRN QMSGNO:NEAR,QYESNO:NEAR,MOVMSG:NEAR,LABWIN:NEAR EXTRN CKPTM:NEAR,SAVINX:NEAR,WPOST:NEAR,WTID:NEAR EXTRN FRECMD:NEAR,CKCTLK:NEAR,WFBLK:NEAR,DSPCLS:NEAR EXTRN GETSBF:NEAR,RDUSER:NEAR,SKBLK:NEAR,DSPSTS:NEAR EXTRN CPYFIL:NEAR,APPDSB:NEAR,VALSEC:NEAR,DSPSEC:NEAR EXTRN FREWIN:NEAR,SETWIN:NEAR,RESWIN:NEAR,UPAR00:NEAR EXTRN LOCKWT:NEAR,UNLOCK:NEAR,GETMSG:NEAR,CPCSTA:near EXTRN GETLIN:NEAR,OPNLF:NEAR,SKBLK:NEAR,CMPSTR:near EXTRN OPNMSG:near,QDFLT:NEAR,CKFSPC:NEAR,LOGDSK:NEAR EXTRN GETUSR:NEAR,PUTUSR:NEAR,FREUSR:NEAR,UPDUSR:NEAR EXTRN MVCSTR:NEAR,CPCSTR:NEAR,LININ:NEAR,MVLSTR:NEAR EXTRN ATOINX:NEAR PUBLIC DSPCLR,SETGID,PACKMF,RENMSG,RECMSG PUBLIC LISTMH,ARCLOG,USERFM,SYSMSG,PACKUF PUBLIC FNKEY,MAKEPR,FDIRFM,PDIRFI,STSYSP PUBLIC PSECNO ASSUME CS:CSEG,DS:NOTHING,ES:SYSDATA SYSOP PROC NEAR ;--------------------------------------------------------- ;FUNCTION KEY ROUTINES ;--------------------------------------------------------- FNKEY: CMP AL,FNCNT ;MAX VALID FUNCTION CODE JBE FNKEY0 ;NO PROBLEM STC ;SHOW ERROR RET FNKEY0: CBW ;MAKE WORD INDEX SHL AX,1 ;FORM INDEX MOV DI,AX ;NEED INDEX REGISTER JMP FNTBL[DI] ;GO TO SPECIFIC ROUTINE ;-------------------------------------------------------- ;DISPLAY CALLER'S LOG ;-------------------------------------------------------- DSPCLR: CALL TAYSOP ;AUTHORIZED CALLER? JZ DSPCLX ;NO CALL DSPC00 ;LOCAL ROUTINE JMP MMENU1 ;MAIN MENU DSPCLX: JMP MMENU2 ;UNKNOWN COMMAND DSPC00: MOV DX,OFFSET CALLRN ;CALLER FILE CALL SNDCF ;TRANSMIT FILE RET ;--------------------------------------------------------- ;SET GROUP ID ;--------------------------------------------------------- SETGID: CALL TAYSOP ;AUTHORIZED CALLER? JNZ SETG10 ;YES JMP MMENU2 ;UNKNOWN COMMAND SETG10: CMP WORD PTR [BX+USRIN],0 ;STACKED INPUT? JNZ SETG20 ;YES MOV AX,108 ;GID? CALL QMSGNO ;ASK USER JC SETG90 ;LOST CARRIER SETG20: CALL DQCMD ;GET RESPONSE CALL XLATE ;MAKE UPPER CASE MOV CX,8 ;GID LENGTH CALL PADB ;PAD WITH BLANKS MOV DI,SI MOV SI,WORD PTR [BX+USRST] ;USER RECORD MOV WORD PTR [SI-2],UEGID ;POINT TO GROUPID CALL MOVSTL ;MOVE TO RECORD SETG90: JMP MMENU1 ;MAIN MENU ;--------------------------------------------------------- ;PACK MESSAGE FILE ; BP-2 CCEMAIL.FIL HANDLE ; BP-4 CCEMAIL.FIL BUFFER ADDRESS ; BP-6 PURGE COUNTER ; BP-8 CURRENT BLOCK NUMBER - CCEMAIL.FIL ; BP-10 HANDLE FOR TEMP MESSAGES FILE ; BP-12 NUMBER OF INDEX BLOCKS ; BP-14 HANDLE FOR ARCHIVE/MERGE FILE ; BP-16 MERGE FILE BUFFER ADDRESS ; BP-18 MERGE COUNT ; BP-20 FLAGS ; 0001H - NORMAL PACK ; 0002H - MERGE MAIL FILES ; 0004H - RECOVER DELETED MESSAGES ; 0008H - ARCHIVE DELETED MESSAGES ;--------------------------------------------------------- PACKMF: CALL TSYSOP ;AUTHORIZED CALLER? JNZ PACK10 ;YES JMP MMENU2 ;UNKNOWN COMMAND PACK10: MOV AX,111 ;PACK OPTION? CALL QMSGNO ;GET RESPONSE JC PACK12 ;DEFAULT TO NO CALL DQCMD ;GET RESPONSE CALL XLATE ;MAKE UPPER CASE MOV CX,[SI-2] ;RESPONSE LENGTH JCXZ PACK12 ;NO PACK MOV AX,1 ;ASSUME NORMAL PACK CMP BYTE PTR [SI],'P' ;PACK? JZ PACK20 ;YES MOV AX,9 ;ASSUME ARCHIVE CMP BYTE PTR [SI],'A' ;ARCHIVE? JZ PACK20 ;YES MOV AX,5 ;ASSUME RECOVER & MERGE CMP BYTE PTR [SI],'R' ;RECOVER? JZ PACK20 ;YES MOV AX,3 ;ASSUME MERGE CMP BYTE PTR [SI],'M' ;MERGE? JZ PACK20 ;YES PACK12: JMP MMENU1 ;MAIN MENU PACK20: CMP MSGUCNT,0 ;FILE IN USE? JZ PACK30 ;NO MOV AX,110 ;FILE IN USE CALL WMSGNO JMP MMENU1 ;EXIT PACK30: MOV MSGUCNT,-1 ;SHOW FILE BEING COMPRESSED TEST WORD PTR EMIXF,80H ;INDEX FILE AVAILABLE? JZ PACK31 ;NO OR WORD PTR EMIXF,8000H ;SHOW PACK IN PROCESS AND WORD PTR EMIXF,NOT 80H ;SHOW NOT AVAILABLE PACK31: FRAME 10 MOV [BP-20],AX ;OPTION FLAGS ;QUERY FOR SIZE CHANGE CALL ILINEB ;INITIALIZE BUFFER MOV AX,305 ;MAXIMUM MSGS CALL MOVMSG ;MOVE TO BUFFER MOV AX,DS:MSGCKPT+MDIMAX ;CURRENT FILE SIZE MOV [BP-12],AX ;SET AS DEFAULT CALL BINASP ;PUT IN BUFFER MOV AX,306 ;MESSAGE TRAILER CALL MOVMSG ;MOVE TO BUFFER CALL QUERY ;ASK OPERATOR CALL DQCMD ;GET RESPONSE IN BUFFER MOV CX,WORD PTR [SI-2] ;LENGTH JCXZ PACK34 ;USE CURRENT LENGTH CALL ASCBIN ;CONVERT TO BINARY CMP AX,DS:MSGCKPT+MIACTM ;LARGE ENOUGH? JNB PACK33 ;YES MOV AX,DS:MSGCKPT+MIACTM ;SET MINIMUM VALUE PACK33: ADD AX,MSGSIZ-1 ;ROUND UP AND AX,NOT MSGSIZ-1 ;TO SECTOR BOUNDRY MOV [BP-12],AX ;NEW FILE SIZE ;ALLOCATE NEW INDEX STRINGS IN MEMORY MOV SI,MSGINX1 ;MESSAGE NUMBER INDEX CALL FREBUF ;FREE IT MOV SI,MSGINX2 ;MESSAGE BLOCK INDEX CALL FREBUF ;FREE IT MOV AX,[BP-12] ;NEW MAXIMUM SHL AX,1 ;2 BYTES PER ENTRY CALL GETSBF ;GET SYSTEM BUFFER MOV MSGINX1,SI ;NEW NUMBER INDEX CALL GETSBF ;GET SYSTEM BUFFER MOV MSGINX2,SI ;NEW BLOCK INDEX ;DELETE PREVIOUS BACKUP FILE PACK34: MOV AH,41H ;DELETE FILE MOV DX,OFFSET MAILOFN ;CCEMAIL.BAK PUSH DS PUSH ES POP DS INT 21H ;DOS REQUEST POP DS ;MAKE EMAIL FILE UNAVAILABLE TO OTHER PROCESSES MOV AX,MSSGH ;FILE HANDLE MOV [BP-2],AX ;INPUT FILE HANDLE MOV MSSGH,0 ;SHOW FILE CLOSED ;CREATE NEW MESSAGES FILE AS CCEMAIL.$$$ PACK35: MOV AH,3CH ;CREATE FUNCTION XOR CX,CX ;NORMAL ATTRIBUTE MOV DX,OFFSET MAILTFN ;TEMPORARY FILE NAME PUSH DS PUSH ES POP DS INT 21H ;DOS REQUEST POP DS MOV [BP-10],AX ;NEW HANDLE JNC PACK40 ;OPEN OK ERR 2 PACK40: MOV [BP-10],AX ;FILE HANDLE MOV AX,MSGSIZ ;RECORD SIZE CALL GETBUF ;GET BUFFER MOV [BP-16],SI ;MERGE BUFFER ADDRESS MOV AX,MSGSIZ ;RECORD SIZE CALL GETBUF ;GET BUFFER MOV [BP-4],SI ;MAIN BUFFER ADDRESS XOR DI,DI ;MESSAGE INDEX POINTER MOV DS:MSGCKPT+MIACTM,DI ;CLEAR ACTIVE MESSAGES MOV DS:MSGCKPT+MIFRST,DI ;CLEAR START POINTER MOV DS:MSGCKPT+MFLASH,DI ;1ST FLASH MESSAGE MOV DS:MSGCKPT+MLASTF,DI ;LAST FLASH MESSAGE MOV [BP-6],DI ;CLEAR MSGS PURGED MOV [BP-18],DI ;CLEAR MSGS MERGED MOV [BP-8],DI ;MSG INDEX POINTER MOV [BP-14],DI ;NO ARCHIVE FILE ;SEEK INPUT FILE PAST INDEX BLOCKS XOR AX,AX ;CLEAR WORK REG CMP DS:MSGCKPT+MVERS,0 ;OLD FORMAT? JZ PACK43 ;YES - NO INDEX RECORDS MOV AX,DS:MSGCKPT+MDIMAX ;CURRENT MAXIMUM PACK42: MOV CL,5 ;SHIFT FACTOR SHR AX,CL ;CONVERT TO RECORDS PACK43: INC AX ;ALLOW FOR HEADER MOV CX,[BP-2] ;INPUT FILE HANDLE CALL SKBLK ;SEEK ;SEEK OUTPUT FILE PAST INDEX MOV AX,[BP-12] ;NEW MAXIMUM MOV CL,5 ;SHIFT FACTOR SHR AX,CL ;CONVERT TO RECORDS INC AX ;ALLOW FOR HEADER MOV CX,[BP-10] ;OUTPUT FILE HANDLE CALL SKBLK ;SEEK ;OPEN MERGE/ARCHIVE FILE PACK50: TEST WORD PTR [BP-20],0AH ;NEED ANY? JNZ PACK51 ;YES JMP PACK60 ;NO PACK51: MOV AX,456 ;ARCHIVE FILE MSG TEST WORD PTR [BP-20],8 ;ARCHIVE? JNZ PACK52 ;YES MOV AX,455 ;MERGE FILE MSG PACK52: CALL QMSGNO ;GET FILE NAME JNB PACK54 ;GOOD ENTRY PACK53: MOV WORD PTR [BP-20],NOT 0AH ;CLEAR MERGE FLAGS JMP PACK60 ;PROCEED WITH PACK PACK54: CALL DQCMD ;GET RESPONSE CALL XLATE ;MAKE UC MOV CX,[SI-2] ;GET LENGTH JCXZ PACK53 ;NORMAL PACK MOV AL,0 ;STRING TERMINATOR CALL APPBYT ;ADD TO STRING MOV AH,3CH ;CREATE FUNCTION TEST WORD PTR [BP-20],8 ;ARCHIVE? JNZ PACK55 ;YES MOV AH,3DH ;OPEN FUNCTION PACK55: XOR CX,CX ;NORMAL ATTRIBUTE MOV DX,SI ;FILE NAME INT 21H ;DOS REQUEST MOV [BP-14],AX ;NEW HANDLE JNC PACK60 ;OPEN OK MOV AX,457 ;CAN'T OPEN MSG CALL WMSGNO ;DISPLAY MSG JMP PACK50 ;PROMPT AGAIN ;COPY/MERGE ACTIVE MESSAGES ;READ RECORD FROM MAIN FILE PACK60: OR WORD PTR [BX+CBFLG],SFNOPL ;NO 'MORE' PROMPTS TEST WORD PTR [BP-20],1 ;EOF ON MAIN? JZ PACK62 ;YES - CHECK MERGE CALL PACKMF_RDMAIN ;GET NEXT MAIN RECORD JNC PACK62 ;NOT EOF AND WORD PTR [BP-20],NOT 1 ;SET EOF ;READ RECORD FROM MERGE FILE PACK62: TEST WORD PTR [BP-20],2 ;EOF ON MERGE? JZ PACK72 ;YES - WRITE MAIN RECORD CALL PACKMF_RDMRGE ;GET NEXT MERGE RECORD JNC PACK64 ;NOT EOF AND WORD PTR [BP-20],NOT 2 ;SET EOF JMP PACK72 ;GO WRITE MAIN PACK64: TEST WORD PTR [BP-20],1 ;EOF ON MAIN? JZ PACK70 ;YES - WRITE MERGE RECORD MOV SI,[BP-4] ;MAIN FILE HEADER MOV DI,[BP-16] ;MERGE FILE HEADER MOV AX,[DI+MMNUMB] ;MERGE MSG NUMBER CMP AX,[SI+MMNUMB] ;MAIN MSG NUMBER JA PACK72 ;WRITE MAIN NEXT JB PACK70 ;WRITE MERGE NEXT MOV BYTE PTR [DI+MDFLAG],0 ;DISCARD EQUAL MERGE MSG JMP PACK62 ;READ MERGE NEXT ;WRITE MERGE FILE RECORD PACK70: CALL PACKMF_WRMRGE ;WRITE MERGE RECORD JMP PACK62 ;READ NEXT MERGE PACK72: TEST WORD PTR [BP-20],1 ;EOF ON MAIN? JZ PACK78 ;MIGHT BE DONE CALL PACKMF_WRMAIN JMP PACK60 ;READ MAIN PACK78: TEST WORD PTR [BP-20],2 ;EOF ON MERGE? JZ PACK80 ;YES JMP PACK60 ;READ MAIN ;ISSUE STATISTICS MESSAGE PACK80: CALL ILINEB ;FORMAT BUFFER MOV AX,[BP-6] ;MESSAGES PURGED OR AX,AX ;ANYTHING? JZ PACK81 ;NO - SKIP MESSAGE CALL BINASP MOV AX,266 ;MESSAGES PURGED CALL MOVMSG ;MOVE TO BUFFER CALL WRMSG PACK81: CALL ILINEB ;FORMAT BUFFER MOV AX,[BP-18] ;MESSAGES MERGED OR AX,AX ;ANYTHING? JZ PACK82 ;NO - SKIP MESSAGE CALL BINASP MOV AX,459 ;MESSAGES PURGED CALL MOVMSG ;MOVE TO BUFFER CALL WRMSG ;CLEAR REST OF MSGINX1 PACK82: MOV CX,[BP-12] ;MAXIMUM ENTRIES MOV DI,[BP-8] ;NEXT POINTER SUB CX,DS:MSGCKPT+MIACTM ;REMAINING SLOTS XOR AX,AX JCXZ PACK90 PUSH BX MOV BX,MSGINX1 PACK85: MOV [BX+DI],AX ;CLEAR ENTRY ADD DI,2 ;NEXT ENTRY LOOP PACK85 POP BX ;CLOSE CCEMAIL.FIL PACK90: MOV SI,[BP-4] ;MAIN BUFFER ADDRESS CALL FREBUF ;FREE IT MOV AH,3EH ;CLOSE FUNCTION PUSH BX MOV BX,[BP-2] ;MAIN FILE HANDLE INT 21H ;DOS REQUEST POP BX ;CLOSE CCEMAIL.$$$ MOV AH,3EH ;CLOSE FUNCTION PUSH BX MOV BX,[BP-10] ;MAIN FILE HANDLE INT 21H ;DOS REQUEST POP BX ;CLOSE MERGE/ARCHIVE FILE IF ANY MOV SI,[BP-16] ;MERGE BUFFER ADDRESS CALL FREBUF ;FREE IT MOV AH,3EH ;CLOSE FUNCTION PUSH BX MOV BX,[BP-14] ;MERGE FILE HANDLE OR BX,BX ;EXIST? JZ PACK92 ;NO INT 21H ;DOS REQUEST PACK92: POP BX ;RENAME CCEMAIL.FIL TO CCEMAIL.BAK MOV AH,56H ;RENAME FUNCTION MOV DX,OFFSET MSSGN ;MESSAGES FILE NAME MOV DI,OFFSET MAILOFN ;MESSAGES.BAK PUSH DS PUSH ES POP DS INT 21H ;DOS REQUEST POP DS ;RENAME CCEMAIL.$$$ TO CCEMAIL.FIL MOV AH,56H ;RENAME FUNCTION MOV DX,OFFSET MAILTFN ;TEMPORARY FILE NAME MOV DI,OFFSET MSSGN ;CCEMAIL.FIL PUSH DS PUSH ES POP DS INT 21H ;DOS REQUEST POP DS ;OPEN NEW CCEMAIL.FIL MOV AX,3D02H ;OPEN REQUEST MOV DX,OFFSET MSSGN ;FILE NAME PUSH DS PUSH ES POP DS INT 21H ;DOS REQUEST POP DS JNC PACK95 ;GOOD OPEN ERR 2 ;BAD NEWS PACK95: MOV MSSGH,AX ;FILE HANDLE ;CHECKPOINT NEW INDEX ARRAYS MOV DS:MSGCKPT+MVERS,2 ;SHOW NEW FORMAT MOV AX,[BP-12] ;NEW MSG MAX MOV DS:MSGCKPT+MDIMAX,AX ;SET NEW MAX CALL SAVINX ;SAVE INDEX ARRAYS CALL CKPTM ;CHECKPOINT 1ST RECORD MOV SP,BP ;FREE LOCAL STORAGE POP BP ;RESTORE CALLER'S FRAME MOV MSGUCNT,0 ;SHOW FILE AVAILABLE TEST WORD PTR EMIXF,8000H ;DID WE DISABLE INDEX? JZ PACK99 ;NO AND WORD PTR EMIXF,NOT 8000H ;CLEAR OUR FLAG OR WORD PTR EMIXF,80H ;ENABLE INDEX AGAIN PACK99: JMP MMENU1 ;MAIN MENU ;PACKMF SUBROUTINES ;READ HEADER FROM MAIN FILE PACKMF_RDMAIN: MOV SI,[BP-4] ;BUFFER ADDRESS CMP BYTE PTR [SI+MDFLAG],0 ;VALID RECORD? JNZ PACKMF_RDMA15 ;YES - ANALYZE IT PACKMF_RDMA10: CALL PACKMF_RBMAIN ;READ ONE BLOCK JNZ PACKMF_RDMA15 ;GOOD READ STC ;SHOW EOF RET PACKMF_RDMA15: MOV SI,[BP-4] ;BUFFER ADDRESS MOV AL,BYTE PTR [SI+MDFLAG] ;LIVE/DELETE FLAG CMP AL,0E1H ;LIVE MESSAGE? JNZ PACKMF_RDMA20 ;NO - TAKE CORRECTIVE ACTION CLC RET PACKMF_RDMA20: CMP AL,0E2H ;DELETED MESSAGE? JNZ PACKMF_RDMA30 ;NO - PURGE BLOCK MOV BYTE PTR [SI+MDFLAG],0E1H ;MARK AS LIVE TEST WORD PTR [BP-20],4 ;RECOVER DELETES? JZ PACKMF_RDMA25 ;NO - PURGE BLOCK CLC RET PACKMF_RDMA25: INC WORD PTR [BP-6] ;COUNT PURGED MESSAGE CALL ILINEB ;FORMAT BUFFER MOV AX,263 ;MSG # CALL MOVMSG ;MOVE TO BUFFER MOV DI,[BP-4] ;BUFFER MOV AX,WORD PTR [DI+MMNUMB] ;MESSAGE NUMBER CALL BINASP MOV AX,265 ;PURGED CALL MOVMSG ;MOVE TO BUFFER CALL WRMSG PACKMF_RDMA30: TEST WORD PTR [BP-20],8 ;ARCHIVE DELETES? JZ PACKMF_RDMA40 ;NO CALL PACKMF_WBARCH ;ARCHIVE PURGED BLOCK PACKMF_RDMA40: JMP PACKMF_RDMA10 ;READ NEXT BLOCK ;READ HEADER FROM MERGE FILE PACKMF_RDMRGE: MOV SI,[BP-16] ;BUFFER ADDRESS CMP BYTE PTR [SI+MDFLAG],0 ;VALID RECORD? JNZ PACKMF_RDMR15 ;YES - ANALYZE IT PACKMF_RDMR10: CALL PACKMF_RBMRGE ;READ ONE BLOCK JNZ PACKMF_RDMR15 ;GOOD READ STC RET PACKMF_RDMR15: MOV SI,[BP-16] ;BUFFER ADDRESS MOV AL,BYTE PTR [SI+MDFLAG] ;LIVE/DELETE FLAG CMP AL,0E1H ;LIVE MESSAGE? JNZ PACKMF_RDMR20 ;NO - TAKE CORRECTIVE ACTION CLC RET PACKMF_RDMR20: CMP AL,0E2H ;DELETED MESSAGE? JNZ PACKMF_RDMR10 ;NO - PURGE BLOCK MOV BYTE PTR [SI+MDFLAG],0E1H ;MARK AS LIVE TEST WORD PTR [BP-20],4 ;RECOVER DELETES? JZ PACKMF_RDMR10 ;NO - PURGE BLOCK CLC RET ;WRITE CURRENT MAIN MSG TO NEW MAIL FILE PACKMF_WRMAIN: CALL ILINEB ;FORMAT BUFFER MOV AX,263 ;MSG # CALL MOVMSG ;MOVE TO BUFFER MOV DI,[BP-4] ;BUFFER MOV AX,WORD PTR [DI+MMNUMB] ;MESSAGE NUMBER TEST BYTE PTR [DI+MPFLAG],1 ;FLASH MSG? JZ PACKMF_WRMA20 ;NO CMP DS:MSGCKPT+MFLASH,0 ;1ST FLASH MSG? JNZ PACKMF_WRMA10 ;NO MOV DS:MSGCKPT+MFLASH,AX ;MARK 1ST FLASH MSG PACKMF_WRMA10: CMP DS:MSGCKPT+MLASTF,AX ;NEW LAST FLASH? JNC PACKMF_WRMA20 ;NO MOV DS:MSGCKPT+MLASTF,AX ;SET NEW LAST FLASH PACKMF_WRMA20: MOV DI,[BP-8] ;INDEX PUSH BX MOV BX,MSGINX1 ;POINT TO INDEX MOV [BX+DI],AX ;STORE MESSAGE NUMBER POP BX CALL BINASP CALL GCBLK ;GET CURRENT BLOCK # PUSH BX MOV BX,MSGINX2 ;POINT TO INDEX MOV [BX+DI],AX ;STORE BLOCK POP BX MOV DS:MSGCKPT+MILAST,DI ;LAST INDEX MOV AX,264 ;COPIED CALL MOVMSG ;MOVE TO BUFFER CALL WRMSG INC DS:MSGCKPT+MIACTM ;COUNT MESSAGE ADD WORD PTR [BP-8],2 ;NEXT INDEX CALL MSFCNV ;CONVERT MSG HEADER PACKMF_WRMA30: CALL PACKMF_WBMAIL ;WRITE BLOCK PACKMF_WRMA40: CALL PACKMF_RBMAIN ;GET NEXT RECORD JNZ PACKMF_WRMA50 ;GOOD READ STC ;EOF RET PACKMF_WRMA50: MOV SI,[BP-4] ;BUFFER ADDRESS MOV AL,BYTE PTR [SI+MDFLAG] ;MESSAGE DELETE FLAG CMP AL,0E1H ;LIVE HEADER? JZ PACKMF_WRMA60 ;YES - EXIT CMP AL,0E2H ;DELETED HEADER? JNZ PACKMF_WRMA30 ;NO - COPY MSG BLOCK PACKMF_WRMA60: CLC RET ;WRITE CURRENT MERGE MSG TO NEW MAIL FILE PACKMF_WRMRGE: CALL ILINEB ;FORMAT BUFFER MOV AX,263 ;MSG # CALL MOVMSG ;MOVE TO BUFFER MOV DI,[BP-16] ;BUFFER MOV AX,WORD PTR [DI+MMNUMB] ;MESSAGE NUMBER TEST BYTE PTR [DI+MPFLAG],1 ;FLASH MSG? JZ PACKMF_WRMR20 ;NO CMP DS:MSGCKPT+MFLASH,0 ;1ST FLASH MSG? JNZ PACKMF_WRMR10 ;NO MOV DS:MSGCKPT+MFLASH,AX ;MARK 1ST FLASH MSG PACKMF_WRMR10: CMP DS:MSGCKPT+MLASTF,AX ;NEW LAST FLASH? JNC PACKMF_WRMR20 ;NO MOV DS:MSGCKPT+MLASTF,AX ;SET NEW LAST FLASH PACKMF_WRMR20: MOV DI,[BP-8] ;INDEX PUSH BX MOV BX,MSGINX1 ;POINT TO INDEX MOV [BX+DI],AX ;STORE MESSAGE NUMBER POP BX CALL BINASP CALL GCBLK ;GET CURRENT BLOCK # PUSH BX MOV BX,MSGINX2 ;POINT TO INDEX MOV [BX+DI],AX ;STORE BLOCK POP BX MOV DS:MSGCKPT+MILAST,DI ;LAST INDEX MOV AX,458 ;MERGED CALL MOVMSG ;MOVE TO BUFFER CALL WRMSG INC DS:MSGCKPT+MIACTM ;COUNT ACT MESSAGE INC WORD PTR [BP-18] ;COUNT MERGED MESSAGE ADD WORD PTR [BP-8],2 ;NEXT INDEX CALL MSFCNV ;CONVERT MSG HEADER PACKMF_WRMR30: CALL PACKMF_WBMRGE ;WRITE BLOCK FROM MERGE PACKMF_WRMR40: CALL PACKMF_RBMRGE ;GET NEXT RECORD JNZ PACKMF_WRMR50 ;GOOD READ STC ;EOF RET PACKMF_WRMR50: MOV SI,[BP-16] ;BUFFER ADDRESS MOV AL,BYTE PTR [SI+MDFLAG] ;MESSAGE DELETE FLAG CMP AL,0E1H ;LIVE HEADER? JZ PACKMF_WRMR60 ;YES - EXIT CMP AL,0E2H ;DELETED HEADER? JNZ PACKMF_WRMR30 ;NO - COPY MSG BLOCK PACKMF_WRMR60: CLC RET ;READ ONE BLOCK FROM OLD MAIL FILE PACKMF_RBMAIN: MOV AH,3FH ;READ FUNCTION MOV CX,MSGSIZ ;BYTES TO READ MOV DX,[BP-4] ;BUFFER ADDRESS PUSH BX MOV BX,[BP-2] ;FILE HANDLE INT 21H ;DOS REQUEST POP BX JNC PACKMF_RBMA10 ;NO ERROR ERR 9 PACKMF_RBMA10: CMP AX,0 ;END OF FILE? RET ;READ ONE BLOCK FROM MERGE FILE PACKMF_RBMRGE: MOV AH,3FH ;READ FUNCTION MOV CX,MSGSIZ ;BYTES TO READ MOV DX,[BP-16] ;BUFFER ADDRESS PUSH BX MOV BX,[BP-14] ;FILE HANDLE INT 21H ;DOS REQUEST POP BX JNC PACKMF_RBMR10 ;NO ERROR ERR 9 PACKMF_RBMR10: CMP AX,0 ;END OF FILE? RET ;WRITE ONE BLOCK FROM OLD MAIL TO NEW MAIL FILE PACKMF_WBMAIL: MOV AH,40H ;WRITE FUNCTION MOV CX,MSGSIZ ;BYTES TO WRITE MOV DX,[BP-4] ;BUFFER ADDRESS PUSH BX MOV BX,[BP-10] ;FILE HANDLE INT 21H ;DOS REQUEST POP BX JNC PACKMF_WBMA10 ;NO ERROR ERR 2 PACKMF_WBMA10: CMP AX,CX ;OUT OF SPACE? RET ;WRITE ONE BLOCK FROM MERGE FILE TO NEW MAIL FILE PACKMF_WBMRGE: MOV AH,40H ;WRITE FUNCTION MOV CX,MSGSIZ ;BYTES TO WRITE MOV DX,[BP-16] ;BUFFER ADDRESS PUSH BX MOV BX,[BP-10] ;FILE HANDLE INT 21H ;DOS REQUEST POP BX JNC PACKMF_WBMR10 ;NO ERROR ERR 2 PACKMF_WBMR10: CMP AX,CX ;OUT OF SPACE? RET ;WRITE ONE BLOCK FROM OLD MAIL TO ARCHIVE FILE PACKMF_WBARCH: MOV AH,40H ;WRITE FUNCTION MOV CX,MSGSIZ ;BYTES TO WRITE MOV DX,[BP-4] ;BUFFER ADDRESS PUSH BX MOV BX,[BP-14] ;FILE HANDLE INT 21H ;DOS REQUEST POP BX JNC PACKMF_WBAR10 ;NO ERROR ERR 2 PACKMF_WBAR10: CMP AX,CX ;OUT OF SPACE? RET GCBLK: XOR CX,CX MOV DX,CX ;OFFSET 0 GCBLK1: MOV AX,4201H ;SEEK CURRENT + OFFSET PUSH BX MOV BX,[BP-10] ;FILE HANDLE INT 21H ;DOS REQUEST POP BX MOV CX,MSGSIZ ;BLOCK SIZE DIV CX ;CONVERT TO BLOCKS RET ;--------------------------------------------------------- ;RENUMBER MESSAGE FILE ; BP-2 ADJUSTMENT VALUE ; BP-4 MSG INDEX/USER RECORD ADDRESS ; BP-6 CURRENT USER BLOCK NUMBER ; BP-8 NEW 1ST MSG NUMBER ; BP-10 THRESHOLD MESSAGE NUMBER ; BP-12 DEFAULT BUFFER ;--------------------------------------------------------- RENMSG: CALL TSYSOP ;AUTHORIZED CALLER? JNZ REN010 ;YES JMP MMENU2 ;UNKNOWN COMMAND REN010: CMP MSGUCNT,0 ;MESSAGE FILE IN USE? JZ REN030 ;NO PROBLEM MOV AX,110 ;FILE IN USE CALL WMSGNO REN020: JMP MMENU1 ;EXIT REN030: MOV MSGUCNT,-1 ;SHOW FILE LOCKED PUSH BP ;SAVE CALLER'S FRAME MOV BP,SP ;ESTABLISH LOCAL FRAME SUB SP,12 ;ALLOCATE LOCAL VARIABLES XOR AX,AX ;NULL MOV [BP-2],AX ;ADJUSTMENT VALUE MOV [BP-6],AX ;USER BLOCK MOV [BP-12],AX ;DEFAULT BUFFER MOV WORD PTR [BP-8],1 ;DEFAULT NEW STARTING MSG MOV DI,DS:MSGCKPT+MIFRST ;START OF INDEX ARRAY MOV [BP-4],DI ;CURRENT INDEX VALUE PUSH BX MOV BX,MSGINX1 ;POINT TO INDEX MOV CX,[BX+DI] ;1ST MESSAGE NUMBER POP BX MOV [BP-10],CX ;DEFAULT THRESHOLD MSG # MOV AX,8 ;BUFFER SIZE CALL GETBUF ;GET BUFFER MOV [BP-12],SI ;PARK MOV AX,[BP-8] ;DEFAULT STARTING # CALL BINASP ;PUT IN BUFFER MOV AX,120 ;NEW LOWEST NUMBER MOV DI,[BP-12] ;DEFAULT STRING CALL QDFLT ;GET RESPONSE JNC REN033 ;OK JMP REN100 ;LOST CARRIER REN033: CALL DQCMD ;GET RESPONSE MOV CX,[SI-2] ;FIELD WIDTH JCXZ REN035 ;USE DEFAULT CALL ASCBIN ;GET BINARY NUMBER MOV [BP-8],AX ;SET 1ST MSG # REN035: MOV SI,[BP-12] ;DEFAULT BUFFER MOV WORD PTR [SI-2],0 ;RESET MOV AX,[BP-10] ;DEFAULT CALL BINASP ;PUT IN BUFFER MOV AX,393 ;MSG TO RENUMBER MOV DI,[BP-12] ;DEFAULT STRING CALL QDFLT ;GET RESPONSE JNC REN037 ;OK JMP REN100 ;LOST CARRIER REN037: CALL DQCMD ;DEQUEUE RESPONSE MOV CX,[SI-2] ;FIELD WIDTH JCXZ REN039 ;USE DEFAULT CALL ASCBIN ;GET BINARY NUMBER MOV [BP-10],AX ;SET THRESHOLD REN039: MOV AX,[BP-10] ;THRESHOLD MSG # SUB AX,[BP-8] ;NEW MSG # MOV [BP-2],AX ;ADJUSTMENT FACTOR MOV DI,[BP-4] ;MESSAGE INDEX REN040: PUSH BX MOV BX,MSGINX2 ;POINT TO BLOCK INDEX MOV AX,[BX+DI] ;BLOCK NUMBER POP BX MOV WORD PTR [BX+USRMP],AX ;BLOCK TO READ CALL READM ;READ MESSAGE MOV DX,[BP-10] ;THRESHOLD CMP WORD PTR [SI+MMNUMB],DX ;MESSAGE NUMBER JB REN048 ;DON'T MESS WITH THIS MSG MOV AX,[BP-2] ;ADJUSTMENT VALUE SUB WORD PTR [SI+MMNUMB],AX ;MESSAGE NUMBER PUSH BX MOV BX,MSGINX1 ;POINT TO INDEX SUB WORD PTR [BX+DI],AX ;ADJUST MSG # IN INDEX POP BX REN048: MOV CX,2 ;MAX # OF POINTERS ADD SI,MFBPTR ;BACKWARD POINTER REN050: CMP WORD PTR [SI],0 ;POINTER EXIST? JZ REN060 ;NO CMP WORD PTR [SI],DX ;ABOVE THRESHOLD? JB REN060 ;NO SUB WORD PTR [SI],AX ;ADJUST POINTER REN060: ADD SI,2 ;NEXT POINTER OFFSET LOOP REN050 ;NEXT POINTER CALL WRITM ;RE-WRITE RECORD ADD WORD PTR [BP-4],2 ;NEXT MESSAGE INDEX MOV DI,[BP-4] ;MESSAGE INDEX CMP DI,DS:MSGCKPT+MILAST ;END OF FILE? JA REN070 ;YES JMP REN040 ;NEXT MESSAGE ;UPDATE MSGCKPT POINTERS REN070: MOV AX,[BP-2] ;ADJUSTMENT FACTOR MOV DX,[BP-10] ;THRESHOLD VALUE CMP DS:MSGCKPT+MLASTMN,DX ;NEED ADJUSTING? JB REN072 ;NO SUB DS:MSGCKPT+MLASTMN,AX ;HIGH MESSAGE NUMBER REN072: CMP DS:MSGCKPT+MFLASH,0 ;ANY FLASH MESSAGES? JZ REN079 ;NO CMP DS:MSGCKPT+MFLASH,DX ;ABOVE THRESHOLD? JB REN074 ;NO SUB DS:MSGCKPT+MFLASH,AX ;FIRST FLASH MSG REN074: CMP DS:MSGCKPT+MLASTF,DX ;ABOVE THRESHOLD? JB REN079 ;NO SUB DS:MSGCKPT+MLASTF,AX ;LAST FLASH MSG REN079: CALL CKPTM ;RE-WRITE MSGCKPT CALL SAVINX ;RE-WRITE INDICES MOV MSGUCNT,0 ;UNLOCK FILE ;NOW ADJUST USERS 'LAST MESSAGE' POINTERS MOV WORD PTR [BP-6],3 ;1ST USER BLOCK NUMBER REN080: MOV AX,[BP-6] ;USER BLOCK NUMBER CALL GETUSR ;READ USER RECORD MOV [BP-4],SI ;SAVE ADDRESS JC REN100 ;END OF FILE ;UPDATE USER RECORD MOV SI,[BP-4] ;USER RECORD ADDRESS MOV AX,[BP-2] ;ADJUSTMENT FACTOR MOV DX,[BP-10] ;THRESHOLD CMP WORD PTR [SI+UELMSG],0 ;POINTER EXIST? JZ REN097 ;NO CMP WORD PTR [SI+UELMSG],DX ;ABOVE THRESHOLD? JB REN097 ;NO SUB WORD PTR [SI+UELMSG],AX ;ADJUST POINTER REN097: CMP WORD PTR [SI+UEHMSG],0 ;POINTER EXIST? JZ REN098 ;NO CMP WORD PTR [SI+UEHMSG],DX ;ABOVE THRESHOLD? JB REN098 ;NO SUB WORD PTR [SI+UEHMSG],AX ;ADJUST POINTER REN098: MOV AX,[BP-6] ;USER SLOT NUMBER CALL PUTUSR ;WRITE AND RELEASE RECORD ADD WORD PTR [BP-6],2 ;NEXT RECORD JMP REN080 ;GO READ REN100: MOV SI,[BP-12] ;DEFAULT BUFFER CALL FREBUF ;FREE IT MOV SP,BP ;FREE LOCAL STORAGE POP BP ;RESTORE CALLER'S FRAME JMP MMENU1 ;MAIN MENU ;--------------------------------------------------------- ;RECOVER DELETED MESSAGE ; BP-2 MSG # TO RECOVER ; BP-4 MSGINX OFFSET TO INSERT RECOVERED MSG ; BP-6 BLOCK NUMBER OF INSERTED RECORD ;--------------------------------------------------------- RECMSG: CALL TAYSOP ;AUTHORIZED CALLER? JNZ RECM00 ;OK JMP MMENU2 ;UNKNOWN COMMAND RECM00: CMP MSGUCNT,0 ;FILE IN USE? JZ RECM05 ;NO MOV AX,110 ;FILE IN USE CALL WMSGNO ;TELL OPERATOR JMP MMENU1 ;EXIT RECM05: PUSH BP ;SAVE CALLER'S FRAME MOV BP,SP ;ALLOCATE LOCAL FRAME SUB SP,6 ;ALLOCATE LOCAL VARIABLES MOV MSGUCNT,-1 ;LOCK FILE RECM10: CALL DQCMD ;GET MESSAGE NUMBER JNC RECM20 ;GOT IT MOV AX,362 ;MSG TO RECOVER CALL QMSGNO ;ASK OPERATOR JNC RECM10 ;DEQUEUE MSG RECM9J: JMP RECM55 ;LOST CARRIER RECM20: MOV CX,[SI-2] ;RESPONSE LENGTH JCXZ RECM9J ;EXIT CALL ASCBIN ;CONVERT TO BINARY MOV [BP-2],AX ;MSG NUMBER TO RECOVER OR AX,AX ;ANYTHING? JZ RECM9J ;NO - EXIT MOV DI,MSGINX1 ;MSG # INDEX MOV CX,DS:MSGCKPT+MILAST ;LAST ARRAY ENTRY ADD CX,2 ;POINT PAST END JZ RECM40 ;LIST IS EMPTY SHR CX,1 ;CONVERT LENGTH TO ENTRIES RECM30: CMP AX,[DI] ;LOOK FOR MATCH JZ RECM9J ;MSG WAS NOT DELETED JB RECM40 ;MSG GOES HERE ADD DI,2 ;NEXT ENTRY LOOP RECM30 ;TRY NEXT ENTRY RECM40: SUB DI,MSGINX1 ;OFFSET IN TABLE MOV [BP-4],DI ;MESSAGE GOES HERE SUB DI,2 ;LAST LOWER ENTRY JNC RECM48 ;VALID ENTRY XOR AX,AX ;CLEAR WORK REG CMP DS:MSGCKPT+MVERS,0 ;OLD VERSION? JZ RECM42 ;YES - NO INDEX MOV AX,DS:MSGCKPT+MDIMAX ;INDEX BLOCKS MOV CL,5 ;SHIFT FACTOR SHR AX,CL ;CONVERT TO RECORDS RECM42: INC AX ;ALLOW FOR HEADER JMP SHORT RECM50 ;GO READ FILE RECM48: PUSH BX MOV BX,MSGINX2 ;BLOCK INDEX MOV AX,[BX+DI] ;BLOCK NUMBER POP BX RECM50: MOV WORD PTR [BX+USRMP],AX ;BLOCK TO READ RECM52: CALL READM ;READ BLOCK JNZ RECM55 ;END OF FILE MOV AX,WORD PTR [SI+MMNUMB] ;MESSAGE NUMBER CMP AX,[BP-2] ;THIS MESSAGE? JZ RECM60 ;YES JNB RECM55 ;CAN'T FIND MESSAGE MOV AX,WORD PTR [SI+MRSIZE] ;SIZE OF THIS MESSAGE ADD WORD PTR [BX+USRMP],AX ;POINT TO NEXT MESSAGE JMP RECM52 ;TRY NEXT MESSAGE RECM55: MOV AX,364 ;ERROR MSG CALL WMSGNO ;TELL USER JMP SHORT RECM90 ;EXIT RECM60: MOV BYTE PTR [SI+MDFLAG],0E1H ;MARK MESSAGE LIVE MOV WORD PTR [SI+MFPTR1],0 ;CLEAR FORWARD POINTER MOV AX,WORD PTR [BX+USRMP] ;BLOCK NUMBER MOV [BP-6],AX ;BLOCK TO INSERT MOV AX,DS:MSGCKPT+MIACTM ;ACTIVE MESSAGE COUNT CMP AX,DS:MSGCKPT+MDIMAX ;MAXIMUM MSGS JNB RECM55 ;TOO MANY MESSAGE CALL WRITM ;UPDATE MESSAGE INC DS:MSGCKPT+MIACTM ;ACTIVE MESSAGE COUNT INC ADDCNT ;SHOW MESSAGE ADDED CALL ATOINX ;RESTORE 'TO' INDEX ENTRY MOV SI,MSGINX1 ;MESSAGE NUMBER ARRAY MOV DI,MSGINX2 ;BLOCK NUMBER ARRAY ADD DS:MSGCKPT+MILAST,2 ;NEW LAST ENTRY MOV CX,DS:MSGCKPT+MILAST ;LAST ENTRY SUB CX,[BP-4] ;BYTES TO MOVE SHR CX,1 ;ENTRIES TO MOVE PUSH BX MOV BX,DS:MSGCKPT+MILAST ;OFFSET LAST ENTRY JCXZ RECM67 ;LAST ENTRY RECM65: SUB BX,2 ;PREVIOUS BUCKET MOV AX,[BX+SI] ;MSG NUMBER MOV [BX+SI+2],AX ;MOVE UP MOV AX,[BX+DI] ;BLOCK NUMBER MOV [BX+DI+2],AX ;MOVE UP LOOP RECM65 ;KEEP IT MOVING RECM67: MOV AX,[BP-2] ;THIS MSG NUMBER MOV [BX+SI],AX ;INSERT IT MOV AX,[BP-6] ;THIS BLOCK NUMBER MOV [BX+DI],AX ;INSERT IT POP BX MOV AX,363 ;SUCCESSFUL RECOVERY CALL WMSGNO ;TELL OPERATOR RECM90: MOV MSGUCNT,0 ;SHOW FILE AVAILABLE CALL PKINX ;FORCE UPDATE OF INDEX MOV SP,BP ;FREE LOCAL STORAGE POP BP ;RESTORE CALLER'S FRAME JMP MMENU1 ;MAIN MENU ;--------------------------------------------------------- ;LIST FORMATTED MESSAGE HEADERS ;--------------------------------------------------------- LISTMH: CALL TAYSOP ;AUTHORIZED CALLER? JNZ LIST10 ;OK JMP MMENU2 ;UNKNOWN COMMAND LIST10: JMP NOTYET ;--------------------------------------------------------- ;ARCHIVE CALLERS LOG ;--------------------------------------------------------- ARCLOG: CALL TSYSOP ;AUTHORIZED CALLER? JNZ ARCL10 ;OK JMP MMENU2 ;UNKNOWN COMMAND ARCL10: PUSH BP ;SAVE CALLER'S FRAME MOV BP,SP ;ESTABLISH LOCAL FRAME SUB SP,6 ;ALLOCATE LOCAL STORAGE ;TRY TO OPEN ARCHIEVE FILE MOV AX,3D01H ;OPEN FOR OUTPUT MOV DX,OFFSET CALOFN ;ARCHIEVE FILE NAME PUSH DS PUSH ES POP DS INT 21H ;DOS REQUEST POP DS JNC ARCL20 ;OPEN OK CMP AX,2 ;NOT FOUND? JZ ARCL15 ;MUST CREATE IT ARCL13: ERR 8 ARCL15: MOV AH,3CH ;CREATE FILE XOR CX,CX ;NORMAL ATTRIBUTE PUSH DS PUSH ES POP DS INT 21H ;DOS REQUEST POP DS JC ARCL13 ;CAN NOT CREATE FILE MOV [BP-4],AX ;FILE HANDLE JMP SHORT ARCL30 ;GO OPEN INPUT FILE ARCL20: MOV [BP-4],AX ;FILE HANDLE MOV AX,4202H ;SEEK END OF FILE PUSH BX MOV BX,[BP-4] ;FILE HANDLE MOV CX,-1 ;EOF -1 MOV DX,CX ;FILE OFFSET INT 21H ;DOS CALL POP BX JC ARCL13 ;BAD RETURN ARCL30: MOV AX,3D00H ;OPEN FOR INPUT MOV DX,OFFSET CALLRN ;CALLER FILE PUSH DS PUSH ES POP DS INT 21H ;DOS REQUEST POP DS JNC ARCL35 ;GOOD OPEN JMP ARCL60 ;RESET FILE ARCL35: MOV [BP-2],AX ;FILE HANDLE MOV AX,512 ;FILE BUFFER SIZE CALL GETBUF ;GET FILE BUFFER MOV [BP-6],SI ;BUFFER ADDRESS ARCL40: MOV AH,3FH ;READ REQUEST MOV DX,[BP-6] ;READ ADDRESS MOV CX,512 ;READ LENGTH PUSH BX MOV BX,[BP-2] ;INPUT FILE HANDLE INT 21H ;DOS REQUEST POP BX JC ARCL13 ;PROBLEMS CMP AX,0 ;END OF FILE? JZ ARCL50 ;YES - DONE MOV CX,AX ;DATA LENGTH MOV AH,40H ;WRITE REQUEST PUSH BX MOV BX,[BP-4] ;OUTPUT FILE HANDLE INT 21H ;DOS REQUEST POP BX JC ARCL13 ;PROBLEMS CMP AX,CX ;WRITE ENOUGH BYTES? JNZ ARCL13 ;NO JMP ARCL40 ;NEXT SECTOR ARCL50: MOV AH,3EH ;CLOSE FUNCTION PUSH BX MOV BX,[BP-4] ;OUTPUT FILE HANDLE INT 21H ;DOS REQUEST MOV AH,3EH ;CLOSE FUNCTION MOV BX,[BP-2] ;INPUT FILE HANDLE INT 21H ;DOS REQUEST POP BX MOV SI,[BP-6] ;BUFFER ADDRESS CALL FREBUF ;FREE BUFFER ;RESET INPUT FILE TO ZERO LENGTH ARCL60: MOV AH,3CH ;CREATE FUNCTION MOV DX,OFFSET CALLRN ;CALLERS FILE NAME XOR CX,CX ;NORMAL ATTRIBUTE PUSH DS PUSH ES POP DS INT 21H ;DOS REQUEST POP DS PUSH BX MOV BX,AX ;FILE HANDLE MOV AH,3EH ;CLOSE FUNCTION INT 21H ;DOS REQUEST POP BX MOV SP,BP ;FREE LOCAL STORAGE POP BP ;RESTORE CALLER'S FRAME JMP MMENU1 ;MAIN MENU ;--------------------------------------------------------- ;USER FILE MAINTENANCE FUNCTIONS ; BP-2 FUNCTION CODE & FLAGS ; 0=LIST ALL ENTRIES ; 1=PRINT ALL ENTRIES ; 2=MODIFY ENTRIES ; 3=PRINT THIS ENTRY ; 4=DISPLAY SECTION 0 ; 8=HOLDING USER RECORD ; BP-4 ADDRESS OF USER RECORD ; BP-6 CURRENT USER BLOCK NUMBER ; BP-8 FIRST USER BLOCK NUMBER ; BP-10 SECTION MASK ;--------------------------------------------------------- USERFM: MOV AX,-1 ;ALL SECTIONS CALL TSIGOP ;AUTHORIZED CALLER? JNZ USER10 ;YES JMP MMENU2 ;UNKNOWN COMMAND USER10: MOV AX,112 ;LIST, PRINT, OR MODIFY CALL QMSGNO JNC USER15 ;GOOD RESPONSE USERJX: JMP MMENU1 ;LOST CARRIER USER15: CALL DQCMD ;GET RESPONSE CALL XLATE ;MAKE UPPER CASE CMP WORD PTR [SI-2],0 ;NULL RESPONSE JZ USERJX ;EXIT FRAME 5 XOR AX,AX MOV [BP-2],AX ;DEFAULT TO LIST MOV [BP-4],AX ;NO BUFFER YET CMP USRINXA,0 ;ANY INDEX? JZ USER21 ;NO MOV AX,USRINXL ;INDEX LENGTH INC AX ;BASE 1 MOV CX,6 ;SHIFT FACTOR SHR AX,CL ;CONVERT TO BLOCKS INC AX ;ALLOW FOR CONTROL REC USER21:MOV [BP-6],AX ;DEFAULT TO 1ST USER MOV [BP-8],AX ;1ST USER RECORD LODSB ;GET RESPONSE CMP AL,'L' ;LIST? JZ USER30 ;YES - DEFAULT CMP AL,'P' ;PRINT? JNZ USER22 ;NO OR WORD PTR [BP-2],1 ;MARK FOR PRINT OR WORD PTR [BX+CBFLG],SFNOPL ;NO 'MORE' PROMPTS JMP SHORT USER30 USER22: CMP AL,'M' ;MODIFY? JZ USER24 ;YES JMP USER90 ;NO - INVALID USER24: OR WORD PTR [BP-2],2 ;MARK FOR MODIFY MOV AX,DS:MSGCKPT+MLASTU ;LAST ENTRY MOV DX,[BP-8] ;LOWEST VALID ENTRY AND DX,1 ;ODD OR EVEN? OR AX,DX ;FORCE BOUNDRY ALIGNMENT MOV [BP-6],AX ;START WITH LAST ENTRY USER30: CALL VALSEC ;GET VALID SECTIONS MOV DX,AX ;REMEMBER MOV SI,60 ;SECTION NUMBER PROMPT CALL PSECNO ;SECTION NUMBERS MOV [BP-10],AX ;SECTIONS TO SEARCH OR AX,AX ;SECTION ZERO SPECIFIED? JZ USER35 ;YES - FLAG IT CMP AX,DX ;DEFAULT RESPONSE? JNZ USER40 ;NO - TURN OF SECTION 0 USER35: OR WORD PTR [BP-2],4 ;SET SECTION ZERO DISPLAY USER40: CALL CKCTLK ;CTL K? JC USEJ90 ;YES - ABORT LISTING MOV AX,[BP-6] ;BLOCK NUMBER CALL GETUSR ;READ USER RECORD USE40A: MOV [BP-4],SI ;POINTER TO RECORD JNC USER41 ;GOOD READ USEJ90: JMP USER90 ;END OF FILE USER41: MOV DI,[BP-4] ;ADDRESS RECORD OR WORD PTR [BP-2],8 ;SHOW RECORD HELD CMP BYTE PTR [DI],0 ;DELETED ENTRY? JNZ USER42 ;NO PROBLEM USE41A: JMP USE51A ;YES - SKIP USER42: MOV AX,WORD PTR [DI+UESECT] ;MESSAGE SECTION FLAGS OR AX,AX ;ANY SECTION? JNZ USE42A ;NO PROBLEM TEST WORD PTR [BP-2],4 ;DISPLAY SECT 0? JNZ USE42B ;YES USE42A: AND AX,[BP-10] ;MATCH SECTION? JZ USE41A ;NO - SKIP CALL TSIGOP ;CONTROL THIS USER? JZ USE41A ;NO - SKIP RECORD USE42B: CALL ILINEB ;FORMAT BUFFER MOV AX,[BP-6] ;USER BLOCK NUMBER SUB AX,[BP-8] ;RELATIVE ENTRY NUMBER SHR AX,1 ;ADJUST FOR BLOCK SIZE MOV CX,4 ;ALLOW 4 DIGITS CALL BINASC MOV AL,':' CALL APPBYT ;ADD TO STRING INC WORD PTR [SI-2] ;DELIMITER MOV CX,UELNK-UENAM-1 ;LENGTH OF USER NAME CALL MOVSTL ;MOVE NAME TEST BYTE PTR [DI+UESTAT],80H ;LOCKED OUT? JZ USER43 ;NO MOV AX,267 ;LOCKED OUT CALL MOVMSG ;MOVE TO BUFFER JMP USER48 ;SKIP STATISTICS USER43: MOV DI,[BP-4] ADD DI,UEMEMO ;SYSOP DEFINED FIELD MOV CX,UEUPLD-UEMEMO CALL MOVSTL INC WORD PTR [SI-2] ;DELIMITER MOV DI,[BP-4] ADD DI,UEGID ;GROUPID MOV CX,8 ;GID LENGTH CALL MOVSTL CALL PRMSG ;DISPLAY MSG JNC USER44 ;OK JMP USER90 ;NO MORE USER44: CALL ILINEB ;FORMAT BUFFER ADD WORD PTR [SI-2],9 ;INDENT MOV AX,279 ;AUTH= CALL MOVMSG ;MOVE TO BUFFER MOV DI,[BP-4] ;USER RECORD MOV AL,'N' ;ASSUME NONE TEST BYTE PTR [DI+UESTAT],31H ;ANY? JZ USER45 ;NO MOV AL,'L' ;ASSUME LIMITED TEST BYTE PTR [DI+UESTAT],10H ;CORRECT? JNZ USER45 ;YES MOV AL,'S' ;ASSUME SIGOP TEST BYTE PTR [DI+UESTAT],1 ;CORRECT? JNZ USER45 ;YES MOV AL,'G' ;MUST BE GLOBAL USER45: CALL APPBYT ;ADD TO STRING MOV AL,' ' ;ASSUME NO RESTRICTION TEST BYTE PTR [DI+UESTAT],40H JZ USER46 ;CORRECT MOV AL,'R' ;RESTRICTED USER46: CALL APPBYT ;ADD TO STRING TEST BYTE PTR [DI+UESTAT2],8 ;MANUAL DELETE? JZ USR46B ;NO MOV AL,'K' ;KEEP USER FLAG CALL APPBYT ;ADD TO DISPLAY USR46B: MOV AX,278 ;MSECT= CALL MOVMSG ;MOVE TO BUFFER MOV DI,[BP-4] ;USER RECORD MOV AX,WORD PTR [DI+UESECT] ;SECTION BIT MASK CALL HEXSTR ;DISPLAY AS HEX MOV AX,361 ;FLAGS= CALL MOVMSG ;MOVE TO BUFFER MOV DI,[BP-4] ;USER RECORD MOV AX,WORD PTR [DI+UESIGS] ;SECTION BIT MASK CALL HEXSTR ;DISPLAY AS HEX MOV AX,268 ;PW= CALL MOVMSG ;MOVE TO BUFFER MOV DI,[BP-4] ;USER RECORD MOV AL,'Y' ;ASSUME YES CMP WORD PTR [DI+UEPSWD],0 ;PASSWORD EXIST? JNZ USR46A ;YES MOV AL,'N' ;NO PASSWORD USR46A: CALL APPBYT ;DISPLAY MOV AX,269 ;TIMES ON CALL MOVMSG ;MOVE TO BUFFER MOV DI,[BP-4] ;USER RECORD MOV AX,WORD PTR [DI+UETIMO] ;TIMES ON CALL BINASP MOV AX,270 ;LMSG CALL MOVMSG ;MOVE TO BUFFER MOV DI,[BP-4] ;USER RECORD MOV AX,WORD PTR [DI+UELMSG] ;LAST MESSAGE CALL BINASP MOV AX,303 ;'TIME=' CALL MOVMSG ;MOVE TO BUFFER XOR AX,AX ;ASSUME 0 MOV DI,[BP-4] ;USER RECORD TEST BYTE PTR [DI+UESTAT],2 ;FIXED TIME? JZ USER47 ;NO MOV AX,WORD PTR [DI+UERTIM] ;TIME ALLOCATION USER47: CALL BINASP ;PUT IN BUFFER CALL PRMSG ;OUTPUT MESSAGE JNC USE47A ;OK JMP USER90 ;NO MORE USE47A: CALL ILINEB ;FORMAT BUFFER ADD WORD PTR [SI-2],14 ;INDENT MOV DI,[BP-4] ;USER RECORD MOV CX,WORD PTR [DI+UELDAT] ;YEAR MOV DX,WORD PTR [DI+UELDAT+2] ;MONTH & DAY CALL DTEASC ;PUT IN STRING INC WORD PTR [SI-2] ;LEAVE BLANK MOV CX,WORD PTR [DI+UELTIM] ;HOURS & MINUTES MOV DX,WORD PTR [DI+UELTIM+2] ;SECONDS CALL TIMHM ;PUT IN STRING INC WORD PTR [SI-2] ;DELIMITER MOV AX,271 ;UPLOAD CALL MOVMSG ;MOVE TO BUFFER MOV AX,WORD PTR [DI+UEUPLD] ;UPLOAD COUNT MOV CX,4 CALL BINASC MOV AX,272 ;DNLD CALL MOVMSG ;MOVE TO BUFFER MOV AX,WORD PTR [DI+UEDNLD] ;DOWNLOAD COUNT MOV CX,4 CALL BINASC MOV AX,273 ;MSGR CALL MOVMSG ;MOVE TO BUFFER MOV AX,WORD PTR [DI+UEMSGR] ;MESSGES READ MOV CX,4 CALL BINASC MOV AX,274 ;MSGE CALL MOVMSG ;MOVE TO BUFFER MOV AX,WORD PTR [DI+UEMSGE] ;MESSAGES ENTERED MOV CX,4 CALL BINASC MOV AX,275 ;MSGK CALL MOVMSG ;MOVE TO BUFFER MOV AX,WORD PTR [DI+UEMSGK] ;MESSAGES KILLED MOV CX,4 CALL BINASC USER48: CALL PRMSG ;OUTPUT MESSAGE JNC USE48A ;OK JMP USER90 ;NO MORE USE48A: MOV DI,[BP-4] ;USER RECORD TEST BYTE PTR [DI+UESTAT],12 ;REG PENDING OR DENIED? JZ USER50 ;NO PROBLEM TEST BYTE PTR [DI+UESTAT],8 ;PENDING? MOV AX,131 ;ASSUME PENDING JNZ USER49 ;CORRECT MOV AX,132 ;DENIED USER49: CALL PRMSGN ;OUTPUT MSG JNC USER50 ;OK JMP USER90 ;NO MORE USER50: CALL ILINEB ;EMPTY BUFFER CALL PRMSG ;OUTPUT MSG JNC USE50A ;OK JMP USER90 ;NO MORE USE50A: MOV DI,[BP-4] ;USER RECORD TEST BYTE PTR [DI+UESTAT],20H ;GLOBAL SYSOP? JZ USER51 ;NO PROBLEM CALL TSYSOP ;ARE WE ONE TOO? JNZ USER51 ;YES JMP USE51A ;DO NOT ALLOW CHANGES USER51: TEST WORD PTR [BP-2],2 ;MODIFY? JNZ USE51B ;YES USE51A: MOV AX,[BP-6] ;USER RECORD NUMBER CALL FREUSR ;FREE IT AND WORD PTR [BP-2],NOT 8 ;SHOW RECORD FREE JMP USER60 ;DO NEXT ENTRY USE51B: AND WORD PTR [BP-2],-2 ;TURN OFF PRINT MOV AX,113 ;DELETE ... USER CALL QMSGNO JNC USER52 ;GOOD READ JMP USER90 ;LOST CARRIER USER52: CALL DQCMD ;GET RESPONSE CMP WORD PTR [SI-2],0 ;NULL RESPONSE? JZ USE51A ;PREVIOUS BLOCK CMP BYTE PTR [SI],'0' ;LOWEST NUMERIC JB USER54 ;NOT NUMERIC CMP BYTE PTR [SI],'9' ;HIGHEST NUMERIC JA USER54 ;NOT NUMERIC MOV AX,[BP-6] ;USER RECORD NUMBER CALL FREUSR ;FREE IT AND WORD PTR [BP-2],NOT 8 ;SHOW RECORD FREE MOV CX,4 ;MAXIMUM FIELD WIDTH MOV SI,WORD PTR [BX+USRCMD] ;COMMAND BUFFER CALL ASCBIN ;GET VALUE SHL AX,1 ;ADJUST FOR BLOCK SIZE ADD AX,[BP-8] ;PHYSICAL BLOCK # MOV [BP-6],AX ;SET FOR READ JMP USER40 ;GET SPECIFIED RECORD USER54: CALL XLATE ;MAKE UPPER CASE CMP WORD PTR [SI-2],5 ;NAME? JB USER57 ;NO MOV AX,[BP-6] ;USER RECORD NUMBER CALL FREUSR ;FREE IT AND WORD PTR [BP-2],NOT 8 ;SHOW RECORD FREE MOV CX,UELNK-UENAM ;MAX LENGTH MOV SI,WORD PTR [BX+USRCMD] ;COMMAND BUFFER CALL PADB ;PAD WITH BLANKS CALL STRIP ;RESET LENGTH CALL RDUSER ;GET BLOCK NUMBER JNB USER56 ;FOUND NAME JMP USER51 ;CAN'T FIND NAME USER56: MOV [BP-6],AX ;SET BLOCK NUMBER JMP USE40A ;DISPLAY ENTRY USER57: LODSB ;GET COMMAND CHAR MOV DI,OFFSET CTBLS1 ;VALID COMMAND STRING MOV CX,(JTBLS1-CTBLS1) ;TABLE LENGTH REPNZ SCASB ;CHECK FOR MATCH JZ USE57A ;OK JMP USER51 ;NOT VALID USE57A: SUB DI,OFFSET CTBLS1+1 ;OFFSET IN TABLE SHL DI,1 ;TABLE WIDTH JMP JTBLS1[DI] ;GO TO ROUTINE USER58: MOV AX,[BP-6] ;SLOT # CALL UPDUSR ;WRITE USER RECORD CALL LABWIN ;UPDATE WINDOW LABEL JMP USER41 ;RE-DISPLAY ENTRY USER60: TEST WORD PTR [BP-2],2 ;MODIFY? JNZ USER61 ;YES - GO BACKWARDS ADD WORD PTR [BP-6],2 ;NEXT BLOCK JMP USER40 ;GET NEXT ENTRY USER61: SUB WORD PTR [BP-6],2 ;PREVIOUS BLOCK MOV AX,[BP-6] ;NEW BLOCK CMP AX,[BP-8] ;LOWEST VALID BLOCK JB USER6A ;EXIT JMP USER40 ;DISPLAY ENTRY USER6A: JMP USER90 ;EXIT USER62: OR WORD PTR [BP-2],1 ;TURN ON PRINT JMP USER41 ;DISPLAY SAME ENTRY ;DELETE USER USER64: CALL TAYSOP ;SYSOP? JNZ USER65 ;YES JMP USER41 ;DON'T ALLOW DELETE USER65: MOV DI,[BP-4] ;USER RECORD XOR AX,AX MOV CX,UELNK-UENAM ;LENGTH OF NAME PUSH ES PUSH DS POP ES REP STOSB ;CLEAR NAME POP ES JMP USER58 ;RE-WRITE RECORD USER66: MOV DI,[BP-4] ;USER RECORD XOR BYTE PTR [DI+UESTAT],80H ;LOCKED OUT JMP USER58 ;WRITE RECORD USER68: MOV AX,114 ;NEW PASSWORD CALL QMSGNO JNC USER69 ;GOOD READ JMP USER90 ;LOST CARRIER USER69: CALL DQCMD ;GET RESPONSE CMP WORD PTR [SI-2],0 ;NULL STRING? JZ USER60 ;YES - NO ACTION CALL STRIP ;STRIP TRAILING BLANKS MOV AX,WORD PTR [SI-2] ;LENGTH OR AX,AX ;WAS ALL BLANKS? JZ USE69A ;YES CALL XLATE ;UPPER CASE MOV CX,15 ;MAX PASSWORD LENGTH CALL PADB ;PAD TO LENGTH CALL CRCCLC ;ENCRYPT USE69A: MOV DI,[BP-4] ;USER RECORD MOV WORD PTR [DI+UEPSWD],AX ;STORE IN RECORD JMP USER58 ;WRITE RECORD USER70: MOV AX,116 ;GROUPID CALL QMSGNO JNC USER71 ;GOOD READ JMP USER90 ;LOST CARRIER USER71: CALL DQCMD ;GET RESPONSE CALL XLATE ;UPPER CASE MOV CX,8 ;GID LENGTH CALL PADB ;PAD TO LENGTH MOV DI,[BP-4] ;USER RECORD ADD DI,UEGID ;GID OFFSET PUSH ES PUSH DS POP ES REP MOVSB ;MOVE TO STRING POP ES JMP USER58 ;WRITE RECORD USER74: MOV AX,115 ;SYSOP AUTHORITY CALL QMSGNO JNC USER76 ;GOOD READ JMP USER90 ;LOST CARRIER USER76: CALL DQCMD ;GET RESPONSE CALL XLATE ;UPPER CASE LODSB ;GET CHAR XOR AH,AH ;ASSUME NONE CMP AL,'N' ;NONE? JZ USER78 ;GO SET NONE MOV AH,10H ;LIMITED CMP AL,'L' ;IS IT? JZ USER78 ;YES MOV AH,20H ;GLOBAL CMP AL,'G' ;IS IT JZ USER78 ;YES MOV AH,1 ;SIGOP CMP AL,'S' ;IS IT? JZ USER78 ;YES JMP USER74 ;REPEAT PROMPT USER78: MOV DI,[BX+USRST] ;INVOKER'S USER RECORD MOV AL,BYTE PTR [DI+UESTAT] ;STATUS FIELD AND AL,31H ;AUTHORITY BITS TEST AL,10H ;LOCAL AUTHORITY? JZ USE78A ;NO OR AL,1 ;SIGOP AUTHORITY USE78A: TEST AL,20H ;GLOBAL AUTHORITY? JZ USE78B ;NO OR AL,11H ;LOCAL AND SIGOP AUTHORITY USE78B: AND AH,AL ;CAN NOT AUTHORIZE HIGHER CMP BYTE PTR [SI],'R' ;RESTRICT TO CONSOLE? JNZ USER79 ;NO OR AH,40H ;FLAG AS RESTRICTED USER79: MOV DI,[BP-4] ;USER RECORD AND BYTE PTR [DI+UESTAT],8EH OR BYTE PTR [DI+UESTAT],AH ;SET NEW AUTHORITY JMP USER58 ;WRITE RECORD ;AUTHORIZE MESSAGE SECTIONS USER80: MOV SI,123 ;SECTION # PROMPT MOV DI,[BP-4] ;USER RECORD MOV AX,[DI+UESECT] ;CURRENT SECTION #S CALL PSECNO ;GET NEW VALUE JC USER85 ;INVALID RESPONSE CALL TAYSOP ;LOCAL SYSOP? JNZ USER82 ;YES MOV SI,[BX+USRST] ;INVOKERS USER RECORD MOV DX,[SI+UESIGS] ;SIGS CONTROLLED AND DX,DS:MSGCKPT+MDSIGS ;VALID SECTIONS AND AX,DX ;SECTIONS TO ADD NOT DX ;SECTIONS TO KEEP AND DX,[DI+UESECT] ;PREVIOUS SECTIONS OR AX,DX ;NEW SECTIONS USER82: MOV [DI+UESECT],AX ;SET NEW VALUE JMP USER58 ;UPDATE RECORD USER85: JMP USER41 ;RE-DISPLAY RECORD USER90: TEST WORD PTR [BP-2],8 ;HOLDING RECORD? JZ USER92 ;NO - DON'T FREE AGAIN MOV AX,[BP-6] ;USER RECORD NUMBER CALL FREUSR ;FREE IT USER92: EXITF MMENU1 ;VALIDATE NEW USER REGISTRATION USE100: MOV DI,[BP-4] ;USER RECORD AND BYTE PTR [DI+UESTAT],255-12 ;CLEAR PENDING & DENIED JMP USER58 ;UPDATE RECORD USE110: MOV DI,[BP-4] ;USER RECORD AND BYTE PTR [DI+UESTAT],255-8 ;CLEAR PENDING OR BYTE PTR [DI+UESTAT],4 ;SET DENIED JMP USER58 ;UPDATE RECORD ;SET USER TIME LIMIT USE120: CALL DQCMD ;INPUT AVAILABLE? JNC USE122 ;YES USE121: CALL ILINEB ;INIT BUFFER MOV AX,303 ;'TIME=' CALL MOVMSG ;MOVE TO BUFFER CALL QUERY ;GET RESPONSE JNC USE120 ;GOOD RESPONSE JMP USER90 ;EXIT USE122: MOV CX,WORD PTR [SI-2] ;RESPONSE LENGTH JCXZ USER85 ;NULL RESPONSE CALL ASCBIN ;GET VALUE MOV DI,[BP-4] ;USER RECORD AND BYTE PTR [DI+UESTAT],NOT 2 ;CLEAR FIXED TIME FLAG OR AX,AX ;SET TIME TO AUTO? JZ USE123 ;YES OR BYTE PTR [DI+UESTAT],2 ;SHOW FIXED TIME USE123: MOV WORD PTR [DI+UERTIM],AX ;SET NEW TIME JMP USER58 ;UPDATE RECORD USE130: MOV DI,[BP-4] ;USER RECORD PUSH DI ;PASS AS PARM CALL UPAR00 ;USER PARM ROUTINE JMP USER58 ;UPDATE RECORD ;SET SECURITY FLAGS USE140: MOV SI,123 ;SECTION # PROMPT MOV DI,[BP-4] ;USER RECORD MOV AX,[DI+UESIGS] ;CURRENT SECTION #S CALL PSECNO ;GET NEW VALUE JC USE145 ;INVALID RESPONSE MOV [DI+UESIGS],AX ;SET NEW VALUE JMP USER58 ;UPDATE RECORD USE145: JMP USER41 ;RE-DISPLAY RECORD USE150: MOV DI,[BP-4] ;USER RECORD XOR BYTE PTR [DI+UESTAT2],8 ;FLIP MANUAL DELETE FLAG JMP USER58 ;UPDATE RECORD PRMSGN: CALL ILINEB ;INIT LINE BUFFER CALL MOVMSG ;GET MESSAGE IN BUFFER PRMSG: CALL WRMSG ;DISPLAY ON SCREEN JC PRMSGC ;NO MORE TEST WORD PTR [BP-2],1 ;PRINTER ON? JNZ PRMSG0 ;YES PRMSGC: RET PRMSG0: TEST WORD PTR [BX+CBMDM],MDMKBD ;LOCAL? JZ PRMSGC ;NO - DON'T PRINT PUSH AX PUSH DX PUSH SI PUSH CX XOR DX,DX ;SELECT PRINTER 1 MOV CX,WORD PTR [SI-2] ;LENGTH JCXZ PRMSG2 ;NULL STRING PRMSG1: LODSB ;GET CHAR MOV AH,0 ;PRINT FUNCTION INT 17H ;PRINT CHAR TEST AH,29H ;ANY ERROR? JNZ PRMSGX ;YES - EXIT LOOP PRMSG1 ;REST OF STRING PRMSG2: MOV AX,13 ;C/R INT 17H ;PRINT CHAR MOV AX,10 ;LINE FEED INT 17H ;PRINT CHAR PRMSGX: POP CX POP SI POP DX POP AX RET ;---------------------------------------------------------- ;EDIT SYSTEM MESSAGES ; BP-2 FLAGS ; 0=LIST ALL ENTRIES ; 1=PRINT ALL ENTRIES ; 2=MODIFY ENTRIES ; 4=STRING IN PROCESS ; 8=NEED DELIMITER ; BP-4 HIGH SYSTEM MESSAGE NUMBER ; BP-6 MESSAGE BUFFER ; BP-8 HIGH MERGE MESSAGE NUMBER ; BP-10 available ; BP-12 OUTPUT FILE HANDLE ; BP-14 CURRENT SYSTEM MSG NUMBER ; BP-16 CURRENT MERGE MSG NUMBER ; BP-18 MERGE FILE BUFFER ; BP-20 OUTPUT FILE BUFFER ; bp-22 Position in Line Buffer ; bp-24 File Header ; bp-26 File position ;--------------------------------------------------------- SYSMSG: CALL TSYSOP ;AUTHORIZED CALLER? JNZ SYSM10 ;YES JMP MMENU2 ;UNKNOWN COMMAND SYSM10: MOV AX,112 ;LIST, PRINT, OR MODIFY CALL QMSGNO JNC SYSM20 ;GOOD RESPONSE SYSMJX: JMP MMENU1 ;LOST CARRIER SYSM20: CALL DQCMD ;GET RESPONSE CALL XLATE ;MAKE UPPER CASE CMP WORD PTR [SI-2],0 ;NULL RESPONSE JZ SYSMJX ;EXIT PUSH BP ;SAVE CALLER'S FRAME MOV BP,SP ;ESTABLISH LOCAL FRAME SUB SP,26 ;ALLOCATE LOCAL STORAGE XOR AX,AX MOV [BP-2],AX ;DEFAULT TO LIST CMP BYTE PTR [SI],'L' ;LIST? JZ SYSM30 ;YES - DEFAULT OK CMP BYTE PTR [SI],'P' ;PRINT? JNZ SYSM22 ;NO MOV WORD PTR [BP-2],1 ;MARK FOR PRINT OR WORD PTR [BX+CBFLG],SFNOPL ;NO 'MORE' PROMPTS JMP SHORT SYSM30 SYSM22: CMP BYTE PTR [SI],'M' ;MODIFY? JZ SYSM24 ;YES JMP SYSM90 ;NO - INVALID SYSM24: MOV WORD PTR [BP-2],2 ;MARK FOR MODIFY SYSM30: PUSH ES MOV ES,MSGSEG ;MESSAGE SEGMENT MOV AX,ES:[0] ;HIGH MESSAGE NO. MOV [BP-4],AX POP ES XOR AX,AX MOV [BP-6],AX ;NO BUFFER YET MOV [BP-8],AX ;NOT IN STRING MOV [BP-10],AX ;NO INPUT FILE MOV [BP-12],AX ;NO OUTPUT FILE MOV WORD PTR [BP-14],1 ;CURRENT MSG NUMBER mov [bp-18],ax ;no merge file buffer mov [bp-26],ax ;Output file position TEST WORD PTR [BP-2],2 ;MODIFY? JZ SYSM40 ;NO JMP SYSM60 ;ENTER MERGE CODE ;LIST OR PRINT CCMSG.DAT SYSM40: MOV SI,[BP-6] ;OLD MESSAGE BUFFER CALL FREBUF ;FREE IT MOV WORD PTR [BP-6],0 ;SHOW FREE MOV AX,[BP-14] ;NEXT MESSAGE NUMBER CMP AX,[BP-4] ;END OF MESSAGES? JBE SYSM41 ;NOT YET JMP SYSM90 ;EXIT SYSM41: CALL ILINEB ;GET LINE BUFFER MOV DI,OFFSET STR01 ;MSG CALL MVCSTR ;PUT IN BUFFER MOV AX,[BP-14] ;MESSAGE NUMBER CALL BINASP ;APPEND DIGITS MOV WORD PTR [SI-2],8 ;TAB CALL GETMSG ;GET MSG IN [DI] MOV [BP-6],DI ;START OF MSG MOV CX,[DI-2] ;MESSAGE LENGTH SYSM42: CALL SYS110 ;CHECK SIZE CMP BYTE PTR [DI],'"' ;QUOTES? JZ SYSM43 ;SPECIAL CASE CMP BYTE PTR [DI],' ' ;NEXT CHAR PRINTABLE? JNB SYSM50 ;YES SYSM43: CALL SYS100 ;CLOSE STRING CALL SYS120 ;INSERT DELIMITER MOV AL,[DI] ;NON-PRINTABLE CHAR PUSH DI PUSH CX MOV DI,OFFSET SYTBL1 ;CONTROL CHARS MOV CX,SYTBL2-SYTBL1 ;TABLE LENGTH REPNZ SCASB ;LOOK FOR MATCH POP CX JNZ SYSM44 ;NOT IN TABLE SUB DI,OFFSET SYTBL1+1 ;OFFSET IN TABLE SHL DI,1 ;TABLE WIDTH MOV DI,SYTBL2[DI] ;STRING ADDRESS CALL MVCSTR ;MOVE TO BUFFER POP DI JMP SHORT SYSM45 ;END OF FIELD SYSM44: POP DI XOR AH,AH ;CBW CALL BINASP ;APPEND DIGITS SYSM45: OR WORD PTR [BP-2],8 ;NEED DELIMITER SYSM46: INC DI ;NEXT CHAR LOOP SYSM42 ;GO HANDLE ;END OF MESSAGE CALL SYS100 ;CLOSE STRING AND WORD PTR [BP-2],NOT 8 ;NO DELIMITER NEEDED CALL PRMSG ;DISPLAY LINE JNC SYSM48 ;OK JMP SYSM90 ;NO MORE SYSM48: INC WORD PTR [BP-14] ;NEXT MSG JMP SYSM40 ;HANDLE NEXT MESSAGE SYSM50: TEST WORD PTR [BP-2],4 ;ALREADY IN STRING? JNZ SYSM52 ;YES CALL SYS120 ;INSERT DELIMITER MOV AL,'"' ;QUOTE CALL APPBYT ;PUT IN BUFFER OR WORD PTR [BP-2],4 ;STRING IN PROCESS SYSM52: MOV AL,[DI] ;PRINTABLE CHARACTER CALL APPBYT ;PUT IN BUFFER JMP SYSM46 ;GO HANDLE NEXT CHAR ;UPDATE CCMSG.DAT SYSM60: MOV AX,3D00H ;INPUT CALL OPNLF ;OPEN LOCAL FILE JNC SYSM62 ;OK JMP SYSM90 ;EXIT SYSM62: MOV [BP-10],AX ;INPUT FILE HANDLE ;VALIDATE MERGE FILE MOV WORD PTR [BP-8],0 ;NO MESSAGE FOUND mov word ptr [bp-16],0 ;no current msg MOV AX,260 ;BUFFER SIZE CALL GETBUF ;GET BUFFER MOV [BP-18],SI ;MERGE FILE WORK BUFFER LEA DI,[SI+4] ;START OF DATA MOV [SI+2],DI ;CURRENT BUFFER POSITION mov ax,128 ;output buffer size call getbuf ;get buffer mov [bp-20],si ;remember SYSM64: mov si,[bp-20] ;output buffer mov word ptr [si-2],0 ;clear CALL SYS130 ;GET NEXT MESSAGE # JC SYSM70 ;END OF FILE mov ax,[bp-16] ;message number CMP AX,[BP-8] ;IN SEQUENCE? JAE SYSM66 ;YES CALL ILINEB ;INIT LINE BUFFER PUSH AX ;MERGE MESSAGE NUMBER MOV AX,389 ;'MESSAGE CALL MOVMSG ;MOVE TO BUFFER POP AX ;MESSAGE NUMBER CALL BINASP ;APPEND DIGITS MOV AX,390 ;'OUT OF SEQUENCE CALL MOVMSG ;MOVE TO BUFFER CALL WRMSG ;DISPLAY MESSAGE JMP SYSM90 ;EXIT SYSM66: MOV [BP-8],AX ;HIGHEST MESSAGE NUMBER JMP SYSM64 ;KEEP IT MOVING SYSM70: CMP WORD PTR [BP-8],0 ;ANY MESSAGES FOUND? JNZ SYSM72 ;YES MOV AX,388 ;INVALID FILE CALL WMSGNO ;DISPLAY MESSAGE JMP SYSM90 ;EXIT SYSM72: MOV AX,0 ;SEEK TO BEGINNING MOV CX,[BP-10] ;INPUT FILE HANDLE CALL SKBLK ;LSEEK ;delete old backup file mov dx,offset msgofn ;old backup name cmp testf,0 ;test system? jz sysm73 ;no mov dx,offset msgotn ;old test backup name sysm73: mov ah,41h ;delete file PUSH DS PUSH ES POP DS int 21h ;dos request POP DS ;rename current file mov ah,56h ;rename request mov dx,offset msgfiln ;live file mov di,offset msgofn ;backup name cmp testf,0 ;test system? jz sysm74 ;no mov dx,offset msgtfin ;test file mov di,offset msgotn ;backup name sysm74: PUSH DS PUSH ES POP DS int 21h ;dos request POP DS ;create new file mov ah,3ch ;create xor cx,cx ;normal attribute mov dx,offset msgfiln ;production file name cmp testf,0 ;test system? jz sysm75 ;no mov dx,offset msgtfin ;test file name sysm75: push ds push es pop ds int 21h ;dos request pop ds jnc sysm76 ;ok err 11H sysm76: mov [bp-12],ax ;output file handle mov cx,[bp-4] ;current high msg cmp cx,[bp-8] ;higher than merge? jae sysm77 ;yes mov cx,[bp-8] ;new high value sysm77: mov ax,4 ;bytes per entry mul cx ;header length add ax,4 ;plus overhead call getbuf ;get buffer mov [bp-24],si ;remember mov [si-2],ax ;set size mov [si],cx ;new max msg # call sys160 ;write header mov word ptr [bp-14],1 ;1st system msg mov word ptr [bp-16],0 ;no merge msg yet sysm80: mov ax,[bp-16] ;current merge msg cmp ax,-1 ;done? jz sysm82 ;yes mov [bp-8],ax ;remember last mov si,[bp-20] ;output buffer mov word ptr [si-2],0 ;clear call sys130 ;get merge line jnc sysm81 ;ok mov word ptr [bp-16],-1 ;mark end of file jmp sysm82 ;try system file sysm81: mov ax,[bp-16] ;msg found cmp ax,[bp-8] ;continuation? jz sysm84 ;yes sysm82: mov ax,[bp-14] ;system msg # cmp ax,[bp-4] ;at end? jbe sysm83 ;no problem cmp word ptr [bp-16],-1 ;end of merge file? jz sysm86 ;yes - done sysm83: inc word ptr [bp-14] ;next msg # cmp ax,[bp-16] ;replace from merge? jz sysm84 ;yes call getmsg ;get system message mov si,di ;for write call sys170 ;write to file call frebuf ;free buffer jmp sysm82 ;next msg sysm84: mov si,[bp-20] ;merge line call sys170 ;write to file jmp sysm80 ;next merge line sysm86: MOV AX,0 ;SEEK TO BEGINNING MOV CX,[BP-12] ;output FILE HANDLE CALL SKBLK ;LSEEK mov si,[bp-24] ;file header mov ax,[bp-26] ;file size mov [si+2],ax ;eof call sys160 ;write file header ;close output file mov ah,3eh ;close request push bx mov bx,[bp-12] ;output file handle int 21h ;dos request pop bx ;free buffers mov si,[bp-24] ;file header call frebuf ;free it mov si,[bp-20] ;output file buffer call frebuf ;free it ;load new msg file call opnmsg ;reload messages ;exit SYSM90: MOV SI,[BP-18] ;MESSAGE BUFFER CALL FREBUF ;FREE IT MOV SP,BP ;FREE LOCAL STORAGE POP BP ;RESTORE CALLER'S FRAME JMP MMENU1 ;EXIT SYS100: TEST WORD PTR [BP-2],4 ;OPEN STRING? JNZ SYS102 ;YES RET SYS102: MOV AL,'"' ;QUOTE CALL APPBYT ;ADD TO BUFFER AND WORD PTR [BP-2],NOT 4 ;STRING CLOSED OR WORD PTR [BP-2],8 ;DELIMITER NEEDED RET SYS110: CMP WORD PTR [SI-2],75 ;LINE FULL? JA SYS112 ;YES RET SYS112: CALL SYS100 ;CLOSE STRING AND WORD PTR [BP-2],NOT 8 ;DON'T NEED DELIMITER CALL PRMSG ;DISPLAY LINE JNC SYS114 ;OK JMP SYSM90 ;NO MORE SYS114: CALL ILINEB ;CLEAR BUFFER ADD WORD PTR [SI-2],8 ;TAB INTO LINE RET SYS120: TEST WORD PTR [BP-2],8 ;NEED DELIMITER? JNZ SYS122 ;YES RET SYS122: MOV AL,',' ;COMMA CALL APPBYT ;ADD TO BUFFER AND WORD PTR [BP-2],NOT 8 ;NO DELIMITER NEEDED RET ;PARSE NEXT line IN MERGE FILE SYS130: MOV AX,[BP-18] ;BUFFER PUSH AX MOV AX,[BP-10] ;INPUT FILE HANDLE PUSH AX CALL GETLIN ;GET NEXT LINE JNC SYS132 ;FOUND ONE RET ;end of file sys132: mov word ptr [bp-22],0 ;start of line mov [bp-6],si ;line buffer SYS134: mov si,[bp-6] ;line buffer mov cx,[bp-22] ;buffer position CALL GTOKEN ;GET TOKEN mov [bp-22],cx ;new position jnc sys136 ;valid token RET sys136: mov si,di ;token buffer cmp ax,1 ;unquoted string? jz sys138 ;yes ja sys150 ;no sys137: clc ;good return ret ;end of line sys138: call xlate ;upper case mov di,offset str07 ;DD call CPCSTA ;is it? jz sys139 ;yes - ignore mov di,offset str01 ;msg prefix call cpcstr ;start of message? jnz sys140 ;no push si mov cx,[si-2] ;string length sub cx,3 ;less header add si,3 ;point to digits call ascbin ;get value pop si mov [bp-16],ax ;message number sys139: call frebuf ;free token buffer jmp sys134 ;next token sys140: mov cx,sytbl2-sytbl1 ;# of entries mov di,offset sytbl2 ;list of entries sys142: push di mov di,ES:[di] ;next string call CPCSTA ;match? jz sys144 ;yes pop di ;list pointer add di,2 ;next entry loop sys142 ;try it call frebuf ;free token buffer jmp sys137 ;abandon line sys144: pop di ;clean up stack sub di,offset sytbl2 ;position in list shr di,1 ;entry number mov al,sytbl1[di] ;control char sys146: call frebuf ;free token buffer mov si,[bp-20] ;output buffer call appbyt ;add to buffer mov [bp-20],si ;appbyt can change si jmp sys134 ;next token sys150: cmp ax,2 ;quoted string? jnz sys152 ;no xchg si,di mov si,[bp-20] ;output buffer call movstr ;append to buffer mov [bp-20],si ;append can change si xchg si,di jmp sys139 ;next token sys152: cmp ax,4 ;numeric string? jz sys154 ;yes jmp sys139 ;not valid sys154: mov cx,[si-2] ;string length call ascbin ;convert jmp sys146 ;next token sys160: mov cx,[si-2] ;string length jcxz sys165 ;exit add [bp-26],cx ;new file size mov ah,40h ;write function mov dx,si ;buffer address push bx mov bx,[bp-12] ;handle int 21h ;dos request pop bx cmp ax,cx ;write all bytes? jz sys165 ;yes err 11h ;crash sys165: ret sys170: mov di,[bp-24] ;header shl ax,1 shl ax,1 ;offset in header add di,ax ;position in header cmp word ptr [di],0 ;offset present? jnz sys172 ;yes - must be continuation mov ax,[bp-26] ;file position mov [di],ax ;msg offset sys172: mov ax,[si-2] ;string length add [di+2],ax ;message length call sys160 ;write to file ret ;------------------------------------------------------------ ;GET NEXT TOKEN FROM LINE BUFFER ; ENTRY: SI -> SOURCE LINE ; CX = OFFSET IN LINE ; RETURN: (IF C=0) ; AX = TOKEN TYPE ; 0 - END OF STRING ; 1 - UNQUOTED STRING ; 2 - QUOTED STRING ; 4 - NUMERIC STRING ; CX = NEW LINE OFFSET ; DI -> BUFFER CONTAINING TOKEN ; STACK: BP-2 TOKEN TYPE ; BP-4 STRING ; BP-6 OFFSET IN STRING ; BP-8 OUTPUT BUFFER ;--------------------------------------------------------- GTOKEN: PUSH BP ;SAVE CALLER'S FRAME MOV BP,SP ;ANCHOR LOCAL FRAME SUB SP,8 ;ALLOCATE LOCAL STORAGE XOR AX,AX ;NULL MOV WORD PTR [BP-2],AX ;CLEAR TOKEN TYPE MOV [BP-4],SI ;STRING ADDRESS MOV [BP-6],CX ;OFFSET INTO STRING MOV [BP-8],AX ;NO OUTPUT BUFFER MOV CX,[SI-2] ;STRING LENGTH ADD SI,WORD PTR [BP-6] ;CURRENT STRING POSITION SUB CX,[BP-6] ;REMAINING LENGTH JA GTOK10 ;GO PARSE JMP GTOK90 ;EXIT GTOK10: LODSB ;GET NEXT CHAR cmp al,'"' ;start of string? jz gtok14 ;yes cmp al,"'" ;start of string? jz gtok14 ;yes CMP AL,' ' ;BLANK? JA GTOK14 ;NO PROBLEM GTOK12: LOOP GTOK10 ;IGNORE BLANKS JMP GTOK90 ;EXIT GTOK14: PUSH AX PUSH SI MOV AX,CX ;LENGTH CALL GETBUF ;GET BUFFER mov di,si ;stosb convention MOV [BP-8],di ;OUTPUT BUFFER POP SI POP AX CMP AL,'"' ;DOUBLE QUOTE? JZ GTOK20 ;YES - START STRING CMP AL,"'" ;SINGLE QUOTE? JZ GTOK20 ;YES CMP AL,'0' ;DIGIT? JB GTOK12 ;NO - DELIMITER CMP AL,'9' ;DIGIT? JBE GTOK30 ;YES JMP SHORT GTOK40 ;CHARACTER GTOK20: MOV AH,AL ;REMEMBER DELIMITER MOV WORD PTR [BP-2],2 ;SET TOKEN TYPE GTOK22: LODSB ;GET CHAR CMP AL,AH ;ENDING DELIMITER? JZ GTOK24 ;YES - RETURN STRING MOV [DI],AL ;STORE IN BUFFER INC DI LOOP GTOK22 ;KEEP IT MOVING MOV WORD PTR [BP-2],-1 ;SHOW ERROR GTOK24: JMP GTOK90 ;EXIT GTOK30: MOV WORD PTR [BP-2],4 ;SET TOKEN TYPE JMP SHORT GTOK34 ;STORE DIGIT GTOK32: LODSB ;NEXT DIGIT CMP AL,'0' ;DIGIT? JB GTOK36 ;NO CMP AL,'9' ;DIGIT? JA GTOK36 ;NO GTOK34: MOV [DI],AL ;STORE IN BUFFER INC DI LOOP GTOK32 ;KEEP IT MOVING GTOK36: JMP GTOK90 ;EXIT GTOK40: MOV WORD PTR [BP-2],1 ;SET TOKEN TYPE JMP SHORT GTOK44 GTOK42: LODSB ;NEXT CHARACTER CMP AL,'0' ;DELIMITER? JB GTOK90 ;YES GTOK44: MOV [DI],AL ;STORE IN BUFFER INC DI LOOP GTOK42 ;KEEP IT MOVING GTOK90: MOV CX,SI ;CURRENT INPUT POSITION MOV SI,[BP-4] ;STRING ADDRESS SUB CX,SI ;NEW OFFSET MOV AX,DI ;CURRENT OUTPUT POSITION MOV DI,[BP-8] ;OUTPUT BUFFER or di,di ;exist? jz gtok92 ;no SUB AX,DI ;BUFFER LENGTH MOV [DI-2],AX ;SET STRING LENGTH gtok92: MOV AX,[BP-2] ;TOKEN TYPE MOV SP,BP ;FREE LOCAL STORAGE POP BP ;RESTORE CALLER'S FRAME CMP AX,5 ;VALID? CMC ;NO CARRY IS GOOD RET ;----------------------------------------------------------- ;PACK USERS FILE ; BP-2 USERS.$$$ HANDLE ; BP-4 USER RECORD BUFFER ADDRESS ; BP-6 INPUT BLOCK NUMBER ; BP-8 PURGE COUNTER ; BP-10 OUTPUT BLOCK NUMBER ; BP-12 OLD SYSOP BLOCK NUMBER ; BP-14 FIRST USER BLOCK NUMBER ; BP-16 POINTER TO NEW USER INDEX ; BP-18 NEW INDEX LENGTH ; BP-20 NEW SYSOP BLOCK NUMBER ;--------------------------------------------------------- PACKUF: CALL TSYSOP ;AUTHORIZED CALLER? JNZ PACU10 ;YES JMP MMENU2 ;UNKNOWN COMMAND PACU10: MOV AX,117 ;DO YOU WANT TO PACK ... CALL QYESNO ;GET RESPONSE JC PACU12 ;DEFAULT TO NO JZ PACU20 ;YES PACU12: JMP MMENU1 ;MAIN MENU PACU20: CMP USRCNT,1 ;ARE WE ONLY USER? JZ PACU30 ;YES MOV AX,110 ;FILE IN USE CALL WMSGNO JMP MMENU1 ;EXIT PACU30: MOV SI,OFFSET USRLOCK ;USER FILE LOCK WORD CALL LOCKWT ;ACQUIRE FILE LOCK MOV USRCNT,-1 ;INHIBIT LOGONS PUSH BP ;SAVE CALLER'S FRAME MOV BP,SP ;ESTABLISH LOCAL FRAME SUB SP,20 ;ALLOCATE LOCAL STORAGE ;DELETE PREVIOUS BACKUP FILE MOV AH,41H ;DELETE FILE MOV DX,OFFSET USROFN ;CCUSERS.BAK PUSH DS PUSH ES POP DS INT 21H ;DOS REQUEST POP DS ;CREATE NEW USERS FILE PACU35: MOV AH,3CH ;CREATE FUNCTION XOR CX,CX ;NORMAL ATTRIBUTE MOV DX,OFFSET USRTFN ;CCUSERS.$$$ PUSH DS PUSH ES POP DS INT 21H ;DOS REQUEST POP DS JNC PACU40 ;OPEN OK ERR 12 PACU40: MOV [BP-2],AX ;FILE HANDLE MOV AX,256 ;NEW RECORD SIZE CALL GETBUF ;GET BUFFER MOV [BP-4],SI ;BUFFER ADDRESS OR WORD PTR [BX+CBFLG],SFNOPL ;NO 'MORE' PROMPTS MOV WORD PTR [BP-8],0 ;PURGE COUNTER MOV WORD PTR [BP-14],3 ;1ST USER BLOCK NUMBER MOV WORD PTR [BP-6],3 ;INPUT BLOCK NUMBER MOV WORD PTR [BP-10],0 ;OUTPUT BLOCK COUNT MOV AX,WORD PTR [BX+USRSL] ;OUR OLD BLOCK NUMBER MOV [BP-12],AX ;NEED FOR COMPARE ;CREATE NEW USER INDEX MOV AX,256 ;BUFFER SIZE CALL GETSBF ;GET ONE MOV [BP-16],SI ;NEW BUFFER MOV WORD PTR [BP-18],127 ;HIGHEST ENTRY ;WRITE CONTROL RECORD MOV SI,[BP-4] ;BUFFER MOV WORD PTR [SI+UVERS],2 ;FILE VERSION MOV WORD PTR [SI+UINXSZ],128 ;# OF INDEX ENTRIES MOV WORD PTR [SI+UCRSIZ],256 ;USER RECORD SIZE CALL PUWRT ;WRITE CONTROL RECORD CALL PUWRT ;WRITE 1ST INDEX BLOCK CALL PUWRT ;WRITE 2ND INDEX BLOCK CALL FREBUF ;FREE WORK BUFFER ;STEP THROUGH USER RECORDS PACU50: MOV AX,[BP-6] ;NEXT USER BLOCK CALL GETUSR ;GET USER RECORD MOV [BP-4],SI ;RECORD ADDRESS JNC PACU53 ;GOOD READ JMP PACU90 ;END OF FILE PACU53: CALL USRDEL ;TEST FOR DELETE CRITERIA JC PACU60 ;PURGE RECORD ;REBUILD USER INDEX ENTRY MOV AX,UELNK-UENAM ;LENGTH OF NAME CALL GETBUF ;GET BUFFER MOV DI,[BP-4] ;INPUT RECORD ADD DI,UENAM ;USER NAME MOV CX,UELNK-UENAM ;LENGTH CALL MOVSTL ;COPY NAME TO BUFFER CALL STRIP ;STRIP TRAILING BLANKS CALL CRCCLC ;HASH NAME CALL FREBUF ;RELEASE BUFFER MOV SI,AX ;NEED INDEX REG AND SI,[BP-18] ;HIGHEST ENTRY SHL SI,1 ;WORD INDEX ADD SI,[BP-16] ;POINT INTO TABLE MOV CX,[SI] ;GET CURRENT INDEX MOV AX,[BP-10] ;OUTPUT BLOCK MOV [SI],AX ;PUT BLOCK IN TABLE MOV DI,[BP-4] ;POINT TO RECORD MOV [DI+UELNK],CX ;SET LINK POINTER CALL USRCNV ;CONVERT USER RECORD MOV AX,[BP-6] ;USER ENTRY NUMBER CMP AX,[BP-12] ;IS THIS US? JNZ PACU54 ;NO PROBLEM MOV AX,[BP-10] ;OUTPUT BLOCK NUMBER MOV [BP-20],AX ;SAVE NEW SYSOP BLOCK # PACU54: CALL PUWRT ;WRITE OUTPUT MOV AX,264 ;COPIED JMP PACU70 ;DISPLAY ACTION PACU60: MOV AX,265 ;PURGED INC WORD PTR [BP-8] ;PURGE COUNTER PACU70: PUSH AX ;MESSAGE NUMBER CALL ILINEB ;FORMAT BUFFER MOV AX,[BP-6] ;ENTRY NUMBER SUB AX,[BP-14] ;LESS OFFSET SHR AX,1 ;ADJUST FOR BLOCK SIZE MOV CX,4 ;ALLOW FOUR DIGITS CALL BINASC MOV AL,':' CALL APPBYT INC WORD PTR [SI-2] ;DELIMITER MOV DI,[BP-4] ;RECORD ADDRESS CMP BYTE PTR [DI],0 ;DELETED RECORD? JNZ PACU72 ;NO PROBLEM MOV AX,276 ; CALL MOVMSG ;MOVE TO BUFFER JMP PACU74 PACU72: MOV CX,UELNK-UENAM ;LENGTH OF USER NAME CALL MOVSTL ;MOVE NAME PACU74: POP AX ;ACTION STRING CALL MOVMSG ;MOVE TO BUFFER CALL WRMSG ;DISPLAY RESULTS MOV AX,[BP-6] ;USER RECORD CALL FREUSR ;RELEASE IT ADD WORD PTR [BP-6],2 ;NEXT INPUT RECORD JMP PACU50 ;PROCESS NEXT RECORD ;WRITE INDEX TO USER FILE PACU90: MOV AX,1 ;BLOCK # MOV CX,[BP-2] ;FILE HANDLE MOV SI,[BP-16] ;INDEX ADDRESS CALL WFBLK ;WRITE FILE BLOCK MOV AX,2 ;2ND INDEX BLOCK ADD SI,128 ;2ND HALF OF INDEX CALL WFBLK ;WRITE FILE BLOCK MOV AX,[BP-10] ;LAST OUTPUT BLOCK SUB AX,2 ;LAST WRITTEN MOV DS:MSGCKPT+MLASTU,AX ;SAVE IN STATS CALL CKPTM ;CHECK POINT RECORD ;CLOSE NEW USER FILE MOV AH,3EH ;CLOSE FUNCTION PUSH BX MOV BX,[BP-2] ;FILE HANDLE INT 21H ;CLOSE IT POP BX ;CLOSE USERS FILE MOV AH,3EH ;CLOSE PUSH BX MOV BX,USERH ;FILE HANDLE INT 21H ;DOS REQUEST POP BX MOV SI,USRINXA ;EXISTING INDEX CALL FREBUF ;FREE IT ;RENAME CCUSERS.FIL TO CCUSERS.BAK MOV AH,56H ;RENAME FUNCTION MOV DX,OFFSET USERN ;CCUSERS MOV DI,OFFSET USROFN ;CCUSERS.BAK PUSH DS PUSH ES POP DS INT 21H ;DOS REQUEST POP DS ;RENAME CCUSERS.$$$ TO CCUSERS.FIL MOV AH,56H ;RENAME FUNCTION MOV DX,OFFSET USRTFN ;CCUSERS.$$$ MOV DI,OFFSET USERN ;CCUSERS.FIL PUSH DS PUSH ES POP DS INT 21H ;DOS REQUEST POP DS ;OPEN NEW USER FILE MOV AX,3D02H ;OPEN REQUEST MOV DX,OFFSET USERN ;FILE NAME PUSH DS PUSH ES POP DS INT 21H ;DOS REQUEST POP DS JNC PACU95 ;GOOD OPEN ERR 1 ;BAD NEWS PACU95: MOV USERH,AX ;FILE HANDLE MOV AX,[BP-16] ;NEW INDEX POINTER MOV USRINXA,AX ;POINT TO NEW INDEX MOV AX,[BP-18] ;NEW INDEX LENGTH MOV USRINXL,AX ;SET NEW LENGTH MOV AX,[BP-12] ;OLD BLOCK NUMBER CALL FREUSR ;RELEASE IT MOV AX,[BP-20] ;NEW BLOCK NUMBER MOV [BX+USRSL],AX ;UPDATE TCB CALL GETUSR ;POINT TO OUR RECORD MOV [BX+USRST],SI ;UPDATE TCB CALL ILINEB ;FORMAT BUFFER MOV AX,[BP-8] ;PURGE COUNT CALL BINASP ;PUT IN BUFFER MOV AX,277 ;USER ENTRIES PURGED CALL MOVMSG ;MOVE TO BUFFER CALL WRMSG ;DISPLAY RESULT MOV SP,BP ;FREE LOCAL STORAGE POP BP ;RESTORE CALLER'S FRAME MOV USRCNT,1 ;SHOW FILE AVAILABLE MOV SI,OFFSET USRLOCK ;USER FILE LOCK WORD CALL UNLOCK ;RELEASE FILE LOCK JMP MMENU1 ;MAIN MENU PUWRT: MOV AX,[BP-10] ;BLOCK NUMBER MOV CX,256 ;NEW BLOCK SIZE CMP AX,[BP-14] ;USER RECORD? JNB PUWRT0 ;YES MOV CX,UESIZE ;HEADER BLOCK SIZE DEC WORD PTR [BP-10] ;ADJUST FOR SHORT BLOCK PUWRT0: MOV AH,40H ;WRITE FUNCTION MOV DX,[BP-4] ;BUFFER ADDRESS PUSH BX MOV BX,[BP-2] ;FILE HANDLE INT 21H ;DOS REQUEST POP BX JNC PUWRTX ;WRITE OK ERR 12 PUWRTX: ADD WORD PTR [BP-10],2 ;OUTPUT BLOCK NUMBER RET ;-------------------------------------------------------------- ;SELECTIVELY DELETE USER RECORDS BASED ON ACTIVITY ; RETURNS CARRY SET IF USER SHOULD BE DELETED ;-------------------------------------------------------------- USRDEL: MOV DI,[BP-4] ;POINT TO RECORD ;-------------------------------------------------------------- ;SPECIAL CODE TO FIX DAVID'S PROBLEM CMP BYTE PTR [DI],0E1H ;BAD ENTRY? JNZ USRD00 ;NO MOV AX,[DI+1] ;MESSAGE SIZE SUB AX,2 ;DELETED RECORD SIZE OR AH,AH ;REASONABLE NUMBER? JNZ USRD00 ;NO - DON'T MESS WITH IT ADD [BP-6],AX ;SKIP BAD BLOCK JMP USRD10 ;GO DELETE ;-------------------------------------------------------------- USRD00: CMP BYTE PTR [DI],0 ;DELETED BY SYSOP? JNZ USRD20 ;NO USRD10: STC ;MARK FOR DELETION RET USRD20: TEST BYTE PTR [DI+UESTAT2],8 ;MANUAL DELETE? JNZ USRD90 ;YES - DON'T DELETE TEST BYTE PTR [DI+UESTAT],30H ;SYSOP OR ASST? JNZ USRD90 ;YES - DON'T DELETE MOV AX,WORD PTR [DI+UELDAT+2] ;MONTH & DAY XCHG AH,AL ;MONTH TO AL PUSH AX CALL DOSDAT ;GET CURRENT DATE POP AX SUB DH,AL ;ELAPSED MONTHS JNC USRD23 ;POSITIVE ADD DH,12 ;CORRECT FOR YEAR USRD23: MOV AX,WORD PTR [DI+UETIMO] ;TIMES ON CMP AX,6 ;UPPER LIMIT JB USRD24 ;NO PROBLEM MOV AX,6 ;LIMIT COUNT USRD24: CMP DH,AL ;OFF LONGER THAN SCORE? JBE USRD90 ;NO - DON'T DELETE JMP USRD10 ;PURGE USER USRD90: CLC ;SHOW KEEP USER RET ;--------------------------------------------------------- ;FDIR FILE MAINTENANCE FUNCTIONS ; BP-2 FUNCTION CODE ; 0=LIST ALL ENTRIES ; 1=PRINT ALL ENTRIES ; 2=MODIFY ENTRIES ; 3=PRINT THIS ENTRY ; BP-4 ADDRESS OF FDIR RECORD ; BP-6 CURRENT FDIR BLOCK NUMBER ; BP-8 ARCHIVE PATH STRING ;--------------------------------------------------------- FDIRFM: CALL TAYSOP ;AUTHORIZED CALLER? JNZ FDIR10 ;YES JMP MMENU2 ;UNKNOWN COMMAND FDIR10: MOV AX,112 ;LIST, PRINT, OR MODIFY CALL QMSGNO JNC FDIR20 ;GOOD RESPONSE FDIRJX: JMP MMENU1 ;LOST CARRIER FDIR20: CALL DQCMD ;GET RESPONSE CALL XLATE ;MAKE UPPER CASE CMP WORD PTR [SI-2],0 ;NULL RESPONSE JZ FDIRJX ;EXIT PUSH BP ;SAVE CALLER'S FRAME MOV BP,SP ;ESTABLISH LOCAL FRAME SUB SP,8 ;ALLOCATE LOCAL STORAGE XOR AX,AX MOV [BP-2],AX ;DEFAULT TO LIST MOV [BP-4],AX ;NO BUFFER YET MOV [BP-6],AX ;BEGINNING OF FILE MOV [BP-8],AX ;NO PATH LODSB ;GET RESPONSE CMP AL,'L' ;LIST? JZ FDIR30 ;YES - DEFAULT CMP AL,'P' ;PRINT? JNZ FDIR22 ;NO MOV WORD PTR [BP-2],1 ;MARK FOR PRINT OR WORD PTR [BX+CBFLG],SFNOPL ;NO 'MORE' PROMPTS JMP SHORT FDIR30 FDIR22: CMP AL,'M' ;MODIFY? JZ FDIR24 ;YES JMP FDIR90 ;NO - INVALID FDIR24: MOV WORD PTR [BP-2],2 ;MARK FOR MODIFY MOV AX,DS:MSGCKPT+MLASTD ;LAST DIRECTORY ENTRY MOV [BP-6],AX ;START WITH LAST RECORD FDIR30: MOV AX,MSGSIZ ;FDIR RECORD LENGTH CALL GETBUF ;GET BUFFER MOV [BP-4],SI ;SAVE ADDRESS FDIR40: CALL CKCTLK ;ABORT REQUEST? JC FDIJ90 ;YES CALL RFDR00 ;READ FDIR RECORD JNZ FDIR41 ;GOOD READ FDIJ90: JMP FDIR90 ;END OF FILE FDIR41: MOV DI,[BP-4] ;ADDRESS RECORD CMP BYTE PTR [DI+FDNAME],0 ;DELETED ENTRY? JNZ FDIR42 ;NO PROBLEM JMP FDIR60 ;YES - SKIP FDIR42: CALL ILINEB ;FORMAT BUFFER MOV AX,[BP-6] ;FDIR BLOCK NUMBER MOV CX,4 ;ALLOW 4 DIGITS CALL BINASC MOV AL,':' CALL APPBYT ;ADD TO STRING INC WORD PTR [SI-2] ;DELIMITER MOV CX,FDOWNR-FDNAME ;LENGTH OF FILE NAME ADD DI,FDNAME ;FILE NAME CALL MOVSTL ;MOVE NAME MOV AX,235 ;DELIMITER CALL MOVMSG ;MOVE TO BUFFER MOV DI,[BP-4] ;RESTORE RECORD ADDRESS ADD DI,FDDESC ;FILE DESCRIPTION MOV CX,FDPATH-FDDESC ;LENGTH CALL MOVSTL MOV AX,284 ;TIMES DOWNLOADED CALL MOVMSG ;MOVE TO BUFFER MOV DI,[BP-4] ;FDIR RECORD MOV AX,WORD PTR [DI+FDACNT] ;TIMES DOWNLOADED CALL BINASP CALL PRMSG ;OUTPUT MESSAGE JNC FDIR43 ;OK JMP FDIR90 ;NO MORE FDIR43: CALL ILINEB ;FORMAT BUFFER ADD WORD PTR [SI-2],6 ;INDENT MOV AX,287 ;SIZE= CALL MOVMSG ;MOVE TO BUFFER MOV DI,[BP-4] ;FDIR RECORD MOV AX,WORD PTR [DI+FDSIZE] ;LSW FILE SIZE MOV DX,WORD PTR [DI+FDSIZE+2] MOV CX,7 ;FIELD WIDTH CALL BINASD ;PUT IN BUFFER MOV AX,288 ;OWNR= CALL MOVMSG ;MOVE TO BUFFER MOV DI,[BP-4] ;FDIR RECORD ADD DI,FDOWNR ;FILE OWNER MOV CX,FDDESC-FDOWNR ;OWNER LENGTH CALL MOVSTL ;MOVE TO BUFFER MOV AX,289 ;PATH= CALL MOVMSG ;MOVE TO BUFFER MOV DI,[BP-4] ;FDIR RECORD ADD DI,FDPATH ;FILE PATH MOV CX,MSGSIZ-FDPATH ;PATH LENGTH CALL MOVSTL ;MOVE TO BUFFER CALL PRMSG ;OUTPUT MESSAGE JNC FDIR44 ;OK JMP FDIR90 ;NO MORE FDIR44: CALL ILINEB ;FORMAT BUFFER ADD WORD PTR [SI-2],6 ;INDENT MOV AX,280 ;STATUS= CALL MOVMSG ;MOVE TO BUFFER MOV DI,[BP-4] ;FDIR RECORD MOV AX,WORD PTR [DI+FDSTAT] ;STATUS CALL HEXSTR ;DISPLAY AS HEX MOV AX,278 ;MSECT= CALL MOVMSG ;MOVE TO BUFFER MOV AX,WORD PTR [DI+FDSECT] ;SECTION BIT MASK CALL HEXSTR ;DISPLAY AS HEX MOV AX,281 ;CLASS CALL MOVMSG ;MOVE TO BUFFER MOV AX,WORD PTR [DI+FDCLAS] ;CLASSIFICATION CALL HEXSTR ;DISPLAY AS HEX MOV AX,282 ;CDATE CALL MOVMSG ;MOVE TO BUFFER MOV CX,WORD PTR [DI+FDCDAT] ;CREATION DATE MOV DX,WORD PTR [DI+FDCDAT+2] CALL DTEASC MOV AX,283 ;LDATE CALL MOVMSG ;MOVE TO BUFFER MOV CX,WORD PTR [DI+FDADAT] ;LAST ACCESSED DATE MOV DX,WORD PTR [DI+FDADAT+2] CALL DTEASC CALL PRMSG ;OUTPUT MESSAGE JNC FDIR45 ;OK JMP FDIR90 ;NO MORE FDIR45: CALL ILINEB ;EMPTY BUFFER CALL PRMSG ;OUTPUT MESSAGE JNC FDIR46 ;OK JMP FDIR90 ;NO MORE FDIR46: TEST WORD PTR [BP-2],2 ;MODIFY? JZ FDIR60 ;NO - DO NEXT ENTRY AND WORD PTR [BP-2],-2 ;TURN OFF PRINT FDIR51: MOV AX,125 ;FDIR MENU CALL QMSGNO JNC FDIR52 ;GOOD READ JMP FDIR90 ;LOST CARRIER FDIR52: CALL DQCMD ;GET RESPONSE CMP WORD PTR [SI-2],0 ;NULL RESPONSE? JZ FDIR61 ;PREVIOUS BLOCK CMP BYTE PTR [SI],'0' ;LOWEST NUMERIC JB FDIR54 ;NOT NUMERIC CMP BYTE PTR [SI],'9' ;HIGHEST NUMERIC JA FDIR54 ;NOT NUMERIC MOV CX,4 ;MAXIMUM FIELD WIDTH CALL ASCBIN ;GET VALUE MOV [BP-6],AX ;SET FOR READ JMP FDIR40 ;GET SPECIFIED RECORD FDIR54: CALL XLATE ;MAKE UPPER CASE LODSB ;GET COMMAND CHAR MOV DI,OFFSET CTBLS2 ;VALID COMMAND STRING MOV CX,(JTBLS2-CTBLS2) ;TABLE LENGTH REPNZ SCASB ;CHECK FOR MATCH JNZ FDIR51 ;NOT VALID SUB DI,OFFSET CTBLS2+1 ;OFFSET IN TABLE SHL DI,1 ;TABLE WIDTH JMP JTBLS2[DI] ;GO TO ROUTINE FDIR58: CALL WFDR00 ;WRITE FDIR RECORD JMP FDIR40 ;RE-DISPLAY ENTRY FDIR60: TEST WORD PTR [BP-2],2 ;MODIFY? JNZ FDIR61 ;YES - GO BACKWARDS INC WORD PTR [BP-6] ;NEXT BLOCK JMP FDIR40 ;GET NEXT ENTRY FDIR61: DEC WORD PTR [BP-6] ;PREVIOUS BLOCK JMP FDIR40 ;DISPLAY RECORD FDIR62: OR WORD PTR [BP-2],1 ;TURN ON PRINT JMP FDIR40 ;DISPLAY SAME ENTRY FDIR64: CALL BLDFN ;GET FILE NAME STRING MOV AH,41H ;DELETE REQUEST MOV DX,SI ;FILE NAME INT 21H ;DOS FUNCTION CALL JNC FDIR66 ;DELETE OK CMP AX,2 ;FILE NOT FOUND? JZ FDIR65 ;YES - DON'T ABORT CMP AX,3 ;PATH NOT FOUND? JZ FDIR65 ;YES - DON'T ABORT ERR 5 ;ERROR DELETING FILE FDIR65: DEC WORD PTR [SI-2] ;TRUNCATE DELIMITER MOV AX,286 ;NOT FOUND CALL MOVMSG ;MOVE TO BUFFER CALL WRMSG ;DISPLAY MSG FDIR66: MOV DI,[BP-4] ;DIRECTORY RECORD XOR AX,AX MOV [DI+FDSIZE],AX ;CLEAR SIZE FIELD MOV [DI+FDSIZE+2],AX TEST WORD PTR [DI+FDSTAT],4 ;SKELETON ENTRY JNZ FDIR69 ;YES - LEAVE ENTRY INTACT ADD DI,FDNAME ;FILE NAME FIELD MOV CX,FDOWNR-FDNAME ;LENGTH OF NAME PUSH ES PUSH DS POP ES REP STOSB ;CLEAR NAME POP ES FDIR69: JMP FDIR58 ;RE-WRITE RECORD ;CHANGE CLASS ASSIGNMENT FDIR70: MOV SI,126 ;SECTION # PROMPT MOV DI,[BP-4] ;FDIR RECORD MOV AX,[DI+FDCLAS] ;GET CURRENT VALUE CALL PSECNO ;GET NEW VALUE JC FDIR85 ;INVALID INPUT MOV [DI+FDCLAS],AX ;SET NEW VALUE JMP FDIR58 ;UPDATE RECORD ;CHANGE SECTION ASSIGNMENT FDIR80: MOV SI,123 ;SECTION # PROMPT MOV DI,[BP-4] ;FDIR RECORD MOV AX,[DI+FDSECT] ;CURRENT SECTION VALUE CALL PSECNO ;GET NEW VALUE JC FDIR85 ;INVALID INPUT MOV [DI+FDSECT],AX ;STORE NEW VALUE JMP FDIR58 ;UPDATE RECORD FDIR85: JMP FDIR40 ;RE-DISPLAY RECORD FDIR90: MOV SI,[BP-4] ;FDIR RECORD CALL FREBUF ;FREE IT MOV SI,[BP-8] ;ARCHIVE PATH CALL FREBUF ;FREE IT MOV SP,BP ;FREE LOCAL STORAGE POP BP ;RESTORE CALLER'S FRAME JMP MMENU1 ;MAIN MENU ;EDIT FILE DESCRIPTION FDIRA0: MOV AX,130 ;NEW DESCRIPTION PROMPT CALL QMSGNO ;PROMPT FOR TEXT JC FDIR85 ;LOST CARRIER CALL DQCMD ;GET RESPONSE MOV CX,WORD PTR [SI-2] ;RESPONSE LENGTH JCXZ FDIR85 ;NULL RESPONSE MOV DI,[BP-4] ;DIRECTORY RECORD ADD DI,FDDESC ;POINT TO DESCRIPTION MOV CX,FDPATH-FDDESC ;LENGTH OF DESCRIPTION CALL PADB ;ADJUST LENGTH PUSH ES PUSH DS POP ES REP MOVSB ;MOVE TO DESCRIPTION POP ES JMP FDIR58 ;RE-DISPLAY RECORD ;RE-NAME FILE FDIRB0: MOV AX,129 ;NEW NAME PROMPT CALL QMSGNO ;ASK USER JC FDIRB2 ;LOST CARRIER CALL DQCMD ;GET RESPONSE MOV CX,[SI-2] ;RESPONSE LENGTH JCXZ FDIRB2 ;NULL RESPONSE CALL STRIP ;REMOVE TRAILING BLANKS CALL XLATE ;MAKE UPPER CASE MOV DI,[BP-4] ;FDIR RECORD PUSH DI ;PASS AS PARAMETER PUSH SI ;PASS AS PARAMETER XOR AX,AX ;NO NEW PATH PUSH AX ;PASS AS PARAMETER CALL RENFIL ;RENAME PHYSICAL FILE JC FDIRB2 ;INVALID REQUEST MOV DI,[BP-4] ;FDIR RECORD ADD DI,FDNAME ;FILE NAME FIELD MOV CX,FDOWNR-FDNAME ;FILE NAME LENGTH CALL PADB ;ADJUST LENGTH PUSH ES PUSH DS POP ES REP MOVSB ;MOVE TO RECORD POP ES FDIRB2: JMP FDIR58 ;RE-DISPLAY RECORD ;MOVE FILE TO ANOTHER DIRECTORY FDIRC0: MOV AX,118 ;NEW PATH PROMPT CALL QMSGNO ;ASK USER JC FDIR85 ;LOST CARRIER CALL DQCMD ;GET RESPONSE MOV CX,[SI-2] ;RESPONSE LENGTH JCXZ FDIRB2 ;NULL RESPONSE CALL STRIP ;REMOVE TRAILING BLANKS CALL XLATE ;MAKE UPPER CASE MOV DI,WORD PTR [SI-2] ;STRING LENGTH OR DI,DI ;NULL? JZ FDIRC2 ;YES ADD DI,SI ;POINT PAST END DEC DI ;LAST CHAR MOV AL,'\' ;PATH DELIMITER CMP BYTE PTR [DI],AL ;PROPER DELIMITER? JZ FDIRC2 ;YES CALL APPBYT ;ADD TO STRING FDIRC2: MOV DI,[BP-4] ;FDIR RECORD PUSH DI ;PASS AS PARAMETER XOR AX,AX ;NO NEW NAME PUSH AX ;PASS AS PARAMETER PUSH SI ;PASS NEW PATH AS PARAMETER CALL RENFIL ;RENAME PHYSICAL FILE JNC FDIRC3 ;RENAME OK JMP FDIR85 ;INVALID REQUEST FDIRC3: MOV DI,[BP-4] ;FDIR RECORD ADD DI,FDPATH ;PATH NAME FIELD MOV CX,MSGSIZ-FDPATH ;FILE NAME LENGTH CALL PADB ;ADJUST LENGTH PUSH ES PUSH DS POP ES REP MOVSB ;MOVE TO RECORD POP ES JMP FDIR58 ;RE-DISPLAY RECORD ;ARCHIVE DOWNLOAD FILE FDIRD0: CMP WORD PTR [BP-8],0 ;ANY PATH YET? JNZ FDIRD4 ;YES MOV AX,118 ;NEW PATH PROMPT CALL QMSGNO ;ASK USER JNC FDIRD2 ;OK FDIRD1: JMP FDIR85 ;LOST CARRIER FDIRD2: CALL DQCMD ;GET RESPONSE MOV CX,[SI-2] ;RESPONSE LENGTH JCXZ FDIRD1 ;NULL RESPONSE CALL STRIP ;REMOVE TRAILING BLANKS CALL XLATE ;MAKE UPPER CASE MOV DI,WORD PTR [SI-2] ;STRING LENGTH OR DI,DI ;NULL? JZ FDIRD3 ;YES ADD DI,SI ;POINT PAST END DEC DI ;LAST CHAR MOV AL,'\' ;PATH DELIMITER CMP BYTE PTR [DI],AL ;PROPER DELIMITER? JZ FDIRD3 ;YES CALL APPBYT ;ADD TO STRING FDIRD3: MOV [BP-8],SI ;ARCHIVE PATH NAME MOV WORD PTR [BX+USRCMD],0 ;NO LONGER COMMAND STRING FDIRD4: MOV AX,MSGSIZ ;DIRECTORY ENTRY LENGTH CALL GETBUF ;GET BUFFER MOV DI,[BP-4] ;DIRECTORY RECORD MOV CX,MSGSIZ ;LENGTH TO MOVE CALL MOVSTL ;COPY RECORD MOV DX,SI ;SAVE ADDRESS MOV AX,40 ;STRING LENGTH CALL GETBUF ;GET BUFFER MOV DI,[BP-8] ;PATH NAME CALL MOVSTR ;MOVE TO BUFFER MOV AX,308 ;DIRECTORY NAME CALL MOVMSG ;MOVE TO BUFFER PUSH DX ;STRING ADDRESS PUSH SI ;FILE NAME STRING XCHG SI,DX ;APPDSB CHANGES SI CALL APPDSB ;APPEND TO DISK PUSHF CALL FREBUF ;DIRECTORY ENTRY MOV SI,DX ;FILE NAME STRING CALL FREBUF ;FREE STRING POPF JNC FDIRD5 ;APPEND OK JMP FDIR85 ;EXIT FDIRD5: CALL BLDFN ;GET CURRENT FILE NAME MOV DX,SI ;SAVE MOV AX,40 ;STRING LENGTH CALL GETBUF ;GET BUFFER MOV DI,[BP-8] ;PATH NAME STRING CALL MOVSTR ;MOVE TO BUFFER MOV DI,[BP-4] ;DIRECTORY RECORD ADD DI,FDNAME ;FILE NAME MOV CX,FDOWNR-FDNAME ;LENGTH OF NAME CALL MOVSTL ;MOVE TO BUFFER XOR AX,AX ;DELIMITER CALL APPBYT ;ADD TO STRING PUSH SI ;TARGET FILE NAME PUSH DX ;CURRENT FILE NAME CALL CPYFIL ;COPY FILE PUSHF CALL FREBUF ;TARGET FILE NAME POPF JC FDIRD6 ;FAILED JMP FDIR64 ;DELETE FILE FDIRD6: MOV AX,309 ;FAILED CALL WMSGNO ;DISPLAY MESSAGE FDIRD7: JMP FDIR40 ;RE-DISPLAY RECORD ;CHANGE STATUS FLAGS FDIRE0: MOV SI,119 ;STATUS FLAGS PROMPT MOV DI,[BP-4] ;FDIR RECORD MOV AX,[DI+FDSTAT] ;GET CURRENT VALUE CALL PSECNO ;GET NEW VALUE JC FDIRD7 ;INVALID INPUT MOV [DI+FDSTAT],AX ;SET NEW VALUE JMP FDIR58 ;UPDATE RECORD ;RE-NAME DOWNLOAD FILE ;CALLED WITH FDIR ADDR, NEW NAME, AND NEW PATH ON STACK ; BP+8 FDIR RECORD ; BP+6 NEW FILE NAME STRING ; BP+4 NEW PATH NAME STRING ; BP-2 OLD NAME STRING FOR DOS ; BP-4 NEW NAME STRING FOR DOS RENFIL: PUSH BP ;CALLER'S FRAME MOV BP,SP ;SET LOCAL FRAME SUB SP,4 ;ALLOCATE LOCAL STORAGE PUSH SI PUSH DI MOV AX,40 ;STRING LENGTH CALL GETBUF ;GET STRING BUFFER MOV DI,[BP+8] ;FDIR RECORD ADD DI,FDPATH ;FILE PATH MOV CX,MSGSIZ-FDPATH ;FILE PATH LENGTH CALL MOVSTL ;MOVE TO BUFFER CALL STRIP ;TRUNCATE TRAILING BLANKS MOV [BP-2],SI ;STRING ADDRESS MOV AX,40 ;STRING LENGTH CALL GETBUF ;GET STRING BUFFER MOV DI,[BP+4] ;NEW FILE PATH OR DI,DI ;EXIST? JNZ RENF10 ;YES MOV DI,[BP-2] ;FILE PATH STRING RENF10: CALL MOVSTR ;COPY FILE PATH MOV [BP-4],SI ;STRING ADDRESS MOV SI,[BP-2] ;OLD NAME STRING MOV DI,[BP+8] ;FDIR RECORD ADD DI,FDNAME ;OLD FILE NAME MOV CX,FDOWNR-FDNAME ;LENGTH OF NAME CALL MOVSTL ;MOVE TO STRING CALL STRIP ;TRUNCATE BLANKS XOR AX,AX ;NULL CALL APPBYT ;DELIMITER MOV [BP-2],SI ;OLD STRING NAME MOV DX,SI ;STRING ADDR FOR DOS MOV SI,[BP-4] ;NEW NAME STRING MOV DI,[BP+6] ;NEW NAME AS ENTERED OR DI,DI ;EXIST? JNZ RENF20 ;YES ;MAKE NEW NAME SAME AS OLD NAME MOV DI,[BP+8] ;FDIR RECORD ADD DI,FDNAME ;OLD FILE NAME MOV CX,FDOWNR-FDNAME ;LENGTH OF NAME CALL MOVSTL ;MOVE TO STRING CALL STRIP ;TRUNCATE BLANKS JMP SHORT RENF30 RENF20: CALL MOVSTR ;MOVE TO STRING RENF30: CALL APPBYT ;DELIMITER MOV [BP-4],SI ;NEW NAME STRING MOV DI,SI ;NEW NAME FOR DOS MOV AH,56H ;RENAME REQUEST PUSH ES PUSH DS POP ES INT 21H ;DOS FUNCTION CALL POP ES PUSHF MOV SI,[BP-2] ;OLD NAME STRING CALL FREBUF ;FREE IT MOV SI,[BP-4] ;NEW NAME STRING CALL FREBUF ;FREE IT POPF POP DI POP SI MOV SP,BP ;FREE LOCAL STORAGE POP BP ;RESTORE CALLER'S FRAME RET 6 ;BUILD CURRENT FILE NAME STRING FOR DOS BLDFN: CALL ILINEB ;INIT BUFFER MOV DI,[BP-4] ;FDIR RECORD ADD DI,FDPATH ;FILE PATH MOV CX,MSGSIZ-FDPATH ;FILE PATH LENGTH CALL MOVSTL ;MOVE TO BUFFER CALL STRIP ;REMOVE TRAILING BLANKS MOV DI,[BP-4] ;FDIR RECORD ADD DI,FDNAME ;FILE NAME MOV CX,FDOWNR-FDNAME ;LENGTH OF FILE NAME CALL MOVSTL ;MOVE TO BUFFER CALL STRIP ;TRUNCATE TRAILING BLANKS XOR AX,AX CALL APPBYT ;DELIMITER RET ;QUERY FOR NEW SECTION NUMBER & PARSE RESPONSE INTO AX ; BP-2 PROMPT MESSAGE ; BP-4 DEFAULT RESULT PSECNO: PUSH BP ;SAVE CALLER'S FRAME MOV BP,SP ;ESTABLISH LOCAL FRAME SUB SP,4 ;ALLOCATE LOCAL STORAGE MOV [BP-2],SI ;MESSAGE NUMBER MOV [BP-4],AX ;DEFAULT RESULT PUSH SI ;RESPONSE BUFFER PTR PUSH BX ;OPERAND REG PUSH CX ;LOOP COUNTER PUSH DX ;RESULTS REG PARS00: CMP WORD PTR [BX+USRIN],0 ;NEXT INPUT IN BUFFER? JNZ PARS01 ;YES - SKIP PROMPT MOV AX,[BP-2] ;PROMPT MSG CALL QMSGNO ;QUERY USER JNC PARS01 ;GOOD RESPONSE JMP PARS80 ;LOST CARRIER PARS01: CALL DQCMD ;GET RESPONSE MOV CX,WORD PTR [SI-2] ;RESPONSE LENGTH JCXZ PARS02 ;NULL RESPONSE CMP BYTE PTR [SI],'?' ;LIST SECTIONS? JNZ PARS09 ;NO MOV AX,[BP-2] ;MESSAGE NUMBER CMP AX,119 ;FILE STATUS? JZ PARS05 ;YES CMP AX,126 ;SYSOP FILE CLASSES JZ PARS03 ;YES CMP AX,63 ;USER FILE CLASSES JNZ PARS06 ;NO - MUST BE SECTION #S MOV DX,-1 ;ALL CLASSES FOR NOW JMP SHORT PARS04 ;GO DISPLAY PARS02: MOV DX,[BP-4] ;DEFAULT RESPONSE JMP PARS90 ;EXIT PARS03: MOV DX,-1 ;ALL CLASSES VALID PARS04: CALL DSPCLS ;DISPLAY FILE CLASSES JMP PARS00 ;REPEAT PROMPT PARS05: MOV DX,7 ;ONLY SUPPORTED VALUES CALL DSPSTS ;DISPLAY OPTIONS JMP PARS00 ;REPEAT PROMPT PARS06: CALL VALSEC ;GET AVAILABLE SECTIONS MOV DX,AX ;SECTIONS TO LIST PARS08: CALL DSPSEC ;LIST AVAILABLE SECTIONS JMP PARS00 ;REPEAT PROMPT PARS09: XOR BX,BX ;CLEAR OPERAND REG MOV DX,[BP-4] ;DEFAULT RESULT PARS10: LODSB ;GET NEXT CHAR CMP AL,'+' ;VALID OPERAND? JZ PARS20 ;YES CMP AL,'-' ;VALID OPERAND? JZ PARS20 ;YES CMP AL,'0' ;VALID NUMERIC? JB PARS15 ;NO CMP AL,'9' ;VALID NUMERIC? JBE PARS30 ;YES PARS15: LOOP PARS10 ;SKIP CHAR JMP PARS50 ;DONE PARS20: MOV BL,AL ;SAVE OPERAND JMP PARS15 ;NEXT CHAR PARS30: DEC SI ;UNDO LODSB INC BH ;COUNT OPERAND CALL ASCBIN ;GET VALUE CMP AX,16 ;MAX VALID JA PARS80 ;NOT VALID PUSH CX MOV CX,AX XOR AX,AX ;CLEAR BIT MASK STC ;WILL SHIFT FROM CARRY RCL AX,CL ;CONVERT TO BIT MASK POP CX CMP BL,'+' ;ADD TO EXISTING? JNZ PARS32 ;NO OR DX,AX ;OR IN RESULT JMP PARS40 ;SKIP NUMERICS PARS32: CMP BL,'-' ;TURN OFF BIT? JNZ PARS34 ;NO NOT AX ;INVERT BITS AND DX,AX ;TURN OFF BITS JMP PARS40 ;SKIP NUMERICS PARS34: MOV DX,AX ;SET VALUE MOV BL,'+' ;DEFAULT TO ADD PARS40: LODSB ;GET CHAR CMP AL,'0' ;VALID NUMERIC? JAE PARS42 ;YES - SKIP DEC SI ;UNDO LODSB JMP PARS10 ;GET NEXT OPERATOR PARS42: LOOP PARS40 ;NEXT CHAR PARS50: CMP BH,0 ;ANY OPERANDS? JZ PARS80 ;NO CLC ;SHOW GOOD RESULT JMP PARS90 ;DONE PARS80: STC ;SHOW INVALID PARS90: MOV AX,DX ;SET RESULT POP DX POP CX POP BX POP SI MOV SP,BP ;FREE LOCAL STORAGE POP BP ;RESTORE CALLER'S FRAME RET RFDR00: MOV AH,3FH ;READ FUNCTION PUSH AX RWDIR: MOV AX,[BP-6] ;BLOCK TO READ MOV CX,128 ;BLOCK SIZE MUL CX ;CONVERT TO OFFSET MOV CX,DX MOV DX,AX MOV AX,4200H ;LSEEK PUSH BX MOV BX,FDIRH ;FILE HANDLE INT 21H ;DOS REQUEST POP BX JNC RFDR10 ;SEEK OK ERR 1 RFDR10: MOV CX,128 ;RECORD LENGTH MOV DX,[BP-4] ;RECORD BUFFER POP AX ;READ OR WRITE FUNCTION PUSH BX MOV BX,FDIRH ;FILE HANDLE INT 21H ;DOS REQUEST POP BX JNC RFDR20 ;GOOD READ ERR 13 RFDR20: CMP AX,0 ;END OF FILE? RET WFDR00: MOV AH,40H ;WRITE FUNCTION PUSH AX JMP RWDIR ;ENTER COMMON CODE ;--------------------------------------------------------- ;PACK DIRECTORY FILE ; BP-2 CCFILDIR.BAK HANDLE ; BP-4 USER RECORD BUFFER ADDRESS ; BP-6 INPUT BLOCK NUMBER ; BP-8 PURGE COUNTER ; BP-10 OUTPUT BLOCK NUMBER ; BP-12 FILE NAME STRING FOR FIND ;--------------------------------------------------------- PDIRFI: CALL TSYSOP ;AUTHORIZED CALLER? JNZ PDIR10 ;YES JMP MMENU2 ;UNKNOWN COMMAND PDIR10: MOV AX,127 ;DO YOU WANT TO PACK ... CALL QYESNO ;GET RESPONSE JC PDIR12 ;DEFAULT TO NO JZ PDIR20 ;YES PDIR12: JMP MMENU1 ;MAIN MENU PDIR20: CMP DIRCNT,0 ;FILE IN USE? JZ PDIR30 ;YES MOV AX,110 ;FILE IN USE CALL WMSGNO JMP MMENU1 ;EXIT PDIR30: MOV DIRCNT,-1 ;INHIBIT DIRECTORY OPS PUSH BP ;SAVE CALLER'S FRAME MOV BP,SP ;ESTABLISH LOCAL FRAME SUB SP,12 ;ALLOCATE LOCAL STORAGE ;DELETE PREVIOUS BACKUP FILE MOV AH,41H ;DELETE FILE MOV DX,OFFSET DIROFN ;CCFILDIR.BAK PUSH DS PUSH ES POP DS INT 21H ;DOS REQUEST POP DS ;CLOSE DIRECTORY FILE MOV AH,3EH ;CLOSE PUSH BX MOV BX,FDIRH ;FILE HANDLE INT 21H ;DOS REQUEST POP BX ;RENAME CCFILDIR.FIL TO CCFILDIR.BAK MOV AH,56H ;RENAME FUNCTION MOV DX,OFFSET FDIRN ;CCFILDIR.FIL MOV DI,OFFSET DIROFN ;CCFILDIR.BAK PUSH DS PUSH ES POP DS INT 21H ;DOS REQUEST POP DS ;CREATE NEW DIRECTORY FILE PDIR32:MOV AH,3CH ;CREATE FUNCTION XOR CX,CX ;NORMAL ATTRIBUTE MOV DX,OFFSET FDIRN ;CCFILDIR.FIL PUSH DS PUSH ES POP DS INT 21H ;DOS REQUEST POP DS MOV FDIRH,AX ;NEW HANDLE JNC PDIR36 ;OPEN OK ERR 1 PDIR36: MOV AX,3D00H ;OPEN FOR READ MOV DX,OFFSET DIROFN ;BACKUP FILE PUSH DS PUSH ES POP DS INT 21H ;DOS REQUEST POP DS JNC PDIR40 ;OPEN OK ERR 14 PDIR40: MOV [BP-2],AX ;FILE HANDLE MOV AX,128 ;RECORD SIZE CALL GETBUF ;GET BUFFER MOV [BP-4],SI ;BUFFER ADDRESS MOV AX,36 ;FILE NAME STRING LENGTH CALL GETBUF ;GET BUFFER MOV [BP-12],SI ;BUFFER ADDRESS OR WORD PTR [BX+CBFLG],SFNOPL ;NO 'MORE' PROMPTS XOR DI,DI ;CURRENT BLOCK MOV [BP-6],DI ;INPUT BLOCK NUMBER MOV [BP-8],DI ;PURGE COUNTER MOV [BP-10],DI ;OUTPUT BLOCK COUNT ;SET DTA TO FIND CONTROL BLOCK MOV AH,1AH ;SET DTA FUNCTION MOV DX,OFFSET FINDCTL ;FIND CONTROL BLOCK PUSH DS PUSH ES POP DS INT 21H ;DOS FUNCTION CALL POP DS PDIR50: MOV AH,3FH ;READ FUNCTION MOV CX,128 ;RECORD SIZE MOV DX,[BP-4] ;BUFFER ADDRESS PUSH BX MOV BX,[BP-2] ;FILE HANDLE INT 21H ;DOS REQUEST POP BX JNC PDIR51 ;GOOD READ ERR 13 PDIR51: CMP AX,0 ;END OF FILE? JNZ PDIR52 ;NO JMP PDIR90 ;END OF FILE PDIR52: MOV DI,[BP-4] ;POINT TO RECORD CMP WORD PTR [DI+FDNAME],0 ;DELETED ENTRY? JNZ PDI52A ;NO PROBLEM JMP PDIR60 ;PURGE RECORD ;SEE IF FILE REALLY EXISTS PDI52A: MOV SI,[BP-12] ;FILE NAME BUFFER CALL BLANKF ;INITIALIZE IT MOV DI,[BP-4] ;DIRECTORY BUFFER ADD DI,FDPATH ;POINT TO PATH MOV CX,MSGSIZ-FDPATH ;PATH LENGTH CALL MOVSTL ;MOVE TO BUFFER CALL STRIP ;TRUNCATE PATH MOV DI,[BP-4] ;DIRECTORY BUFFER ADD DI,FDNAME ;FILE NAME MOV CX,FDOWNR-FDNAME ;NAME LENGTH CALL MOVSTL ;MOVE TO BUFFER CALL STRIP ;TRUNCATE XOR AL,AL ;DELIMITER CALL APPBYT ;DELIMIT BUFFER MOV AH,4EH ;FIND FIRST REQUEST XOR CX,CX ;NORMAL ATTRIBUTE MOV DX,SI ;FILE NAME STRING INT 21H ;DOS FUNCTION CALL MOV DI,[BP-4] ;DIRECTORY BUFFER JNC PDIR53 ;FILE EXISTS - UPDATE INFO TEST WORD PTR [DI+FDSTAT],4 ;SKELETON ENTRY? JZ PDIR60 ;NO - PURGE ENTRY MOV AX,WORD PTR [DI+FDSIZE] ;FILE SIZE LSW OR AX,WORD PTR [DI+FDSIZE+2] JZ PDIR54 ;RETAIN ENTRY XOR AX,AX ;SET FILE SIZE TO ZERO MOV WORD PTR [DI+FDSIZE],AX ;STORE IN DIRECTORY ENTRY MOV WORD PTR [DI+FDSIZE+2],AX MOV AH,2AH ;GET DATE INT 21H ;DOS FUNCTION CALL MOV WORD PTR [DI+FDADAT],CX MOV WORD PTR [DI+FDADAT+2],DX JMP PDIR54 ;UPDATE ENTRY ;UPDATE FILE INFO PDIR53: MOV AX,FFSIZE ;LSW TRUE SIZE MOV WORD PTR [DI+FDSIZE],AX ;STORE IN DIRECTORY ENTRY MOV AX,FFSIZM ;MSW TRUE SIZE MOV WORD PTR [DI+FDSIZE+2],AX MOV AX,FFDATE ;FILE CREATION DATE XOR CX,CX ;WORK REG MOV CL,AH ;YEAR BITS SHR CX,1 ;SHIFT YEAR BITS ADD CX,1980 MOV WORD PTR [DI+FDCDAT],CX ;STORE IN DIRECTORY ENTRY XOR CX,CX ;WORK REG MOV CL,AL AND CL,1FH ;ISOLATE DAY PUSH CX MOV CL,5 SHR AX,CL ;SHIFT OUT DAY POP CX MOV CH,AL AND CH,0FH ;ISOLATE MONTH MOV WORD PTR [DI+FDCDAT+2],CX LEA SI,[DI+FDDESC] ;START OF DESCRIPTION MOV CX,FDPATH-FDDESC ;FIELD LENGTH PDI53A: AND BYTE PTR [SI],07FH ;CLEAR PARITY BIT INC SI LOOP PDI53A PDIR54: MOV AH,40H ;WRITE FUNCTION MOV CX,128 ;RECORD SIZE MOV DX,[BP-4] ;BUFFER ADDRESS PUSH BX MOV BX,FDIRH ;FILE HANDLE INT 21H ;DOS REQUEST POP BX JNC PDIR56 ;WRITE OK ERR 13 PDIR56: INC WORD PTR [BP-10] ;OUTPUT BLOCK NUMBER MOV AX,264 ;COPIED JMP SHORT PDIR70 ;DISPLAY ACTION PDIR60: MOV AX,265 ;PURGED INC WORD PTR [BP-8] ;PURGE COUNTER PDIR70: INC WORD PTR [BP-6] ;INPUT BLOCK NUMBER PUSH AX CALL ILINEB ;FORMAT BUFFER MOV AX,[BP-6] ;ENTRY NUMBER MOV CX,4 ;ALLOW FOUR DIGITS CALL BINASC MOV AL,':' CALL APPBYT INC WORD PTR [SI-2] ;DELIMITER MOV DI,[BP-4] ;RECORD ADDRESS CMP WORD PTR [DI+FDNAME],0 ;DELETED RECORD? JNZ PDIR72 ;NO PROBLEM MOV AX,276 ; CALL MOVMSG ;MOVE TO BUFFER JMP PDIR74 PDIR72: MOV CX,FDOWNR-FDNAME ;LENGTH OF FILE NAME ADD DI,FDNAME ;FILE NAME CALL MOVSTL ;MOVE NAME PDIR74: POP AX ;ACTION STRING CALL MOVMSG ;MOVE TO BUFFER CALL WRMSG ;DISPLAY RESULTS JMP PDIR50 ;NEXT RECORD PDIR90: MOV SI,[BP-4] ;BUFFER ADDRESS CALL FREBUF ;FREE IT MOV SI,[BP-12] ;BUFFER ADDRESS CALL FREBUF ;FREE IT MOV AH,3EH ;CLOSE FUNCTION PUSH BX MOV BX,[BP-2] ;FILE HANDLE INT 21H ;CLOSE IT POP BX MOV AX,[BP-10] ;NEXT OUTPUT BLOCK DEC AX ;LAST OUTPUT BLOCK MOV DS:MSGCKPT+MLASTD,AX ;SAVE IN STATS CALL CKPTM ;CHECKPOINT STATS ;FORCE END OF FILE ON CCFILDIR.FIL MOV AX,FDIRH ;FILE HANDLE CALL FEOF ;FORCE END OF FILE CALL ILINEB ;FORMAT BUFFER MOV AX,[BP-8] ;PURGE COUNT CALL BINASP ;PUT IN BUFFER MOV AX,277 ;USER ENTRIES PURGED CALL MOVMSG ;MOVE TO BUFFER CALL WRMSG ;DISPLAY RESULT MOV SP,BP ;FREE LOCAL STORAGE POP BP ;RESTORE CALLER'S FRAME MOV DIRCNT,0 ;SHOW FILE AVAILABLE JMP MMENU1 ;MAIN MENU ;---------------------------------------------------------- ;SET SYSTEM PARAMETERS ;---------------------------------------------------------- STSYSP: CALL TSYSOP ;AUTHORIZED CALLER? JNZ STSY10 ;YES JMP MMENU2 ;UNKNOWN COMMAND STSY10: CALL ILINEB ;INITIALIZE BUFFER MOV AX,290 ;PUBLIC SECTION #S CALL MOVMSG ;MOVE TO BUFFER MOV AX,DS:MSGCKPT+MDPSECT ;PUBLIC SECTION #S CALL HEXSTR ;DISPLAY AS HEX MOV AX,291 ;NEW USERS SECTIONS CALL MOVMSG ;MOVE TO BUFFER MOV AX,DS:MSGCKPT+MDSECT ;NEW USER DEFAULT SECTIONS CALL HEXSTR ;DISPLAY AS HEX CALL WRMSG ;DISPLAY MESSAGE CALL ILINEB ;INITIALIZE BUFFER MOV AX,360 ;SIGOP SECTIONS CALL MOVMSG ;MOVE TO BUFFER MOV AX,DS:MSGCKPT+MDSIGS ;SIGOP SECTIONS CALL HEXSTR ;DISPLAY AS HEX CALL WRMSG ;DISPLAY MESSAGE CALL ILINEB ;INITIALIZE BUFFER MOV AX,307 ;DEFAULT UPLOAD PATH CALL MOVMSG ;MOVE TO BUFFER MOV DI,OFFSET MSGCKPT+MFPATH MOV CX,MLCNAM-MFPATH ;PATH LENGTH CALL MOVSTL ;MOVE TO BUFFER CALL WRMSG ;DISPLAY MESSAGE CALL ILINEB ;INITIALIZE BUFFER MOV AX,295 ;UPLOAD DEFAULT SECTION CALL MOVMSG ;MOVE TO BUFFER MOV AX,DS:MSGCKPT+MDFSECT ;DEFAULT SECTION CALL HEXSTR ;DISPLAY AS HEX MOV AX,296 ;UPLOAD DEFAULT CLASS CALL MOVMSG ;MOVE TO BUFFER MOV AX,DS:MSGCKPT+MDFCLAS ;DEFAULT CLASS CALL HEXSTR ;DISPLAY AS HEX MOV AX,285 ;UPLOAD DEFAULT STATUS CALL MOVMSG ;MOVE TO BUFFER MOV AX,DS:MSGCKPT+MDFSTAT ;DEFAULT STATUS CALL HEXSTR ;DISPLAY AS HEX CALL WRMSG ;DISPLAY RESULTS CALL ILINEB ;INITIALIZE BUFFER TEST DS:MSGCKPT+MSOPTS,8000H ;AUTHORIZATION REQUIRED? JNZ STSY15 ;AUTHORIZATION REQUIRED MOV AX,292 ;NO CALL MOVMSG ;MOVE TO BUFFER STSY15: MOV AX,293 ;AUTHORIZATION REQUIRED CALL MOVMSG ;MOVE TO BUFFER CALL WRMSG ;DISPLAY CALL ILINEB ;INITIALIZE BUFFER MOV AX,312 ;EXT ASCII OFF TEST DS:MSGCKPT+MSOPTS,1000H ;SUPPORT EXTENDED ASCII? JZ STSY16 ;NO MOV AX,313 ;EXT ASCII ON STSY16: CALL MOVMSG ;MOVE TO BUFFER CALL WRMSG ;DISPLAY CALL ILINEB ;INITIALIZE BUFFER MOV AX,454 ;ASSUME CALL REPORTING OFF TEST DS:MSGCKPT+MSOPTS,10H ;ON? JZ STSY17 ;NO MOV AX,453 ;CALL REPORTING ON STSY17: CALL MOVMSG ;MOVE TO BUFFER CALL WRMSG ;DISPLAY CALL ILINEB ;INITIALIZE BUFFER TEST DS:MSGCKPT+MSOPTS,4000H ;PASSWORDS REQUIRED? JNZ STSY18 ;YES MOV AX,292 ;'NO' CALL MOVMSG ;MOVE TO BUFFER STSY18: MOV AX,294 ;PASSWORDS REQUIRED CALL MOVMSG ;MOVE TO BUFFER CALL WRMSG ;DISPLAY CALL ILINEB ;INITIALIZE BUFFER MOV AX,310 ;USERS OWN MSGS TEST DS:MSGCKPT+MSOPTS,2000H ;SYSOP OWN PUBLIC MSGS? JZ STSY19 ;NO MOV AX,311 ;SYSOP OWNS MSGS STSY19: CALL MOVMSG ;MOVE TO BUFFER CALL WRMSG ;DISPLAY ;DISPLAY MENU STSY20: MOV AX,128 ;SYSTEM PARAMETER MENU CALL QMSGNO ;GET RESPONSE JNC STSY30 ;GOOD RESPONSE STSYJX: JMP MMENU1 ;LOST CARRIER STSY30: CALL DQCMD ;GET COMMAND MOV CX,WORD PTR [SI-2] ;RESPONSE LENGTH JCXZ STSYJX ;EXIT ON NULL RESPONSE CALL XLATE ;MAKE UPPER CASE CMP CX,2 ;EXTENDED CMD? JAE STSY35 ;YES LODSB ;GET CMD CHAR MOV DI,OFFSET CTBLS3 ;VALID COMMAND STRING MOV CX,(JTBLS3-CTBLS3) ;TABLE LENGTH REPNZ SCASB ;CHECK FOR MATCH JNZ STSY20 ;NOT VALID SUB DI,OFFSET CTBLS3+1 ;OFFSET IN TABLE SHL DI,1 ;TABLE WIDTH JMP JTBLS3[DI] ;GO TO ROUTINE STSY35: JNZ STSY20 ;NOT VALID MOV DI,OFFSET CTBLS4 ;VALID COMMAND STRING MOV CX,(JTBLS4-CTBLS4) ;TABLE LENGTH IN BYTES SHR CX,1 ;CONVERT TO WORDS LODSW ;GET COMMAND CHARS REPNZ SCASW ;CHECK FOR MATCH JNZ STSY20 ;NO MATCH SUB DI,OFFSET CTBLS4+2 ;OFFSET IN STRING JMP JTBLS4[DI] ;EXECUTE COMMAND STSY40: MOV AX,DS:MSGCKPT+MDSECT ;DEFAULT SECTION #S MOV SI,123 ;SECTION # PROMPT CALL PSECNO ;GET NEW VALUE JC STSY80 ;RE-DISPLAY RECORD MOV DS:MSGCKPT+MDSECT,AX ;STORE NEW VALUE JMP SHORT STSY70 ;RE-WRITE RECORD STSY50: MOV AX,DS:MSGCKPT+MDPSECT ;PUBLIC SECTIONS MOV SI,123 ;SECTION PROMPT CALL PSECNO ;GET NEW VALUE JC STSY80 ;INVALID RESPONSE MOV DS:MSGCKPT+MDPSECT,AX ;NEW VALUE JMP SHORT STSY70 ;STORE RECORD STSY60: XOR DS:MSGCKPT+MSOPTS,8000H ;FLIP VALIDATION FLAG JMP SHORT STSY70 ;STORE RECORD STSY65: XOR DS:MSGCKPT+MSOPTS,4000H ;FLIP SECURITY FLAG STSY70: CALL CKPTM ;CHECK POINT RECORD STSY80: JMP STSY10 ;RE-DISPLAY RECORD STS100: MOV AX,DS:MSGCKPT+MDFSECT ;DEFAULT FILE SECTION MOV SI,123 ;SECTION # PROMPT CALL PSECNO ;GET NEW VALUE JC STSY80 ;RE-DISPLAY RECORD MOV DS:MSGCKPT+MDFSECT,AX ;STORE NEW VALUE JMP STSY70 ;RE-WRITE RECORD STS200: MOV AX,DS:MSGCKPT+MDFCLAS ;DEFAULT FILE CLASS MOV SI,126 ;CLASS # PROMPT CALL PSECNO ;GET NEW VALUE JC STSY80 ;RE-DISPLAY RECORD MOV DS:MSGCKPT+MDFCLAS,AX ;STORE NEW VALUE JMP STSY70 ;RE-WRITE RECORD STS300: MOV AX,118 ;NEW PATH PROMPT CALL QMSGNO ;ASK USER JNC STS320 ;OK STS310: JMP STSY80 ;LOST CARRIER STS320: CALL DQCMD ;GET RESPONSE MOV CX,[SI-2] ;RESPONSE LENGTH JCXZ STS310 ;NULL RESPONSE CALL STRIP ;REMOVE TRAILING BLANKS CALL XLATE ;MAKE UPPER CASE MOV DI,WORD PTR [SI-2] ;STRING LENGTH OR DI,DI ;NULL? JZ STS330 ;YES ADD DI,SI ;POINT PAST END DEC DI ;LAST CHAR MOV AL,'\' ;PATH DELIMITER CMP BYTE PTR [DI],AL ;PROPER DELIMITER? JZ STS330 ;YES CALL APPBYT ;ADD TO STRING STS330: MOV CX,MLCNAM-MFPATH ;PATH LENGTH CALL PADB ;EXPAND TO RECORD LENGTH MOV WORD PTR [BX+USRCMD],SI ;UPDATE POINTER MOV DI,OFFSET MSGCKPT+MFPATH PUSH ES PUSH DS POP ES REP MOVSB ;MOVE TO RECORD POP ES JMP STSY70 ;RE-WRITE RECORD STS400: XOR DS:MSGCKPT+MSOPTS,2000H ;FLIP OWNERSHIP FLAG JMP STSY70 ;STORE RECORD STS500: XOR DS:MSGCKPT+MSOPTS,1000H ;FLIP ANSI FLAG JMP STSY70 ;STORE RECORD STS600: MOV AX,DS:MSGCKPT+MDFSTAT ;DEFAULT FILE STATUS MOV SI,119 ;STATUS FLAG PROMPT CALL PSECNO ;GET NEW VALUE JC STSY80 ;RE-DISPLAY RECORD MOV DS:MSGCKPT+MDFSTAT,AX ;STORE NEW VALUE JMP STSY70 ;STORE RECORD STS700: MOV AX,DS:MSGCKPT+MDSIGS ;SIGOP SECTIONS MOV SI,123 ;SECTION PROMPT CALL PSECNO ;GET NEW VALUE JNC STS710 ;GOOD RESPONSE JMP STSY80 ;INVALID RESPONSE STS710: MOV DS:MSGCKPT+MDSIGS,AX ;NEW VALUE JMP STSY70 ;STORE RECORD STS800: XOR DS:MSGCKPT+MSOPTS,10H ;FLIP CALL PROGRESS FLAG JMP STSY70 ;STORE RECORD ;--------------------------------------------------------- ;DISPLAY SYSTEM STATUS ;--------------------------------------------------------- WHODAT: MOV AX,5 ;TASK STATUS & STATS CALL WHO ;DISPLAY TASK STATUS CALL CKFSPC ;CHECK FILE SPACE PUSH DX ;FILE SPACE PUSH AX ;SYSTEM SPACE CALL ILINEB ;INITIALIZE BUFFER MOV AX,396 ;SYSTEM DISK HAS ... CALL MOVMSG ;MOVE TO BUFFER POP AX ;SYSTEM SPACE CALL BINASP ;PUT IN MESSAGE MOV AX,234 ;AVAILABLE CALL MOVMSG ;MOVE TO BUFFER CALL WRMSG ;DISPLAY MSG CALL ILINEB ;INITIALIZE BUFFER MOV AX,220 ;UPLOAD DISK HAS ... CALL MOVMSG ;MOVE TO BUFFER POP AX ;FILE SPACE CALL BINASP ;PUT IN MESSAGE MOV AX,234 ;AVAILABLE CALL MOVMSG ;MOVE TO BUFFER CALL WRMSG ;DISPLAY MSG CALL FNPFST ;DISPLAY SYSOP STATUS CALL FSNOST ;DISPLAY SNOOP STATUS CALL FLINST ;DISPLAY TRACE STATUS CLI RET ;--------------------------------------------------------- ;DISPLAY TASK STATUS ; BP-2 TASK COUNT ; BP-4 A(LCBLIST) ; BP-6 ; BP-8 TCB ADDRESS ; BP-10 REQUEST FLAGS ; 01 = BASIC TASK STATUS ; 02 = DISPLAY STACK ; 04 = DISPLAY STATISTICS ;--------------------------------------------------------- WHO: PUSH BP MOV BP,SP ;ESTABLISH LOCAL FRAME SUB SP,10 ;ALLOCATE LOCAL STORAGE MOV [BP-10],AX ;REQUEST FLAGS MOV CX,DS:TSKCNT ;LINE COUNT MOV WORD PTR [BP-4],OFFSET TSKCNT ADD WORD PTR [BP-4],2 ;1ST TCB WHO10: MOV [BP-2],CX ;TASK COUNT MOV DI,[BP-4] ;LCB POINTER MOV DI,WORD PTR [DI] ;TCB ADDRESS MOV [BP-8],DI ;TCB ADDRESS TEST WORD PTR [BP-10],1 ;TASK STATUS? JZ WHO20 ;NO CALL DSPS00 ;DISPLAY TCB STATUS WHO20: TEST WORD PTR [BP-10],2 ;STACK STATUS? JZ WHO90 ;NO CALL DSTK00 ;DISPLAY STACK WHO90: ADD WORD PTR [BP-4],2 ;NEXT TCB PTR MOV CX,[BP-2] ;TCB COUNT LOOP WHO10 CALL FRELBF ;FREE LINE BUFFER MOV SP,BP ;FREE LOCAL STORAGE POP BP ;RESTORE CALLER'S FRAME FNEXIT: CLC RET WHAT: MOV AX,3 ;TASK STATUS + STACK JMP WHO ;COMMON CODE FNCLRS: CALL FREWIN ;RELEASE SCREEN JMP FNEXIT ;EXIT DSPS00: CALL ILINEB ;FORMAT BUFFER MOV AX,259 ;COM CALL MOVMSG ;MOVE TO BUFFER MOV DI,[BP-8] ;TCB ADDRESS MOV AX,WORD PTR [DI+USRLN] ;LINE NUMBER ADD AL,30H ;CONVERT TO ASCII CALL APPBYT ;ADD TO STRING MOV DI,[BP-8] ;TCB ADDRESS TEST BYTE PTR [DI+CBMDM],MDMOS ;OUT OF SERVICE? JZ DSPS05 ;NO MOV AX,297 ;OUT OF SERVICE JMP DSPS28 ;ISSUE MESSAGE DSPS05: CMP WORD PTR [DI+USRFL],-1 ;WAITING? JZ DSPS06 ;YES MOV AX,261 ;RUNNING JMP SHORT DSPS09 ;CHECK LOGON NAME DSPS06: MOV AX,WORD PTR [DI+USRIP] ;RESUME ADDRESS CALL WTID ;GET CORRESPONDING MSG JC DSPS10 ;USE HEX ADDRESS CMP AX,386 ;WAITING FOR CALL? JNZ DSPS09 ;NO PROBLEM DSPS07: TEST BYTE PTR [DI+CBMDM],MDMOO ;ORIGINATE ONLY? JZ DSPS09 ;NO MOV AX,304 ;ORIGINATE ONLY JMP DSPS28 ;ISSUE MESSAGE DSPS09: CALL MOVMSG ;MOVE TO BUFFER JMP SHORT DSPS22 ;CHECK LOGON NAME DSPS10: MOV AX,260 ;WAITING DSPS20: CALL MOVMSG ;MOVE TO BUFFER MOV DI,[BP-8] ;TCB ADDR MOV AX,WORD PTR [DI+USRIP] ;RESUME ADDRESS CALL HEXSTR DSPS22: INC WORD PTR [SI-2] ;LEAVE ONE BLANK MOV DI,WORD PTR [DI+USR3N] ;LOGON NAME OR DI,DI ;EXIST? JZ DSPS30 ;NO CALL MOVSTR ;MOVE IN NAME JMP SHORT DSPS30 ;GO DISPLAY DSPS28: CALL MOVMSG DSPS30: CALL WRMSG RET HEXSTR: PUSH AX XCHG AL,AH CALL HEXBYT POP AX HEXBYT: PUSH AX PUSH CX MOV CL,4 ROR AL,CL CALL HEXDGT POP CX POP AX HEXDGT: AND AL,0FH PUSH BX MOV BX,OFFSET HEXTBL XLAT ES:HEXTBL POP BX CALL APPBYT RET ;---------------------------------------------------- ;DISPLAY STACK FOR TCB IN [BP-8] ;---------------------------------------------------- DSTK00: MOV DI,[BP-8] ;TCB TEST BYTE PTR [DI+CBMDM],MDMOS ;OUT OF SERVICE? JZ DSTK05 ;NO PROBLEM STC ;SHOW SKIPPED RET DSTK05: CALL ILINEB ;FORMAT BUFFER MOV AX,262 ;STACK AT CALL MOVMSG ;MOVE TO BUFFER MOV DI,[BP-8] ;TCB PUSH BP ;SAVE CALLER'S FRAME MOV DX,WORD PTR [DI+USRSP] ;STACK POINTER MOV BP,DX ;STACK POINTER AND DX,0FE00H ;STACK ORIGIN ADD DH,2 ;TOP OF STACK SUB DX,BP ;BYTES ON STACK CMP DX,512 ;EMPTY STACK? JNB DSTK20 ;YES - EXIT SHR DX,1 ;# OF WORDS ON STACK MOV AX,BP ;STACK ADDRESS CALL HEXSTR CALL WRMSG JB DSTK20 ;NO MORE DSTK10: MOV CX,DX ;REMAINING WORDS JCXZ DSTK20 ;DONE CMP CX,12 ;MAX PER LINE JLE DSTK12 ;NO PROBLEM MOV CX,12 ;LIMIT DSTK12: SUB DX,CX ;EXCESS CALL ILINEB ;FORMAT BUFFER DSTK14: MOV AX,[BP] ;STACK ELEMENT CALL HEXSTR ;PUT IN STRING ADD WORD PTR [SI-2],2 ;LEAVE SPACES ADD BP,2 ;NEXT ELEMENT LOOP DSTK14 ;GO HANDLE CALL WRMSG ;DISPLAY LINE JB DSTK20 ;NO MORE JMP DSTK10 ;CHECK NEXT LINE DSTK20: POP BP ;RESTORE CALLER'S FRAME RET ;--------------------------------------------------------- ;DISPLAY STRING HEADERS FROM BUFFER POOL ;--------------------------------------------------------- LSTBUF: PUSH BP ;SAVE CALLER'S FRAME MOV BP,SP ;ESTABLISH LOCAL FRAME SUB SP,2 ;ALLOCATE LOCAL STORAGE MOV AX,109 ;TITLES CALL WMSGNO MOV DI,OFFSET BFRHD ;START OF BUFFER POOL LSTB10: CALL ILINEB ;FORMAT BUFFER MOV [BP-2],DI ;START OF STRING HEADER MOV AX,DI ;ADDRESS IN BUFFER MOV CX,5 ;WORDS TO PRINT JMP SHORT LSTB15 LSTB12: MOV AX,WORD PTR [DI] ;HEADER WORD ADD DI,2 ;NEXT ELEMENT LSTB15: CALL HEXSTR ;PUT IN BUFFER ADD WORD PTR [SI-2],2 ;SPACES LOOP LSTB12 ;KEEP IT MOVING MOV CX,WORD PTR [DI-2] ;CURRENT DATA LENGTH JCXZ LSTB17 ;DISPLAY MAX CMP CX,40 ;OVER MAX? JBE LSTB20 ;NO PROBLEM LSTB17: MOV CX,40 ;ALL THAT WILL FIT LSTB20: CALL MOVSTL ;MOVE TO BUFFER CALL MAKEPR ;MAKE PRINTABLE LSTB30: CALL WRMSG ;DISPLAY JC LSTB40 ;NO MORE MOV DI,[BP-2] ;START OF ELEMENT CMP WORD PTR [DI+QELEN],0 ;VALID LENGTH? JZ LSTB40 ;NO - QUIT ADD DI,WORD PTR [DI+QELEN] ;NEXT ELEMENT JC LSTB40 ;PAST END OF SEGMENT CMP DI,DS:BFRTL ;OUT OF RANGE? JNB LSTB40 ;YES JMP LSTB10 ;KEEP TRUCKING LSTB40: MOV SP,BP ;FREE LOCAL STORAGE POP BP ;RESTORE CALLER'S FRAME CALL FRELBF ;FREE LINE BUFFER CLC RET ;FORCE CALLER TO CHAT MODE FNCHAT: MOV AL,1CH ;FORCE CHAT MOV DX,300 ;'TO FORCE CHAT' JMP SHORT FNLO10 ;COMMON CODE ;FORCE TASK LOGOFF/MODEM RESET FNLOFF: MOV AL,1DH ;FORCE LOGOFF MOV DX,301 ;'TO FORCE LOGOFF' FNLO10: FRAME 2 CBW ;CLEAR AH MOV [BP-2],AX ;POST CODE MOV [BP-4],DX ;MESSAGE STRING CALL ILINEB ;INITIALIZE BUFFER MOV AX,298 ;'LINE #' CALL MOVMSG ;MOVE TO BUFFER MOV AX,[BP-4] ;MESSAGE STRING CALL MOVMSG ;MOVE TO BUFFER CALL QUERY ;GET RESPONSE JC FNLO90 ;EXIT ON ERROR CALL DQCMD ;GET RESPONSE MOV CX,WORD PTR [SI-2] ;RESPONSE LENGTH JCXZ FNLO90 ;NULL RESPONSE CMP BYTE PTR [SI],'D' ;DUMP REQUEST? JNZ FNLO20 ;NO ERR 500H ;TASK DUMP REQUEST FNLO20: CALL ASCBIN ;GET VALUE MOV DI,AX ;LINE NUMBER XCHG AH,AL ;LINE NUMBER ADD [BP-2],AX ;ADD LINE # TO POST CODE CMP DI,DS:TSKCNT ;VALID LINE NUMBER? JNB FNLO70 ;LINE NOT IN SESSION INC DI ;OFFSET FROM TSKCNT SHL DI,1 ;TABLE WIDTH MOV DI,DS:TSKCNT[DI] ;TASK CONTROL BLOCK TEST BYTE PTR [DI+CBMSR],MSRCD ;LINE IN SESSION? JNZ FNLO80 ;YES - GO POST CMP BYTE PTR [BP-2],1DH ;LOGOFF REQUEST? JNZ FNLO70 ;NO - ISSUE ERROR MSG MOV WORD PTR [DI+USRIP],OFFSET INITLN ;LINE INIT RTN MOV WORD PTR [DI+USRFL],0 ;MAKE DISPATCHABLE CLC ;SHOW GOOD RETURN JMP FNLO90 ;EXIT FNLO70: CALL ILINEB ;INITIALIZE BUFFER MOV AX,298 ;'LINE #' CALL MOVMSG ;MOVE TO BUFFER MOV AX,[BP-2] ;LINE # & POST CODE MOV AL,AH ;LINE NUMBER CBW ;MAKE WORD MOV CX,2 ;FIELD WIDTH CALL BINASC ;PUT IN STRING MOV AX,299 ;'NOT IN SESSION' CALL MOVMSG ;MOVE TO BUFFER CALL WRMSG ;DISPLAY MESSAGE STC ;SHOW ERROR JMP FNLO90 ;EXIT FNLO80: MOV AX,[BP-2] ;POST CODE CALL WPOST ;POST CALLER CLC FNLO90: MOV SP,BP ;FREE LOCAL STORAGE POP BP ;RESTORE CALLER'S FRAME CALL FRELBF ;FREE LINE BUFFER CALL FRECMD ;FREE COMMAND BUFFER RET ;----------------------------------------------------------- ;TOGGLE SNOOP FLAG ;----------------------------------------------------------- FSNOOP: XOR DS:MSGCKPT+MSOPTS,2 ;TOGGLE SNOOP FLAG TEST DS:MSGCKPT+MSOPTS,2 ;NOW ON? JZ FSNO10 ;NO TEST DS:MSGCKPT+MSOPTS,4 ;LINE TRACE ALREADY ON? JNZ FSNOST ;YES - DON'T ALLOCATE CALL SETWIN ;ALLOCATE SNOOP WINDOWS JMP FSNOST FSNO10: TEST DS:MSGCKPT+MSOPTS,4 ;LINE TRACE STILL ON? JNZ FSNOST ;YES - DON'T FREE WINDOW CALL RESWIN ;FREE SNOOP WINDOWS FSNOST: MOV AX,121 ;SNOOP ON TEST DS:MSGCKPT+MSOPTS,2 ;NOW ON? JNZ FSNO20 ;YES MOV AX,122 ;SNOOP OFF FSNO20: CALL WMSGNO ;DISPLAY MSG CLC RET ;----------------------------------------------------------------- ;TOGGLE SYSOP AVAILABLE FLAG ;----------------------------------------------------------------- FNPFLG: XOR DS:MSGCKPT+MSOPTS,1 ;TOGGLE SYSOP AVAILABLE FLAG FNPFST: MOV AX,135 ;SYSOP AVAILABLE TEST DS:MSGCKPT+MSOPTS,1 ;NOW ON? JNZ FNPF10 ;YES MOV AX,136 ;SYSOP NOT AVAILABLE FNPF10: CALL WMSGNO ;DISPLAY MSG CLC RET ;----------------------------------------------------------------- ;TOGGLE LINE TRACE FLAG ;----------------------------------------------------------------- FLINET: XOR DS:MSGCKPT+MSOPTS,4 ;TOGGLE TRACE FLAG TEST DS:MSGCKPT+MSOPTS,4 ;NOW ON? JZ FLIN10 ;NO TEST DS:MSGCKPT+MSOPTS,2 ;SNOOP ALREADY ON? JNZ FLINST ;YES - DON'T ALLOCATE CALL SETWIN ;ALLOCATE SNOOP WINDOWS JMP SHORT FLINST ;DISPLAY MSG FLIN10: TEST DS:MSGCKPT+MSOPTS,2 ;SNOOP STILL ON? JNZ FLINST ;YES - DON'T FREE WINDOW CALL RESWIN ;FREE SNOOP WINDOWS FLINST: MOV AX,133 ;TRACE ON TEST DS:MSGCKPT+MSOPTS,4 ;NOW ON? JNZ FLIN20 ;YES MOV AX,134 ;TRACE OFF FLIN20: CALL WMSGNO ;DISPLAY MSG CLC RET ;----------------------------------------------------------------- ;MINI DEBUGGER ;----------------------------------------------------------------- DEBUG: MOV AX,399 ;EXPERT MENU CALL QMSGNO ;GET RESPONSE JNC DEBU30 ;GOOD RESPONSE DEBUJX: JMP FNCLRS ;LOST CARRIER DEBU30: CALL DQCMD ;GET COMMAND MOV CX,WORD PTR [SI-2] ;RESPONSE LENGTH JCXZ DEBUJX ;EXIT ON NULL RESPONSE CALL XLATE ;MAKE UPPER CASE CMP CX,2 ;EXTENDED CMD? JAE DEBUJX ;YES - INVALID LODSB ;GET CMD CHAR MOV DI,OFFSET CTBLD1 ;VALID COMMAND STRING MOV CX,(JTBLD1-CTBLD1) ;TABLE LENGTH REPNZ SCASB ;CHECK FOR MATCH JNZ DEBUG ;NOT VALID SUB DI,OFFSET CTBLD1+1 ;OFFSET IN TABLE SHL DI,1 ;TABLE WIDTH CALL JTBLD1[DI] ;CALL TO ROUTINE JMP DEBUG ;NEXT COMMAND DBMENU: MOV AX,398 ;FULL MENU CALL WMSGNO ;DISPLAY RET DBEXIT: POP AX ;CLEAN UP STACK JMP FNCLRS ;CLEAR SCREEN AND EXIT ;----------------------------------------------------------------- ;HEX MEMORY DISPLAY ; BP-2 DEFAULT ADDRESS REGISTER ; BP-4 DEFAULT SEGMENT REGISTER ; BP-6 REGISTER ID CHARS ; BP-8 1ST LINE OFFSET COUNT ;---------------------------------------------------------------- HEXDSP: PUSH BP ;SAVE CALLER'S FRAME MOV BP,SP ;ESTABLISH LOCAL FRAME SUB SP,8 ;ALLOCATE LOCAL STORAGE XOR AX,AX ;NULL MOV [BP-2],AX ;CLEAR ADDRESS REGISTER MOV [BP-8],AX ;CLEAR OFFSET REGISTER MOV [BP-4],DS ;DEFAULT TO DATA SEG MOV AX,'SD' ;DS ID MOV [BP-6],AX ;SET DEFAULT ID CALL ILINEB ;INIT BUFFER MOV AX,302 ;'PRESS ESCAPE' CALL MOVMSG ;MOVE TO BUFFER CALL WRMSG ;DISPLAY MESSAGE HEXD00: MOV DI,[BP-2] ;DEFAULT VALUE MOV AL,'>' ;PROMPT CALL CONW ;WRITE TO SCREEN CALL LININ ;GET RESPONSE JNB HEXD10 ;GOOD RESPONSE JMP HEXDGX ;EXIT HEXD10: CALL DQCMD ;DEQUEUE COMMAND MOV CX,[SI-2] ;LENGTH JCXZ HEXD30 ;KEEP IT MOVING CALL XLATE ;MAKE UPPER CASE CMP BYTE PTR [SI],'Q' ;QUIT? JNZ HEXD15 ;NO JMP HEXDGX ;EXIT HEXD15: CMP BYTE PTR [SI+2],':' ;SEGMENT SPECIFIED? JNZ HEXD20 ;NO CALL DEBSEG ;PARSE SEG SPEC HEXD20: CALL GETHEX ;GET HEX VALUE MOV DX,AX ;REQUESTED ADDRESS AND AX,0FFF0H ;ALIGN WITH DISPLAY SUB DX,AX ;1ST LINE OFFSET MOV [BP-8],DX ;SAVE FOR CHAR DISPLAY MOV [BP-2],AX ;SET NEW ADDRESS HEXD30: MOV WORD PTR [BX+CBLINO],0 ;CLEAR LINE COUNT MOV CX,8 ;LINES TO DISPLAY HEXD40: MOV DI,[BP-2] ;POINT TO STORAGE CALL ILINEB ;INIT BUFFER MOV AX,[BP-6] ;REG ID CHARS CALL APPBYT MOV AL,AH CALL APPBYT MOV AL,':' ;DELIMITER CALL APPBYT ;ADD TO STRING MOV AX,DI ;STARTING ADDRESS CALL HEXSTR ;PUT IN BUFFER INC WORD PTR [SI-2] ;ADDITIONAL SPACE PUSH CX MOV CX,16 ;BYTES PER LINE MOV DX,[BP-8] ;1ST LINE OFFSET HEXD50: OR DX,DX ;OFFSET? JZ HEXD55 ;NO ADD WORD PTR [SI-2],2 ;BLANKS INC DI DEC DX JMP HEXD60 ;SKIP DIGIT HEXD55: PUSH DS MOV DS,[BP-4] ;TARGET SEGMENT REG MOV AL,BYTE PTR [DI] ;CURRENT HEX VALUE POP DS INC DI ;POINT TO NEXT CALL HEXBYT ;PUT IN BUFFER HEXD60: CMP CX,9 ;MIDDLE OF STRING? JNZ HEXD65 ;NO INC WORD PTR [SI-2] ;ADDITIONAL SPACE HEXD65: INC WORD PTR [SI-2] ;SPACE LOOP HEXD50 ;KEEP IT MOVING ADD WORD PTR [SI-2],4 ;SPACE MOV CX,16 ;CHARS TO DISPLAY MOV DI,[BP-2] ;RESET INDEX MOV DX,[BP-8] ;1ST LINE OFFSET SUB CX,DX ;CHARACTER COUNT ADD WORD PTR [SI-2],DX ;OFFSET IN LINE ADD DI,DX ;OFFSET IN MEMORY SUB DX,DX ;CLEAR OFFSET MOV WORD PTR [BP-8],DX ;AND REMEMBER PUSH ES MOV ES,[BP-4] ;TARGET SEG REG CALL MVLSTR ;MOVE TO BUFFER POP ES CALL MAKEPR ;MAKE PRINTABLE CALL WRMSG ;DISPLAY POP CX ADD WORD PTR [BP-2],16 ;NEXT LINE LOOP HEXD40 ;NEXT LINE JMP HEXD00 ;NEXT COMMAND HEXDGX: MOV SP,BP ;FREE LOCAL STORAGE POP BP ;RESTORE CALLER'S FRAME RET ;----------------------------------------------------------------- ;IO PORT DISPLAY ;---------------------------------------------------------------- IOPDSP: FRAME CALL ILINEB ;INIT BUFFER MOV AX,302 ;'PRESS ESCAPE' CALL MOVMSG ;MOVE TO BUFFER CALL WRMSG ;DISPLAY MESSAGE IOPD00: MOV AL,'>' ;PROMPT CALL CONW ;WRITE TO SCREEN CALL LININ ;GET RESPONSE JNB IOPD10 ;GOOD RESPONSE JMP IOPDGX ;EXIT IOPD10: CALL DQCMD ;DEQUEUE COMMAND MOV CX,[SI-2] ;LENGTH JCXZ IOPD00 ;PROMPT AGAIN CALL XLATE ;MAKE UPPER CASE CMP BYTE PTR [SI],'Q' ;QUIT? JNZ IOPD20 ;NO JMP IOPDGX ;EXIT IOPD20: CALL GETHEX ;GET HEX VALUE MOV DX,AX ;REQUESTED ADDRESS IN AL,DX ;GET VALUE MOV WORD PTR [BX+CBLINO],0 ;CLEAR LINE COUNT CALL ILINEB ;INIT BUFFER CALL HEXBYT ;PUT IN BUFFER CALL WRMSG ;DISPLAY JMP IOPD00 ;NEXT COMMAND IOPDGX: EXITF ;PARSE SEGMENT SPECIFICATION DEBSEG: MOV AX,[SI] ;GET REGISTER ID ADD SI,3 ;POINT TO ADDRESS CMP AL,'D' ;DS? JNZ DEBS10 ;NO MOV [BP-4],DS ;SET TO DS JMP DEBS80 ;DONE DEBS10: CMP AL,'E' ;ES? JNZ DEBS20 ;NO MOV [BP-4],ES ;SET TO ES JMP DEBS80 ;DONE DEBS20: CMP AL,'S' ;SS? JNZ DEBS90 ;NO - INVALID MOV [BP-4],SS ;SET TO SS DEBS80: MOV [BP-6],AX ;REMEMBER SEG ID DEBS90: RET GETHEX: PUSH CX PUSH DX XOR DX,DX ;CLEAR WORK REG MOV CL,4 ;SHIFT FACTOR GETH00: LODSB ;GET DIGIT SUB AL,'0' ;CONVERT TO BINARY JB GETH90 ;INVALID DIGIT CMP AL,10 ;HEX RANGE? JB GETH20 ;NO PROBLEM AND AL,0DFH ;MAKE UPPER CASE CMP AL,17 ;VALID RANGE? JB GETH90 ;NO SUB AL,7 ;CORRECT FOR HEX CMP AL,16 ;VALID? JNC GETH90 ;NO GETH20: SHL DX,CL ;SHIFT ADDRESS REGISTER OR DL,AL ;APPEND NEW DIGIT JMP GETH00 ;GET NEXT DIGIT GETH90: MOV AX,DX ;RESULT DEC SI ;RESTORE TERMINATOR POP DX POP CX CLC RET MAKEPR: PUSH SI PUSH CX MOV CX,WORD PTR [SI-2] ;LENGTH JCXZ MAKE30 ;DON'T GET CARRIED AWAY MAKE10: CMP BYTE PTR [SI],' ' ;PRINTABLE? JAE MAKE20 ;NO PROBLEM MOV BYTE PTR [SI],'.' ;REPLACE WITH DOT MAKE20: INC SI LOOP MAKE10 ;KEEP TRUCKING MAKE30: POP CX POP SI RET ;--------------------------------------------------------------------- ;NORMAL SHUTDOWN ROUTINE ;--------------------------------------------------------------------- SHUTDN: MOV SHUTFLG,0 ;CANCEL DEFERRED SHUTDOWN MOV AX,400 ;CONFIRM SHUTDOWN? CALL QMSGNO ;ASK OPERATOR JC SHUTDX ;LOST CARRIER CALL DQCMD ;GET COMMAND MOV CX,WORD PTR [SI-2] ;RESPONSE LENGTH JCXZ SHUT80 ;EXIT ON NULL RESPONSE CALL XLATE ;MAKE UPPER CASE LODSB ;GET RESPONSE CHAR CMP AL,'Y' ;YES? JZ SHUT40 ;IMMEDIATE SHUTDOWN CMP AL,'N' ;NORMAL SHUTDOWN? JNZ SHUT80 ;NO ;NORMAL SHUTDOWN CALL ILINEB ;INITIALIZE LINE BUFFER MOV AX,402 ;NORMAL SHUTDOWN CALL MOVMSG ;MOVE TO BUFFER CALL LOGDSK ;LOG CALL WRMSG ;DISPLAY RESPONSE MOV SHUTFLG,255 ;FLAG FOR SHUTDOWN JMP SHUT90 ;EXIT ;IMMEDIATE SHUTDOWN SHUT40: CALL ILINEB ;INITIALIZE LINE BUFFER MOV AX,401 ;IMMEDIATE SHUTDOWN CALL MOVMSG ;MOVE TO BUFFER CALL LOGDSK ;LOG CALL WRMSG ;DISPLAY RESPONSE MOV RETCODE,8 ;ERROR LEVEL MOV ABORT,255 ;SHUTDOWN FLAG JMP SHUT90 ;EXIT ;SHUTDOWN CANCELLED SHUT80: CALL ILINEB ;INITIALIZE LINE BUFFER MOV AX,403 ;SHUTDOWN CANCELLED CALL MOVMSG ;MOVE TO BUFFER CALL LOGDSK ;LOG CALL WRMSG ;DISPLAY RESPONSE SHUT90: CLC SHUTDX: RET SYSOP ENDP CSEG ENDS END