PAGE 75,128 TITLE SCRIPT - SCRIPT FILE HANDLER PAGE .XLIST INCLUDE CCBBS.MAC INCLUDE CCBBS.DEF .LIST ;----------------------------------------------- ;SYSTEM DATA SEGMENT ;----------------------------------------------- SYSDATA SEGMENT PARA PUBLIC 'DATA' DLMSTR DB ' ,=',9 ;DELIMITER STRING DLMSTX EQU $ CMD1 DW STR1,ECHO DW STR2,INPUT DW STR3,LOG DW STR4,GOTO DW STR5,IFCMD DW STR6,SET DW STR9,IFNCMD DW STR10,SEND DW STR11,WRITE DW STR12,SETL DW STR15,RETURN DW STR16,CALSPT CMDX EQU $ ;------------------------------------------------------------- ;PSEUDO-VARIABLE TABLE ; 0 POINTER TO VARIABLE NAME ; 2 OFFSET IN USER RECORD ; 3 TYPE BYTE ; 80 = STRING ; 40 = WORD ; 20 = BYTE ; 10 = BIT ; 08 = CAN BE SET ; 4 STRING LENGTH, BIT MASK, OR NUMERIC LIMIT ;------------------------------------------------------------- PVTBL DW PV1,8000H,31 ;UENAM DW PV2,4829H,0 ;UERTIM DW PV57,382DH,80H ;UESTAT2 - NAME IS HANDLE DW PV58,302DH,20H ;UESTAT2 - ABNORMAL LOGOFF DW PV59,302DH,10H ;UESTAT2 - TIMED LOGOFF DW PV60,382DH,08H ;UESTAT2 - MANUAL DELETE DW PV3,382EH,80H ;UESTAT - LOCKED OUT DW PV38,302EH,20H ;UESTAT - GLOBAL SYSOP DW PV39,382EH,10H ;UESTAT - LOCAL SYSOP DW PV4,382EH,8 ;UESTAT - VALIDATION REQUIRED DW PV5,382EH,4 ;UESTAT - VALIDATION REJECTED DW PV6,382EH,2 ;UESTAT - FIXED TIME ALLOCATION DW PV40,382EH,1 ;UESTAT - SIGOP AUTHORITY DW PV7,5833H,1 ;UESECT - 1 THROUGH 16 DW PV8,5833H,2 DW PV9,5833H,4 DW PV10,5833H,8 DW PV11,5833H,10H DW PV12,5833H,20H DW PV13,5833H,40H DW PV14,5833H,80H DW PV15,5833H,100H DW PV16,5833H,200H DW PV17,5833H,400H DW PV18,5833H,800H DW PV19,5833H,1000H DW PV20,5833H,2000H DW PV21,5833H,4000H DW PV22,5833H,8000H DW PV41,5837H,1 ;UESIGS 1-16 DW PV42,5837H,2 DW PV43,5837H,4 DW PV44,5837H,8 DW PV45,5837H,10H DW PV46,5837H,20H DW PV47,5837H,40H DW PV48,5837H,80H DW PV49,5837H,100H DW PV50,5837H,200H DW PV51,5837H,400H DW PV52,5837H,800H DW PV53,5837H,1000H DW PV54,5837H,2000H DW PV55,5837H,4000H DW PV56,5837H,8000H DW PV36,8839H,1 ;UEDLPC DW PV37,883AH,1 ;UEULPC DW PV28,383DH,1 ;UEUFLG 1-8 DW PV29,383DH,2 DW PV30,383DH,4 DW PV31,383DH,8 DW PV32,383DH,10H DW PV33,383DH,20H DW PV34,383DH,40H DW PV35,383DH,80H DW PV23,883EH,34 ;UEMEMO DW PV23A,5874H,80H ;UEOPTS - EXTENDED CHAR SET DW PV23B,5874H,40H ;UEOPTS - ANSI SCREEN SUPPORT DW PV24,5874H,20H ;UEOPTS - NO ALL MAIL DW PV25,5874H,10H ;UEOPTS - NEW MAIL ONLY DW PV26,5874H,8 ;UEOPTS - NO MAIL SCAN DW PV26A,5874H,4 ;UEOPTS - EXPERT MODE DW PV27,8878H,8 ;UEGID PVTBX EQU $ ;COMMAND STRINGS DW STR2-STR1-2 STR1 DB 'ECHO' DW STR3-STR2-2 STR2 DB 'INPUT' DW STR4-STR3-2 STR3 DB 'LOG' DW STR5-STR4-2 STR4 DB 'GOTO' DW STR6-STR5-2 STR5 DB 'IF' DW STR7-STR6-2 STR6 DB 'SET' DW STR8-STR7-2 STR7 DB 'Invalid command "' DW STR9-STR8-2 STR8 DB '" in script file.' DW STR10-STR9-2 STR9 DB 'IFNOT' DW STR11-STR10-2 STR10 DB 'SEND' DW STR12-STR11-2 STR11 DB 'WRITE' DW STR13-STR12-2 STR12 DB 'SETL' DW STR14-STR13-2 STR13 DB 'ON' DW STR15-STR14-2 STR14 DB 'OFF' DW STR16-STR15-2 STR15 DB 'RETURN' DW PV1-STR16-2 STR16 DB 'CALL' ;PSEUDO-VARIABLE STRINGS DW PV2-PV1-2 PV1 DB '@NAME' DW PV3-PV2-2 PV2 DB '@TIMEL' DW PV4-PV3-2 PV3 DB '@LOCK' DW PV5-PV4-2 PV4 DB '@VALREQ' DW PV6-PV5-2 PV5 DB '@VALREJ' DW PV7-PV6-2 PV6 DB '@FIXT' DW PV8-PV7-2 PV7 DB '@SECT1' DW PV9-PV8-2 PV8 DB '@SECT2' DW PV10-PV9-2 PV9 DB '@SECT3' DW PV11-PV10-2 PV10 DB '@SECT4' DW PV12-PV11-2 PV11 DB '@SECT5' DW PV13-PV12-2 PV12 DB '@SECT6' DW PV14-PV13-2 PV13 DB '@SECT7' DW PV15-PV14-2 PV14 DB '@SECT8' DW PV16-PV15-2 PV15 DB '@SECT9' DW PV17-PV16-2 PV16 DB '@SECT10' DW PV18-PV17-2 PV17 DB '@SECT11' DW PV19-PV18-2 PV18 DB '@SECT12' DW PV20-PV19-2 PV19 DB '@SECT13' DW PV21-PV20-2 PV20 DB '@SECT14' DW PV22-PV21-2 PV21 DB '@SECT15' DW PV23-PV22-2 PV22 DB '@SECT16' DW PV23A-PV23-2 PV23 DB '@MEMO' DW PV23B-PV23A-2 PV23A DB '@GRAF' DW PV24-PV23B-2 PV23B DB '@ANSI' DW PV25-PV24-2 PV24 DB '@ALLMAIL' DW PV26-PV25-2 PV25 DB '@NEWMAIL' DW PV26A-PV26-2 PV26 DB '@NOMAIL' DW PV27-PV26A-2 PV26A DB '@EXPERT' DW PV28-PV27-2 PV27 DB '@GROUP' DW PV29-PV28-2 PV28 DB '@FLAG1' DW PV30-PV29-2 PV29 DB '@FLAG2' DW PV31-PV30-2 PV30 DB '@FLAG3' DW PV32-PV31-2 PV31 DB '@FLAG4' DW PV33-PV32-2 PV32 DB '@FLAG5' DW PV34-PV33-2 PV33 DB '@FLAG6' DW PV35-PV34-2 PV34 DB '@FLAG7' DW PV36-PV35-2 PV35 DB '@FLAG8' DW PV37-PV36-2 PV36 DB '@UPLD' DW PV38-PV37-2 PV37 DB '@DNLD' DW PV39-PV38-2 PV38 DB '@GSYSOP' DW PV40-PV39-2 PV39 DB '@LSYSOP' DW PV41-PV40-2 PV40 DB '@SIGOP' DW PV42-PV41-2 PV41 DB '@SECF1' DW PV43-PV42-2 PV42 DB '@SECF2' DW PV44-PV43-2 PV43 DB '@SECF3' DW PV45-PV44-2 PV44 DB '@SECF4' DW PV46-PV45-2 PV45 DB '@SECF5' DW PV47-PV46-2 PV46 DB '@SECF6' DW PV48-PV47-2 PV47 DB '@SECF7' DW PV49-PV48-2 PV48 DB '@SECF8' DW PV50-PV49-2 PV49 DB '@SECF9' DW PV51-PV50-2 PV50 DB '@SECF10' DW PV52-PV51-2 PV51 DB '@SECF11' DW PV53-PV52-2 PV52 DB '@SECF12' DW PV54-PV53-2 PV53 DB '@SECF13' DW PV55-PV54-2 PV54 DB '@SECF14' DW PV56-PV55-2 PV55 DB '@SECF15' DW PV57-PV56-2 PV56 DB '@SECF16' DW PV58-PV57-2 PV57 DB '@HANDLE' DW PV59-PV58-2 PV58 DB '@NOUSER' DW PV60-PV59-2 PV59 DB '@NOTIME' DW PV61-PV60 PV60 DB '@NODEL' PV61 EQU $ SYSDATA ENDS ;----------------------------------------------- ;CODE SEGMENT ;----------------------------------------------- CSEG SEGMENT PARA PUBLIC 'CODE' EXTRN ERROR:NEAR,GETBUF:NEAR,FREBUF:NEAR,CONW:NEAR EXTRN STRIP:NEAR,XLATE:NEAR,ILINEB:NEAR,CMPSTA:NEAR EXTRN WRLIN:NEAR,WRCR:NEAR,LOGDSK:NEAR,MOVSTR:NEAR EXTRN WMSGNO:NEAR,WRMSG:NEAR,CONT:NEAR,CONR:NEAR EXTRN FRELBF:NEAR,LININ:NEAR,DQTIOA:NEAR,APPBYT:NEAR EXTRN APPDSK:NEAR,PADB:NEAR,ASCBIN:NEAR,MOVSTL:NEAR EXTRN YIELD:NEAR,BINASP:NEAR,MVCSTR:NEAR,CPCSTA:NEAR PUBLIC RUNFIL,SENDF,GPARM,GETLIN ASSUME CS:CSEG,DS:NOTHING,ES:SYSDATA RUNFIL PROC NEAR ;------------------------------------------------ ;INTERPRET SCRIPT FILE ; BP+10 PASSED PARM INDEX ; BP+8 USER RECORD ADDRESS ; BP+6 EXIT NAME ; BP+4 SCRIPT FILE NAME (DS) ; BP-2 WORK FLAGS ; 80H = PSEUDO-VARIABLE FOUND ; 04H = ANGLE BRACKETS OPEN ; 02H = RETURN VARIABLE NAME ; 01H = STOP AT 1ST DELIMITER ; BP-4 INPUT LINE CURRENT POSITION ; BP-6 WORK BUFFER - USED BY GTXT00 ; BP-8 VARIABLE INDEX ; BP-10 SCRIPT FILE HANDLE ; BP-12 WORK POINTER - AVAILABLE TO COMMAND RTNS ; BP-14 SESSION FLAGS ; 2 = USE IF NOT LOGIC ; 1 = LAST CMD WAS INPUT ; BP-16 LOOP COUNTER / RETURN CODE ; BP-18 SCRIPT FILE BUFFER ;------------------------------------------------- FRAME 9 PUSH SI PUSH DI MOV WORD PTR [BP-6],0 ;WORK BUFFER MOV WORD PTR [BP-14],1 ;SESSION FLAGS MOV WORD PTR [BP-16],500 ;MAXIMUM GOTO COUNT MOV WORD PTR [BP-18],0 ;NO FILE BUFFER ;OPEN SCRIPT FILE MOV AX,3D00H ;OPEN FOR INPUT MOV DX,[BP+4] ;FILE NAME INT 21H ;DOS REQUEST JNC RUNF10 ;OPEN OK MOV [BP-16],AX ;RETURN ERROR CODE JMP RUNF99 ;ERROR EXIT RUNF10: MOV [BP-10],AX ;FILE HANDLE MOV AX,260 ;BUFFER LENGTH CALL GETBUF ;GET FILE BUFFER MOV [BP-18],SI ;FILE BUFFER ADDRESS LEA DI,[SI+4] ;START OF DATA MOV WORD PTR [SI+2],DI ;START OF BUFFER MOV SI,[BP+10] ;PASSED PARMS MOV [BP-8],SI ;SET AS LOCAL OR SI,SI ;EXIST? JNZ RUNF20 ;YES - DON'T ALLOCATE MOV AX,200 ;100 VARIABLES CALL GETBUF ;GET INDEX BLOCK MOV [BP-8],SI ;INDEX POINTER MOV DI,[BP+6] ;EXIT NAME MOV AX,[DI-2] ;LENGTH CALL GETBUF ;GET BUFFER CALL MOVSTR ;MOVE EXIT NAME MOV DI,[BP-8] ;INDEX BASE MOV [DI],SI ;SAVE AS %0 MOV DI,WORD PTR [BX+USR1N] ;USER 1ST NAME MOV AX,[DI-2] ;LENGTH CALL GETBUF ;GET BUFFER CALL MOVSTR ;MOVE 1ST NAME MOV DI,[BP-8] ;INDEX BASE MOV [DI+2],SI ;SAVE AS %1 MOV DI,WORD PTR [BX+USR2N] ;USER LAST NAME MOV AX,[DI-2] ;LENGTH CALL GETBUF ;GET BUFFER CALL MOVSTR ;MOVE LAST NAME MOV DI,[BP-8] ;INDEX BASE MOV [DI+4],SI ;SAVE AS %2 MOV AX,2 ;LENGTH CALL GETBUF ;GET BUFFER MOV DI,[BP-8] ;INDEX BASE MOV [DI+6],SI ;SAVE AS %3 MOV AX,[BX+USRLN] ;PHYSICAL LINE NUMBER CALL BINASP ;PLACE IN BUFFER RUNF20: MOV AX,[BP-18] ;SCRIPT FILE BUFFER PUSH AX ;PASS AS PARAMETER MOV AX,[BP-10] ;SCRIPT FILE HANDLE PUSH AX ;PASS AS PARAMETER CALL GETLIN ;GET NEXT INPUT LINE JC RUNF90 ;END OF FILE MOV WORD PTR [BP-4],0 ;START OF LINE CALL CASE ;CASE COMMAND JMP RUNF20 ;GET NEXT COMMAND RUNF90: MOV WORD PTR [BP-16],1 ;END OF FILE RUNF92: MOV SI,[BP-6] ;WORK BUFFER CALL FREBUF ;RETURN IT MOV SI,[BP-18] ;FILE BUFFER CALL FREBUF ;FREE IT MOV DI,[BP-8] ;VARIABLE INDEX OR DI,DI ;INDEX EXIST? JZ RUNF98 ;NO CMP WORD PTR [BP+10],0 ;PARMS PASSED? JNZ RUNF98 ;YES - DON'T FREE MOV CX,100 ;NUMBER OF VARIABLES RUNF95: MOV SI,WORD PTR [DI] ;VARIABLE STRING CALL FREBUF ;RETURN VARIABLE ADD DI,2 ;NEXT VARIABLE LOOP RUNF95 ;DO REST MOV SI,[BP-8] ;VARIABLE INDEX CALL FREBUF ;FREE IT RUNF98: PUSH BX MOV BX,[BP-10] ;FILE HANDLE MOV AH,3EH ;CLOSE REQUEST INT 21H ;DOS FUNCTION CALL POP BX TEST WORD PTR [BP-14],1 ;NEED CR? JNZ RUNF99 ;NO CALL WRCR ;BLANK LINE RUNF99: MOV AX,[BP-16] ;RETURN CODE POP DI POP SI EXITF 4 ;SCRIPT FILE COMMAND ROUTINES ECHO: CALL GTXT ;GET TEXT STRING TEST WORD PTR [BP-14],1 ;INPUT LAST? JNZ ECHO10 ;YES - SKIP CALL WRCR ;NEW LINE ECHO10: AND WORD PTR [BP-14],NOT 1 ;LAST OP WAS OUTPUT CALL WRLIN ;WRITE LINE RET INPUT: CALL GVAR ;GET INPUT VARIABLE JC INPU90 ;INVALID MOV WORD PTR [DI],0 ;MARK IT FREE CALL FREBUF ;FREE IT MOV AL,' ' ;BLANK CALL CONW ;WRITE TO SCREEN OR WORD PTR [BP-14],1 ;LAST OP WAS INPUT CALL LININ ;GET USER INPUT JNC INPU10 ;GOOD RESPONSE POP AX ;KILL RETURN MOV WORD PTR [BP-16],-1 ;RETURN CODE JMP RUNF92 ;QUIT INPU10: CALL DQTIOA ;DEQUEUE RESPONSE MOV WORD PTR [DI],SI ;NEW VARIABLE STRING INPU90: RET LOG: CALL GTXT ;GET TEXT STRING CALL LOGDSK ;WRITE TO LOG RET GOTO: CALL GPARM ;GET TARGET LABEL CALL XLATE ;MAKE UPPER CASE MOV AX,WORD PTR [SI-2] ;STRING LENGTH INC AX ;ALLOW FOR DELIMITER MOV DI,SI CALL GETBUF ;GET WORK BUFFER MOV BYTE PTR [SI],':' ;LABEL DELIMITER MOV WORD PTR [SI-2],1 ;SET CURRENT LENGTH CALL MOVSTR ;COPY LABEL STRING MOV [BP-12],SI ;SAVE IN WORK AREA DEC WORD PTR [BP-16] ;LOOP COUNTER JS GOTO10 ;NO MORE BACKWARD GOTOS MOV SI,[BP-18] ;SCRIPT FILE BUFFER MOV WORD PTR [SI],0 ;SHOW BUFFER EMPTY MOV AX,4200H ;SEEK START OF FILE XOR CX,CX XOR DX,DX PUSH BX MOV BX,[BP-10] ;SCRIPT FILE HANDLE INT 21H ;DOS FUNCTION CALL POP BX GOTO10: MOV AX,[BP-18] ;SCRIPT FILE BUFFER PUSH AX ;PASS AS PARAMETER MOV AX,[BP-10] ;SCRIPT FILE HANDLE PUSH AX ;PASS AS PARAMETER CALL GETLIN ;GET NEXT LINE JB GOTO90 ;END OF FILE MOV WORD PTR [BP-4],0 ;START OF LINE CALL GPARM ;GET LABEL, IF ANY JC GOTO10 ;END OF LINE CALL XLATE ;MAKE UPPER CASE MOV DI,[BP-12] ;TARGET LABEL CALL CMPSTA ;MATCH? JNZ GOTO10 ;NO GOTO90: MOV SI,[BP-12] ;LABEL STRING CALL FREBUF ;FREE IT RET CALSPT: CALL GPARM ;GET TARGET LABEL CALL XLATE ;MAKE UPPER CASE MOV AX,WORD PTR [SI-2] ;STRING LENGTH INC AX ;ALLOW FOR DELIMITER MOV DI,SI CALL GETBUF ;GET WORK BUFFER CALL MOVSTR ;COPY LABEL STRING XOR AX,AX ;DELIMITER CALL APPBYT ;ADD TO STRING MOV [BP-12],SI ;SAVE IN WORK AREA MOV AX,[BP-8] ;VARIABLE INDEX PUSH AX MOV AX,[BP+8] ;USER RECORD PUSH AX MOV AX,[BP+6] ;EXIT NAME PUSH AX PUSH SI ;SCRIPT FILE NAME CALL RUNFIL ;RECURSIVE CALL MOV SI,[BP-12] ;SCRIPT NAME CALL FREBUF ;FREE IT RET IFNCMD: OR WORD PTR [BP-14],2 ;REVERSE LOGIC JMP SHORT IFCM00 ;COMMON ROUTINE IFCMD: AND WORD PTR [BP-14],NOT 2 ;EQUAL LOGIC IFCM00: CALL GPARM ;GET 1ST STRING CALL XLATE ;MAKE UC MOV AX,WORD PTR [SI-2] ;STRING LENGTH MOV DI,SI ;SAVE 1ST STRING CALL GETBUF ;GET WORK BUFFER CALL MOVSTR ;COPY STRING MOV WORD PTR [BP-12],SI ;SAVE IN WORK AREA CALL GPARM ;GET 2ND STRING CALL XLATE ;MAKE UC MOV DI,[BP-12] ;STRING1 CALL CMPSTA ;COMPARE STRINGS PUSHF ;SAVE RESULT MOV SI,[BP-12] ;LOOSE STRING CALL FREBUF ;FREE IT POP AX ;GET FLAGS TEST WORD PTR [BP-14],2 ;REVERSE LOGIC? JZ IFCM10 ;NO XOR AX,40H ;FLIP ZERO FLAG IFCM10: PUSH AX POPF ;TEST RESULTS JZ IFCM20 ;EXECUTE COMMAND RET IFCM20: JMP CASE ;GET COMMAND RETURN: CALL GPARM ;GET RETURN CODE MOV CX,[SI-2] ;LENGTH CALL ASCBIN ;CONVERT TO BINARY MOV [BP-16],AX ;RETURN CODE POP AX ;KILL RETURN JMP RUNF92 ;EXIT SEND: TEST WORD PTR [BP-14],1 ;INPUT LAST? JNZ SEND00 ;YES - SKIP CALL WRCR ;NEW LINE SEND00: CALL GPARM ;GET FILE NAME XOR AX,AX ;DELIMITER CALL APPBYT ;TERMINATE STRING MOV DX,SI ;FILE NAME STRING CALL SENDF ;SEND FILE OR WORD PTR [BP-14],1 ;SUPPRESS RET ;SET %n=STRING OR @VARIABLE=VALUE SET: CALL GVAR ;GET VARIABLE POINTER JNC SET01 ;GOOD RESULT JMP SETX ;NOT VALID SET01: TEST WORD PTR [BP-2],80H ;PSEUDO-VARIABLE? JNZ SET02 ;YES JMP SET50 ;NO SET02: TEST BYTE PTR ES:[DI+3],8 ;SETABLE? JNZ SET03 ;YES JMP SETX ;NO - EXIT SET03: MOV [BP-12],DI ;REMEMBER POINTER CALL GTXT ;GET ASSIGNMENT STRING TEST BYTE PTR ES:[DI+3],80H ;STRING VARIABLE? JZ SET10 ;NO MOV CX,ES:[DI+4] ;TARGET LENGTH CALL PADB ;PAD TO LENGTH XOR AX,AX MOV AL,ES:[DI+2] ;OFFSET IN USER RECORD MOV DI,[BP+8] ;USER RECORD ADD DI,AX ;INDEX INTO RECORD PUSH ES PUSH DS POP ES REP MOVSB ;MOVE TO FIELD POP ES CLC ;SHOW GOOD RETURN JMP SETX ;EXIT SET10: TEST BYTE PTR ES:[DI+3],10H ;BIT VARIABLE? JZ SET40 ;NO CALL XLATE ;UPPER CASE FOR TEST MOV DX,ES:[DI+4] ;BIT MASK XOR AX,AX MOV AL,ES:[DI+2] ;OFFSET IN RECORD MOV DI,OFFSET STR13 ;'ON' CALL CPCSTA ;MATCH? JNZ SET14 ;NO MOV DI,[BP+8] ;USER RECORD ADD DI,AX ;INDEX INTO RECORD OR [DI],DX ;TURN ON BIT CLC ;GOOD RETURN JMP SETX ;EXIT SET14: MOV DI,OFFSET STR14 ;'OFF' CALL CPCSTA ;MATCH? JNZ SET18 ;NO NOT DX ;AND LOGIC MOV DI,[BP+8] ;USER RECORD ADD DI,AX ;INDEX INTO RECORD AND [DI],DX ;TURN OFF BIT CLC ;GOOD RETURN JMP SETX ;EXIT SET18: STC ;SHOW ERROR JMP SETX ;EXIT SET40: MOV CX,[SI-2] ;STRING LENGTH CALL ASCBIN ;CONVERT TO NUMBER MOV DX,AX XOR AX,AX MOV AL,ES:[DI+2] ;OFFSET IN RECORD TEST BYTE PTR ES:[DI+3],40H ;WORD VALUE? PUSHF ;REMEMBER RESULT MOV DI,[BP+8] ;USER RECORD ADD DI,AX ;INDEX INTO RECORD POPF ;WORD? JZ SET45 ;NO MOV [DI],DX ;STORE WORD JMP SHORT SET48 ;EXIT SET45: MOV [DI],DL ;STORE BYTE SET48: CLC ;GOOD RETURN JMP SETX ;EXIT SET50: MOV [BP-12],SI ;VARIABLE ADDRESS CALL GTXT ;GET STRING MOV WORD PTR [DI],SI ;STORE IN INDEX MOV SI,[BP-12] ;OLD STRING CALL FREBUF ;FREE OLD STRING MOV WORD PTR [BP-6],0 ;NO WORK AREA SETX: RET SETL: CALL GVAR ;GET VARIABLE POINTER JC SETLX ;NOT VALID PUSH DI ;INDEX ENTRY MOV [BP-12],SI ;PARK STRING CALL GPARM ;GET LENGTH MOV CX,WORD PTR [SI-2] ;STRING LENGTH CALL ASCBIN ;CONVERT TO BINARY MOV CX,AX ;NEW LENGTH MOV SI,[BP-12] ;VARIABLE STRING OR SI,SI ;EXIST? JNZ SETL20 ;NO PROBLEM CALL GETBUF ;GET ONE SETL20: CALL PADB ;SET NEW SIZE POP DI ;INDEX ENTRY MOV WORD PTR [DI],SI ;PADB MAY HAVE CHANGED IT SETLX: RET WRITE: CALL GPARM ;GET FILE NAME XOR AX,AX ;DELIMITER CALL APPBYT ;ADD TO STRING MOV [BP-12],SI ;PARK IT MOV WORD PTR [BP-6],0 ;SHOW NO WORK BUFFER CALL GTXT ;GET TEXT STRING PUSH SI ;TEXT TO WRITE MOV SI,[BP-12] ;FILE NAME PUSH SI ;FILE NAME CALL APPDSK ;WRITE TO FILE MOV [BP-6],SI ;WORK BUFFER CAN CHANGE MOV SI,[BP-12] ;FILE NAME CALL FREBUF ;FREE FILE NAME RET SENDF: MOV AX,3D00H ;OPEN FOR INPUT INT 21H ;DOS REQUEST JNC SENDF1 ;OPEN OK STC ;SHOW FILE NOT FOUND RET SENDF1: PUSH BP ;SAVE CALLERS FRAME POINTER MOV BP,SP ;SET NEW FRAME POINTER SUB SP,4 ;RESERVE LOCAL STORAGE PUSH SI PUSH DI MOV [BP-2],AX ;FILE HANDLE MOV AX,260 ;BUFFER SIZE CALL GETBUF ;GET BUFFER MOV WORD PTR [BP-4],SI ;FILE BUFFER ADDRESS LEA DI,[SI+4] ;START OF DATA MOV WORD PTR [SI+2],DI ;START OF BUFFER MOV AX,29 ;USE ^K ... CALL WMSGNO CALL ILINEB ;GET LINE BUFFER SENDF2: MOV AX,[BP-4] ;SCRIPT FILE BUFFER PUSH AX ;PASS AS PARAMETER MOV AX,[BP-2] ;FILE HANDLE PUSH AX ;PASS AS PARAMETER CALL GETLIN ;GET INPUT LINE JC SENDF5 ;END OF FILE CALL WRMSG ;WRITE TO TERMINAL JC SENDF5 ;NO MORE CALL CONT ;CHECK INPUT JZ SENDF2 ;GET NEXT LINE CALL CONR ;READ CHAR JC SENDF5 ;LOST CARRIER CMP AL,11 ;ABORT? JNZ SENDF2 ;NO SENDF5: CALL FRELBF ;FREE LINE BUFFER MOV SI,[BP-4] ;FILE BUFFER CALL FREBUF ;FREE IT CALL WRCR ;NEW LINE PUSH BX MOV BX,[BP-2] ;FILE HANDLE MOV AH,3EH ;CLOSE FILE INT 21H ;DOS CALL POP BX JNC SENDF6 ;CLOSE OK ERR 4 SENDF6: POP DI POP SI MOV SP,BP POP BP CLC ;SHOW GOOD RETURN RET ;SUBROUTINES ;------------------------------------------------------------ ;GET LINE FROM FILE ; INPUT BP+4 = FILE HANDLE ; BP+6 = 260 BYTE WORK BUFFER ; RETURNS LINE FROM FILE IN STANDARD LINE BUFFER IF C=0 ;------------------------------------------------------------ GETLIN: PUSH BP ;SAVE CALLER'S FRAME MOV BP,SP ;ESTABLISH LOCAL FRAME GETL00: CALL ILINEB ;INIT LINE BUFFER MOV DI,SI ;START OF DATA GETL10: MOV CX,[SI-2] ;CURRENT LENGTH ADD CX,8 ;STRING HEADER CMP CX,[SI-6] ;MAX LENGTH JB GETL20 ;NO PROBLEM MOV AX,CX ;CURRENT MAX SHR AX,1 ;DIVIDE BY TWO SHR AX,1 ;25% OF ORIGINAL ADD CX,AX ;125% OF ORIGINAL SUB DI,SI ;CONVERT TO OFFSET CALL PADB ;EXTEND STRING CALL STRIP ;TRIM BLANKS MOV WORD PTR [BX+USRLB],SI ;UPDATE SYSTEM POINTER ADD DI,SI ;NEW BUFFER OFFSET GETL20: PUSH SI PUSH DI MOV SI,[BP+6] ;SCRIPT FILE BUFFER DEC WORD PTR [SI] ;REMAINING COUNT JNS GETL30 ;CHARACTER IN BUFFER LEA DI,[SI+4] ;START OF BUFFER MOV WORD PTR [SI+2],DI ;POINT TO START MOV CX,256 ;READ 256 CHARS PUSH BX MOV BX,[BP+4] ;SCRIPT FILE HANDLE MOV DX,WORD PTR [SI+2] ;INPUT BUFFER MOV AH,3FH ;READ REQUEST INT 21H ;DOS FUNCTION CALL POP BX OR AX,AX ;READ OK? JZ GETL90 ;END OF FILE DEC AX MOV WORD PTR [SI],AX ;NEW CHAR COUNT GETL30: MOV DI,[SI+2] ;POINT TO CHARACTER MOV AL,BYTE PTR [DI] ;CHAR READ POP DI MOV BYTE PTR [DI],AL ;STORE IN BUFFER INC WORD PTR [SI+2] ;POINT TO NEXT CHAR POP SI CMP AL,13 ;? JZ GETL10 ;YES - IGNORE CMP AL,10 ;? JZ GETL40 ;YES INC DI ;NEXT LINE POSITION INC WORD PTR [SI-2] ;COUNT CHARACTER JMP GETL10 ;GET NEXT CHAR GETL40: CALL STRIP ;TRUNCATE TRAILING BLANKS CLC ;SHOW GOOD RETUN JMP SHORT GETL99 ;EXIT GETL90: STC ;SHOW END OF FILE GETL99: MOV SP,BP ;FREE LOCAL STORAGE POP BP ;RESTORE CALLER'S FRAME CALL YIELD ;LET OTHERS RUN RET 4 CASE: CALL GPARM ;GET COMMAND JC CASE90 ;NULL LINE CMP BYTE PTR [SI],';' ;COMMENT JZ CASE90 ;YES - SKIP LINE CMP BYTE PTR [SI],':' ;LABEL? JZ CASE90 ;YES - SKIP LINE CALL XLATE ;MAKE UPPER CASE MOV DI,OFFSET CMD1 ;VALID COMMANDS CASE10: PUSH DI MOV DI,WORD PTR ES:[DI] ;NEXT COMMAND CALL CPCSTA ;MATCH ON COMMAND? POP DI JZ CASE20 ;YES ADD DI,4 ;POINT TO NEXT CMD CMP DI,OFFSET CMDX ;END OF LIST? JNZ CASE10 ;NO CALL ILINEB ;INITIALIZE BUFFER MOV DI,OFFSET STR7 ;INVALID COMMAND CALL MVCSTR ;MOVE TO BUFFER MOV DI,[BP-6] ;COMMAND STRING CALL MOVSTR ;MOVE TO BUFFER MOV DI,OFFSET STR8 ;IN SCRIPT FILE CALL MVCSTR ;MOVE TO BUFFER CALL LOGDSK ;LOG ERROR JMP CASE90 ;INVALID COMMAND CASE20: JMP WORD PTR ES:[DI+2] ;EXECUTE COMMAND CASE90: RET GVAR: MOV WORD PTR [BP-2],3 ;SET PARM & VAR FLAGS CALL GTXT00 ;GET PARAMETER STRING JC GVARX ;NO INPUT CMP BYTE PTR [SI],'@' ;PSEUDO-VARIABLE? JNZ GVAR50 ;NO - TRY TEXT VARIABLE CALL PVINX ;LOOK UP PSEUDO-VARIABLE JC GVARX ;NOT VALID OR WORD PTR [BP-2],80H ;MARK PSEUDO-VARIABLE FOUND CLC ;GOOD RETURN JMP GVARX ;EXIT GVAR50: CMP BYTE PTR [SI],'%' ;SYMBOLIC VARIABLE? STC ;ASSUME NO JNZ GVARX ;NO MOV AL,BYTE PTR [SI+1] ;GET VARIABLE NUMBER MOV AH,'0' ;ASSUME SINGLE DIGIT CMP WORD PTR [SI-2],3 ;TWO DIGIT? JNZ GVAR60 ;NO MOV AH,AL ;1ST DIGIT MOV AL,BYTE PTR [SI+2] ;2ND DIGIT GVAR60: CALL INDX ;GET VARIABLE ADDRESS GVARX: RET GPARM: MOV WORD PTR [BP-2],1 ;SET PARM FLAG JMP SHORT GTXT00 ;COMMON CODE GTXT: MOV WORD PTR [BP-2],0 ;CLEAR WORK FLAGS GTXT00: PUSH DI PUSH CX MOV DI,[BP-6] ;WORK BUFFER OR DI,DI ;EXIST? JNZ GTXT01 ;YES PUSH SI MOV AX,160 ;WORK AREA LENGTH CALL GETBUF ;GET BUFFER MOV [BP-6],SI ;INPUT POINTER MOV DI,SI ;DESTINATION REG POP SI GTXT01: MOV WORD PTR [DI-2],0 ;RESET LENGTH MOV SI,WORD PTR [BX+USRLB] ;INPUT BUFFER MOV CX,WORD PTR [SI-2] ;STRING LENGTH SUB CX,WORD PTR [BP-4] ;CURRENT POSITION JA GTXT02 ;OK JMP GTXT90 ;ALREADY PAST END GTXT02: ADD SI,WORD PTR [BP-4] ;NEXT POSITION GTXT10: CALL GCHAR ;GET NEXT CHAR JS GTXT80 ;END OF STRING CMP AL,' ' ;BLANK? JZ GTXT10 ;DELETE LEADING BLANKS CMP AL,9 ;TAB? JZ GTXT10 ;DELETE LEADING TAB JMP SHORT GTXT22 ;TEST FOR ANGLE BRACKETS GTXT20: CALL GCHAR ;GET NEXT CHAR JS GTXT80 ;END OF STRING GTXT22: CMP AL,'<' ;START OF BRACKETS? JNZ GTXT24 ;NO OR WORD PTR [BP-2],4 ;SHOW OPEN BRACKETS JMP GTXT20 ;GET NEXT CHAR GTXT24: TEST WORD PTR [BP-2],2 ;EXPAND VARIABLES? JNZ GTXT30 ;NO CMP AL,'%' ;SUBSTITUTION CHAR? JZ GTXT26 ;YES CMP AL,'@' ;PSEUDO VARIABLE? JNZ GTXT30 ;NO CALL PSEUDO ;EXPAND PSEUDO CHAR TEST WORD PTR [BP-2],1 ;STOP ON DELIMITER? JNZ GTXT80 ;YES - EXIT JMP GTXT20 ;CONTINUE SCAN GTXT26: CALL GCHAR ;GET NEXT CHAR JS GTXT80 ;END OF STRING CMP AL,'0' ;NUMERIC? JB GTXT40 ;NO - TREAT AS LITERAL CMP AL,'9' ;NUMERIC? JA GTXT40 ;NO - TREAT AS LITERAL MOV AH,'0' ;ASSUME SINGLE DIGIT JCXZ GTXT28 ;END OF STRING CMP BYTE PTR [SI],'0' ;NEXT CHAR NUMERIC? JB GTXT28 ;NO CMP BYTE PTR [SI],'9' ;NUMERIC? JA GTXT28 ;NO MOV AH,AL ;1ST DIGIT CALL GCHAR ;GET 2ND DIGIT GTXT28: CALL CONCAT ;CONCATANATE VARIABLE JMP GTXT20 ;GET NEXT CHAR GTXT30: TEST WORD PTR [BP-2],1 ;STOP ON DELIMITER? JZ GTXT38 ;NO TEST WORD PTR [BP-2],4 ;ANGLE BRACKETS OPEN? JNZ GTXT38 ;YES CALL CKDLM ;CHECK FOR DELIMITER JZ GTXT80 ;END OF PARM GTXT38: CMP AL,'>' ;CLOSE BRACKET? JNZ GTXT40 ;NO AND WORD PTR [BP-2],NOT 4 ;SHOW BRACKETS CLOSED JMP GTXT20 ;GET NEXT CHAR GTXT40: XCHG SI,DI ;FOR APPBYT CALL APPBYT ;APPEND TO STRING XCHG SI,DI JMP GTXT20 ;GET NEXT CHAR GTXT80: CLC JMP SHORT GTXT98 GTXT90: STC GTXT98: MOV SI,DI ;RETURNED STRING MOV [BP-6],SI ;CHANGED BY APPBYT? POP CX POP DI RET GCHAR: LODSB ;GET INPUT CHAR INC WORD PTR [BP-4] ;CURRENT POSITION DEC CX ;REMAINING CHARS RET CKDLM: PUSH DI PUSH CX MOV DI,OFFSET DLMSTR ;DELIMITER STRING MOV CX,DLMSTX-DLMSTR ;LENGTH REPNZ SCASB ;MATCH POP CX POP DI RET CONCAT: PUSH SI PUSH DI CALL INDX ;GET VARIABLE ADDRESS POP DI ;TARGET STRING JBE CONC90 ;INVALID OR NULL VARIABLE XCHG SI,DI ;FOR MOVSTR CALL MOVSTR ;ADD TO STRING MOV [BP-6],SI ;MIGHT HAVE CHANGED MOV DI,SI ;RESTORE DI CONC90: POP SI RET INDX: SUB AL,'0' ;CONVERT TO BINARY JB INDX90 ;INVALID SUB AH,'0' ;CONVERT TO BINARY JB INDX90 ;INVALID PUSH CX MOV CH,AL ;2ND DIGIT MOV CL,10 MOV AL,AH ;1ST DIGIT MUL CL ;TIMES TEN ADD AL,CH ;+ 2ND DIGIT POP CX CMP AL,100 ;VALID RANGE? JNB INDX90 ;NO CBW ;MAKE WORD MOV DI,AX ;MOVE TO INDEX SHL DI,1 ;INDEX WIDTH ADD DI,[BP-8] ;INDEX BASE MOV SI,WORD PTR [DI] ;VARIABLE STRING OR SI,SI ;EXIST? CLC RET INDX90: STC RET ;PSEUDO-VARIABLE EXPANSION ROUTINE PSEUDO: PUSH [BP-12] MOV [BP-12],DI ;PARK DESTINATION STRING PUSH SI PUSH AX MOV AX,CX ;REMAINING LENGTH CALL GETBUF ;GET BUFFER MOV DI,SI ;USE AS TARGET POP AX POP SI PUSH DI PSEU10: MOV [DI],AL ;MOVE TO BUFFER INC DI ;NEXT BUFFER POS CALL GCHAR ;GET NEXT CHAR JS PSEU20 ;END OF STRING CALL CKDLM ;DELIMITER? JNZ PSEU10 ;KEEP IT MOVING PSEU20: MOV AX,DI ;END OF STRING POP DI ;START OF STRING SUB AX,DI ;STRING LENGTH MOV [DI-2],AX ;SET LENGTH PUSH SI ;SOURCE STRING MOV SI,DI ;P-V STRING CALL PVINX ;LOOK UP VARIABLE PUSHF ;REMEMBER RESULT CALL FREBUF ;FREE STRING POPF ;VALID PV? POP SI ;SOURCE STRING JC PSEU90 ;INVALID PARM TEST BYTE PTR ES:[DI+3],80H ;STRING VARIABLE? JZ PSEU30 ;NO PUSH SI PUSH CX XOR AX,AX MOV AL,BYTE PTR ES:[DI+2] ;OFFSET MOV CX,WORD PTR ES:[DI+4] ;LENGTH MOV DI,[BP+8] ;USER RECORD ADD DI,AX ;INDEX INTO RECORD MOV SI,[BP-12] ;DESTINATION STRING CALL MOVSTL ;MOVE TO TARGET MOV [BP-12],SI ;MAY HAVE CHANGED CALL STRIP ;DELETE TRAILING BLANKS POP CX POP SI JMP PSEU90 ;DONE PSEU30: TEST BYTE PTR ES:[DI+3],10H ;BIT VARIABLE? JZ PSEU90 ;NO PUSH SI PUSH DX MOV SI,OFFSET STR13 ;ASSUME ON XOR AX,AX MOV AL,BYTE PTR ES:[DI+2] ;OFFSET MOV DX,WORD PTR ES:[DI+4] ;LENGTH MOV DI,[BP+8] ;USER RECORD ADD DI,AX ;INDEX INTO RECORD TEST [DI],DX ;BIT SET? POP DX JNZ PSEU35 ;YES MOV SI,OFFSET STR14 ;OFF PSEU35: MOV DI,SI ;SOURCE STRING MOV SI,[BP-12] ;TARGET STRING CALL MVCSTR ;MOVE TO TARGET MOV [BP-12],SI ;MAY HAVE CHANGED POP SI PSEU90: MOV DI,[BP-12] ;RESTORE TARGET STRING POP [BP-12] RET ;PSEUDO-VARIABLE LOOK UP ROUTINE ;ENTRY: SI -> PSEUDO-VARIABLE STRING ;RETURNS: DI -> ENTRY IN TABLE IF CLC PVINX: MOV DI,OFFSET PVTBL ;PSEUDO-VARIABLE TABLE CALL XLATE ;MAKE UPPER CASE PVIN10: PUSH DI MOV DI,WORD PTR ES:[DI] ;NEXT ENTRY CALL CPCSTA ;MATCH? POP DI JZ PVIN20 ;YES ADD DI,6 ;POINT TO NEXT ENTRY CMP DI,OFFSET PVTBX ;END OF TABLE? JNZ PVIN10 ;NO STC ;NOT FOUND PVIN20: RET RUNFIL ENDP CSEG ENDS END