.TITLE BATCH SUBMIT EXECUTOR .IDENT /V02.01/ .ENABLE LC ; ; VERSION V01.00 ; ; ERIC ROSDOL SWS/VIENA ; ; 11-FEB-78 ; ; MODULE CONTENTS: ; ; THIS MODULE CONTAINS ALL ROUTINES NECESSARY TO CONTROL THE ; THE PSEUDO BATCH FUNCTIONALITY OF THE SUBMIT COMMAND WITH ; THE VIRTUAL TERMINAL DRIVER VT: ; ; MODULE MODIFICATION HISTORY: ; ; JGD01 23-MAY-78 ; MODIFIED TO CLEAN UP A BIT, EXTEND BUFFER SIZE ; FOR LOG FILE, TRUNCATE LOG FILE ON EXIT, ETC ; CORRECT(OR TRY TO) SEVERE SYNCRONIZATION PROBLEMS ; WITH LOGGING ON. ALSO (TOGETHER WITH BYE MODIFICATIONS) FIX ; LOGOFF SYNCRONIZATION PROBLEM. ; ALSO AS INITIALLY WRITTEN, BATCH(NE' SEX...) ; DID NOT CORRECTLY USE THE UIC OF THE ; SENDER TASK WHEN INSTALLED AS SLAVE. ; ; JGD02 SPEED BATCH UP A BIT. HAVE BYE SEND A '>' IF ; A VT: LOGS OFF. BATCH NEED NOT WAIT 10 SEC FOR BYE ; COMMAND TO TIME OUT(THIS IS REALLY A BYE FIX). CHECK FOR ; ...AT. TO BECOME ACTIVE BEFORE STARTING TIMEOUT ON READS ; TO ...AT. THIS SOLVES A WEIRD PROBLEM IN WHICH IF ...AT. ; WAS NOT ACTIVATED BY THE @COMMAND AT VT: WITHIN 2 SECONDS ; BATCH WOULD SEND A BYE TO MCR FROM VT:. BYE WOULD THEN ; PROCEED TO ABORT ...AT. BEFORE IT HAD EVEN STARTED EXECUTING ; THE COMMAND FILE. THIS PROBLEM ONLY OCCURED WHEN THE SYSTEM ; WAS LOADED DOWN. ; ; JGD03 A MAJOR REWRITE. AS INITIALLY WRITTEN, BATCH WOULD MALFUNCTION ; WITH ANY NON MCR COMMANDS. THIS WAS BECAUSE BATCH TIMES OUT ; IF IT DID NOT NOTICE THAT MCR WAS PROCESSING AN INDIRECT COMMAND ; (IE U2.AT ON). THIS MEANT NICE FEATURES LIKE CREATING COMMAND ; FILES ON THE FLY WERE IMPOSSIBLE. ; TO FIX THIS PROBLEM, AST'S ARE NOT USED TO TIME OUT ; READS TO VT:(THE OUTPUT FROM THE BATCH ...AT.). THIS SPEEDS ; THINGS UP AT TIMES. SINCE THERE ARE NO LONGER ANY(OR ALMOST) ; TIMEOUTS, THE END OF THE INDIRECT COMMAND FILE IS DETECTED BY ; SCANNING THE BUFFER FOR @ , AT WHICH POINT THE COMMAND ; IS SENT TO VT: TO LOG OFF. WITH THESE CHANGES, THE PREVIOUS ; BYE CHANGES COULD BE REMOVED, AND MAYBE SOMEDAY THEY WILL. ; ; JGD04 BATCH AND ALL THE TASKS IT SPAWNED ON VT: CAN HANG UP IF ; BATCH GETS SHUFFLED. DOING QIO IO.KIL AND MARKTIMES DO ; NOT SEEM TO SOLVE THE PROBLEM, NEITHER DOES PUTTING A ; TIMEOUT COUNT IN VTDRV. IT LOOKS AS IF THE SYSTEM PLACES ; A CHECKPOINT REQUEST TO BAT...(IT GETS MARKED WITH CKR) ; AND ALL ITS REGISTERS AND PC GETS SAVED, BUT IT CAN'T ; CHECKPOINT BECAUSE ITS IO COUNT IS ALMOST NEVER ZERO. ; AVOID PROBLEM BY MAKING BATCH NON-CHECKPOINTABLE JUST ; DURING THE TIMES IT IS READING FROM VT: ; ; JGD13 MODIFY TO WORK WITH V3.2, START TO TRY TO MAKE IT MORE ; LOGICAL. NOW HELLO AND BYE SIGNAL THEIR EXIT ; WITH A $SOJ AND A $EOJ RESPECTIVELY ; ; JGD14 NO LONGER SUBMIT COMMAND FILES TO ...AT. RATHER LET ; THE FILES BE EXECUTED ON VT0: BY ...PIN. NOW ...PIN ; WILL ONLY EXECUTE SIMPLE MCR COMMANDS, BUT(!!) IT IS ; ALMOST 4 TIMES SMALLER THAN ...AT. ; ; JGD15 CONVERT TO USE A DEVICE SET WITH A GLOBAL PATCH AT ; TASK BUILD TIME. ; ; ; Modified by:- ; ; Phil Stephensen-Payne, ; c/o Systime Ltd., ; Concourse Computer Centre, ; 432 Dewsbury Road, ; LEEDS LS11 7DF, ; England. ; ; PSP01 Remove all the patches that require a non-standard system. ; (These might be replaced under conditionals later). ; Handle new packet format from SUBMIT which explicitly ; includes TI: device and UIC (only set for SLAVE take if ; requested - i.e. if BAT... already active the old method ; wouldn't work). ; Tidy up a lot. ; ; PSP02 Change output file format to allow things like 'RST HELP'. ; First try to log terminal off, just in case somebody left ; it logged on. ; ; PSP03 Modify to use IO.WBT in answer to password prompt - thus ; avoiding race conditions. Allow new 'Batch' files which ; are handled directly by BAT rather than by AT. ; ; THIS CODE EXPLICITLY EXCLUDES THE ORIGINAL NETWORK CODE ; ; Packet format to BAT... is:- ; ; WD01-WD07 Command Line to HELLO ; WD08-WD10 Filename (in RAD50) ; WD11 TI: Device of User ; WD12 SY: Device of User ; WD13 UIC of User ; ; Note the format of the device in WDs 11 & 12 is a special one, viz. ; RAD50 representation of device mnemonic plus binary unit number. ; This will handle all devices up to Unit 50 (octal) on standard devices. ; The only place this might be a trouble would be TT, in which case you ; could drop the mnemonic altogether. ; .PAGE .SBTTL DATA Data Definitions ; ; MACRO CALL DEFINITIONS ; .MCALL QIOW$,MRKT$S,RCVX$S,EXIT$S,GTIM$S,FDAT$A,OPEN$W,GET$ .MCALL CMKT$S,GLUN$S,DIR$,QIOW$S,ASTX$S,QIO$,CLOSE$,OPEN$R,PUT$ .MCALL FDBDF$,FDRC$A,FDOP$A,FSRSZ$,FINIT$,OPEN$U .MCALL UCBDF$,WTSE$S,ENCP$S,DSCP$S,NMBLK$,ALUN$S .MCALL QIOW$ UCBDF$ ; ; LOCAL MACRO DEFINITIONS ; ; PRINT AN ASCIZ STRING .MACRO PRINT STRING MOV R0,-(SP) MOV R1,-(SP) MOV #STRING,R0 CALL PNTLIN MOV (SP)+,R1 MOV (SP)+,R0 .ENDM PRINT .NLIST BEX ; ; EQUATED SYMBOLS ; LF=12 CR=15 FF=14 VTTIMO=1 ; Timeout on VT1 reads (in seconds) GENEFN=4 ; EFN for general use (e.g. IO.KIL) VTWEFN=5 ; EFN for writes to VT1 VTREFN=6 ; EFN for reads from VT1 TTYEFN=7 ; EFN for terminal I/O LOGLUN=1 ; LUN for Log File VT0LUN=2 ; LUN for VT0 (for status information) VT1LUN=3 ; LUN for VT1 (communication) TTYLUN=4 ; LUN for user's terminal INPLUN=5 ; LUN for input file ; ; FILE DEFINITION BLOCKS ; LOG: FDBDF$ FDAT$A R.VAR ; FDRC$A ,LOGBUF,132. ; EXPAND LOGBUF TO 132. TO HANDLE LONG LINES FDOP$A LOGLUN,,LOGNB,FO.WRT INPFDB: FDBDF$ FDAT$A R.VAR ; FDRC$A ,LOGBUF+1,132. ; EXPAND INPBUF TO 132. TO HANDLE LONG LINES FDOP$A INPLUN,,LOGNB,FO.RD ; ; FILE STORAGE REGION ; FSRSZ$ 2 ; ONLY ONE FILE AT A TIME ; ; Default File Nameblock for Log-File ; LOGNB: NMBLK$ ,LOG,1,SY,0 ; CTRLZ: .BYTE 26. BYEBUF: .ASCII /BYE/<15> BYECT=.-BYEBUF SETU: .ASCII \SET /UIC=[\ UIC1: .BLKB 3 .ASCII /,/ UIC2: .BLKB 3 .ASCII /]/<15> SETUL=.-SETU .EVEN ; ; Legal AT 'Error Messages' ; ATMSG: .WORD AT1,AT1L .WORD AT2,AT2L .WORD 0 AT1: .ASCII /DELAYING/ AT1L=.-AT1 AT2: .ASCII /CONTINUING/ AT2L=.-AT2 .EVEN ; ; Conversion Table for VFC formats ; VFCTAB: .BYTE ' ,LF,0,CR .BYTE '0,LF,LF,CR .BYTE '1,FF,0,CR .BYTE '+,0,0,CR .BYTE '$,LF,0,0 .BYTE 0,0,0,0 VFCNUM=<.-VFCTAB>/4 ; ; DIRECTIVE PARAMETER BLOCKS ; VT1WRT: QIO$ IO.WLB,VT1LUN,VTWEFN,,,,<0,0,0> VT1RD: QIOW$ IO.RLB,VT1LUN,VTREFN,,VTSTAT,, ; ASK FOR UP TO 132 CHARACTERS BACK QIODPB: QIOW$ IO.WVB,TTYLUN,TTYEFN,,,,<0,0,40> ; WRITE TO TERMINAL ; VTSTAT: .BLKW 2 ; LUNINF: .BLKW 6 ; LUN INFORMATION .WORD ; Prefix for CMDBUF CMDBUF: .BLKW 2 ; SENDERS TASK NAME RAD50 SPEC: .BLKW 15. ; SPECIFIER BUFFER AND OVERHEAD TIMOUT: .WORD 0 ; TIMEOUT INDICATOR .WORD ; LOGBUF: .BLKB 140. ; BUFFER FOR LOGFILE RECORD FILNM: .ASCII /@/ ; For Command file .BLKB 11. ; Nine chars for filename, & spare MRKRET: .WORD 0 ; Return address for Mark Time AST LOGCNT: .WORD 0 ; NUMBER OF TIMES TRIED LOGGING ON SAVSP: .WORD ; Saved Stack Pointer EOFFLG: .BYTE 0 ; FLAG TO INDICATE END OF INDIRECT LOGFLG: .BYTE 0 ; Flag for SBMCMD HELERR: .BYTE 0 ; FLAG TO INDICATE LOGIN ERROR INPFIL: .BYTE 0 ; Flag for input from file ; ; LOCAL MESSAGES ; MSG1: .ASCII <15>/BAT -- YOUR COMMAND FILE (/ MS1NAM: .BLKB 9. .ASCIZ /) IS FINISHED/<15><12><7><7>/>/ MSG2: .ASCII <15>\BAT -- I/O ERROR ON \ MS2NAM: .BLKB 3 .ASCIZ / FILE /<7><7><15><12>/>/ MSG3: .ASCIZ <15>/BAT -- ATTACH FAILURE ON VIRTUAL TERMINAL/<7><7><15><12>/>/ MSG4: .ASCIZ <15>/BAT -- USER CANNOT LOG ONTO VT, TRY AGAIN/<7><15><12>/>/ .EVEN HDRTXT: .ASCII <12>/** START OF COMMAND FILE SUBMITTED BY / TERNAM: .BYTE 0,0,0,0,0,0 .ASCII / ON / OUTDAT: .BYTE 0,0,0,0,0,0,0,0,0 .ASCII / AT / OUTTIM: .BYTE 0,0,0,0,0 .ASCII / **/<15> HDRLN=.-HDRTXT .EVEN .PAGE .SBTTL START Mainline code ;+ ; **-START ; ; THIS ROUTINE TRIES TO GET A DATA PACKET OUT OF ITS RECEIVE QUEUE. ; IF THIS QUEUE IS EMPTY, IT SIMPLY EXITS. IF NOT, ; COMMAND LOGON INFORMATION IS PARSED AND THE ; HELLO MCR FUNCTION EXECUTED ON VT1:. AFTER LOGGING IN, THE ; INDIRECT COMMAND FILE IS SUBMITTED TO VT1: FOR EXECUTION. ; NOTE THAT THE VIRTUAL TERMINAL IS NOT USED TO SUBMIT MCR TYPE ; COMMANDS FROM AN UNPRIVILEGED TASK. IT IS USED TO GET ; INDIRECT COMMAND FILE INFORMATON LOGGED INTO A FILE RATHER THAN ON THE ; NORMAL TI: TERMINAL (WHICH IN ADDITION IT TIES UP). ; ; Originally BATCH took the TI: device and UIC from the person who ; requested it - which might not be the person who submitted the ; packet in the queue. Now that information is passed in the packet ; from SUBMIT. In either case:- ; THIS REQUIRES THAT BATCH BE PRIVILEGED BECAUSE IT MUST BE ABLE TO WRITE ; INTO ANY UIC REQUESTED BY SUB. ALSO IT MUST BE PRIVLEGED TO CONTINUE ; EXECUTION IF USER LOGS OFF HIS TERMINAL.(BATCH MUST NEVER BE ABORTED). ; ; NOTE, IT IS NECESSARY TO INSERT THE TASK'S UIC INTO $FSR2. SINCE BAT... ; IS A SLAVE TASK,'S UIC BECOMES THAT OF THE INITIATING TERMINAL. WHEN IT ; INITIATED, THE ACT OF FIRST STARTING BATCH UP, CORRECTLY INITIALIZES THE ; DEFAULT DIRECTORY STRING IN $$FSR2. HOWEVER, IF BATCH RECEIVES ANOTHER ; REQUEST BEFORE EXITING, THE DEFAULT UIC IN $$FSR2 MUST BE CHANGED TO ; THAT OF THE NEW TERMINAL'S UIC. THERE MUST BE A BETTER WAY OF DOING THIS ; THAN THE FOLLOWING, BUT I HAVEN'T BEEN ABLE TO GET ANY TO WORK CORRECTLY ; START: MOV SP,SAVSP ; Save the stack pointer ; LOOP: MOV SAVSP,SP ; Restore the stack pointer FINIT$ ; Initialise $$FSR CLRB HELERR ; RESET FLAG CLRB INPFIL ; RCVX$S ,#CMDBUF ; GET FIRST PACKET (COMMAND) ; We must now set up the relevant UIC and ; SY: and TI: devices for BAT corresponding ; to those given in the packet CLRB EOFFLG ; ON TO SHOW THAT NOT AT END OF FILE YET MOV SPEC+24.,R1 ; Get the UIC CALL .WDFUI ; Stuff it in $$FSR2 MOV #UIC1,R0 ; Convert and insert the UIC group MOVB SPEC+25.,R1 ; MOV #1,R2 ; CALL $CBTMG ; MOV #UIC2,R0 ; Convert and insert the UIC member MOVB SPEC+24.,R1 ; MOV #1,R2 ; CALL $CBTMG ; MOV #LUNINF,R0 ; Get somewhere to stuff the converted name MOV SPEC+22.,R1 ; Get SY: in weird format CALL $C5TA ; Convert to ASCII CLR LUNINF+2 ; And clear odd bit at end MOV #LUNINF,R0 ; Reset to convert back CALL $CAT5 ; SUB R1,SPEC+22. ; And hence get the unit MOV LUNINF,LOGNB+N.DVNM ; Stuff in filename block MOV SPEC+22.,LOGNB+N.UNIT ; MOV SPEC+14.,LOGNB+N.FNAM ; Insert the filename MOV SPEC+16.,LOGNB+N.FNAM+2 ; MOV SPEC+18.,LOGNB+N.FNAM+4 ; MOV #^RLOG,LOGNB+N.FTYP ; Insert extension MOV #1,LOGNB+N.FVER ; version 1 for log files CMP SPEC+18.,#-1 ; A BAT file BNE 5$ ; If NE no - carry on CLR LOGNB+N.FNAM+4 ; Yes - clear out indicator INCB INPFIL ; Flag its presence ; 5$: CLR SPEC+14. ; Provide Null in case needed MOV #LUNINF,R0 ; Get somewhere to stuff the converted name MOV SPEC+20.,R1 ; Get TI: in weird format CALL $C5TA ; Convert to ASCII CLR LUNINF+2 ; And clear odd bit at end MOVB LUNINF,TERNAM ; Save it for message MOVB LUNINF+1,TERNAM+1 ; MOV #LUNINF,R0 ; Reset to convert back CALL $CAT5 ; SUB R1,SPEC+20. ; And hence get the unit MOV #TERNAM+2,R0 ; Get address for unit MOV SPEC+20.,R1 ; Get unit number CLR R2 ; Suppress zeroes CALL $CBOMG ; Convert the unit number MOVB #':,(R0)+ ; Insert trailing colon ALUN$S #TTYLUN,LUNINF,SPEC+20. ; Assign a LUN to it ALUN$S #VT0LUN,#"VT,#0 ; ASSIGN TO VT AND CHECK IF LOADED BCC 10$ ; IF CC DEVICE OK JMP ATTERR ; PRINT ERROR MESSAGE 10$: ALUN$S #VT1LUN,#"VT,#1 ; ASSIGN TO COMMAND INPUT QIOW$S #IO.ATT,#VT1LUN,#GENEFN ; ATTACH VT1 TERMINAL BCC 20$ ; IF CC ATTACH OK JMP ATTERR ; OTHERWISE PRINT ERROR 20$: GLUN$S #VT0LUN,#LUNINF ; READ LUN INFO FOR VT0: BIT #U2.LOG,LUNINF+6 ; IS VT: LOGGED ON BNE 27$ ; If NE no - carry on MOV #BYEBUF,VT1WRT+Q.IOPL ; Yes - SETUP ADDRESS OF BYE BUFFER MOV #BYECT,VT1WRT+Q.IOPL+2 ; AND BYTE COUNT MOV #27$,MRKRET ; Set return address MRKT$S ,#5,#2,#MKAST1 ; TIMEOUT ON BYE FOR SOME STRANGE REASONS CLRB LOGFLG ; Don't output any returned stuff CALL SBMCMD ; ISSUE BYE COMMAND ALTERNATE ENTRY ; 25$: CALL VTREAD ; Try to read something from VT1 BCS 27$ ; If CS - we timed out, or got IE.EOF BR 25$ ; Else try again ; 27$: QIOW$S #IO.KIL,#VT1LUN,#GENEFN ; TIDY UP ANY LEFT OVER I/O MOV #CMDBUF,R1 ; GET ADDRESS OF SPEC'S MOV #"HE,(R1)+ ; STORE THE LOGGON MOV #"L ,(R1)+ ; COMMAND FOR VT1 30$: TSTB (R1)+ ; IS IT A NULL? BNE 30$ ; IF NE NO CARRY ON MOVB #12,CMDBUF-1 ; Insert a (for Log File only) MOVB #15,-1(R1) ; STUFF IN A SUB #CMDBUF,R1 ; GET LENGTH OF STRING MOV R1,VT1WRT+Q.IOPL+2 ; SETUP DPB COUNT FIELD MOV #CMDBUF,VT1WRT+Q.IOPL ; AND DPB ADDRESS FIELD MOV #FILNM+1,R0 ; Get Address of Filename Buffer MOV #LOGNB+N.FNAM,R3 ; And of Filename MOV (R3)+,R1 ; Get and convert it CALL $C5TA ; MOV (R3)+,R1 ; CALL $C5TA ; MOV (R3)+,R1 ; CALL $C5TA ; CLRB LOG+F.RATT ; Insure FD.CR bit cleared OPEN$W #LOG ; OPEN OUTPUT FILE BCC 50$ ; IF CC NO FILE ERROR JMP FILERR ; OPEN ERROR ; 50$: TSTB INPFIL ; Data from input file? BEQ 55$ ; If EQ no - carry on MOV #^RDAT,LOGNB+N.FTYP ; Yes - reset file extension CLR LOGNB+N.FVER ; version 0 for data files CLR LOGNB+N.FID ; And file ID CLR LOGNB+N.FID+2 ; CLR LOGNB+N.FID+4 ; OPEN$R #INPFDB ; Open Input File BCC 55$ ; If CC - no error JMP FILERR ; Else log error ; 55$: GTIM$S #LOGBUF ; Get date & time information MOV #OUTDAT,R0 ; Get output address for date MOV #LOGBUF,R1 ; Get input address of date CALL $DAT ; Convert it MOV #OUTTIM,R0 ; Reset for time MOV #2,R2 ; just want HH:MM CALL $TIM ; Convert that as well PUT$ #LOG,#HDRTXT,#HDRLN ; WRITE LOG HEADER BCC 60$ ; IF CC PUT OK JMP FILERR ; OTHERWISE FILE ERROR ; 60$: INC VT1WRT+Q.IOPL+2 ; Include LF for file output PUT$ #LOG,#CMDBUF-1,VT1WRT+Q.IOPL+2 ; LOG THE HELLO INPUT BCC 70$ ; IF CC OK JMP FILERR ; OTHERWISE FILE ERROR ; 70$: MOVB #1,LOGFLG ; Echo any replies CALL SBMCMD ; ISSUE HELLO COMMAND QIOW$S #IO.KIL,#VT1LUN,#GENEFN ; TIDY UP ANY LEFT OVER I/O TSTB HELERR ; WAS LOGIN OK BNE 72$ ; IF NE, NO CALL CKLOG ; SEE IF TERMINAL LOGGED ON ALRIGHT BCC 75$ ; LOGGED ON OK, PROCEED MOV #CTRLZ,VT1WRT+Q.IOPL ; Kill any outstanding reads MOV #1,VT1WRT+Q.IOPL+2 ; AND BYTE COUNT CALL SBMCMD ; ISSUE KILL COMMAND ; 72$: CLOSE$ #LOG ; CLOSE THE LOG FILE PRINT MSG4 ; WARN USER THAT HE COULDN'T LOG ONTO VT: CLR TIMOUT ; RESET TIMEOUT SWITCH QIOW$S #IO.KIL,#VT1LUN,#GENEFN ; TIDY UP ANY LEFT OVER I/O JMP LOOP ; GET A NEW COMMAND LINE ; 75$: ; PUT$ #LOG,#SETU,#SETUL ; LOG THE SET /UIC INPUT MOV #SETU,VT1WRT+Q.IOPL ; Yes - SETUP ADDRESS OF SET /UIC BUFFER MOV #SETUL,VT1WRT+Q.IOPL+2 ; AND BYTE COUNT CALL SBMCMD ; ISSUE SET /UIC COMMAND TSTB INPFIL ; Data from input file? BEQ 80$ ; If EQ no - get AT to do the work CALL BATPRC ; Yes - handle data from input file BR 90$ ; Then continue in common code ; 80$: CALL ATPRC ; Get AT to do the work ; 90$: TSTB HELERR ; Did we ever log in? BNE 110$ ; If NE no - then why log out? QIOW$S #IO.KIL,#VT1LUN,#GENEFN ; KILL ANY LEFT OVER IO MOV #BYEBUF,VT1WRT+Q.IOPL ; SETUP ADDRESS OF BYE BUFFER MOV #BYECT,VT1WRT+Q.IOPL+2 ; AND BYTE COUNT MOV #110$,MRKRET ; Set return address for AST MRKT$S ,#10,#2,#MKAST1 ; TIMEOUT ON BYE FOR SOME STRANGE REASONS MOVB #1,LOGFLG ; Echo any replies CALL SBMCMD ; ISSUE BYE COMMAND ALTERNATE ENTRY ; 100$: CALL VTREAD ; Try to read something from VT1 BCS 110$ ; If CS - we timed out, or got IE.EOF CALL PUTBUF ; Output whatever we got BR 100$ ; Else try again ; 110$: QIOW$S #IO.KIL,#VT1LUN,#GENEFN ; TIDY UP ANY LEFT OVER I/O CMKT$S ; CANCEL THE MARK TIME TSTB INPFIL ; Input File? BEQ 120$ ; If EQ no - carry on CLOSE$ #INPFDB ; Yes - close it ; 120$: CLOSE$ #LOG ; CLOSE THE FILE, THE USER CAN PIP IT TO TI: BCS 140$ ; If CS log error ; ; IF IT IS DESIRED TO SPEED UP THE CREATION OF LISTING FILES ONE MAY SET THE ; EXTENSION BLOCK COUNT>1 IN FDAT$A. THE LOG FILE IS TRUNCATED AT THIS POINT TO ; SAVE DISK SPACE. COMMENTING OUT THE CODE WILL SPEED UP PROCESSING SOMEWHAT FOR ; SYSTEMS WITH LOTS OF DISK SPACE. ; OPEN$U #LOG ; OPEN FILE FOR UPDATE ;(NEED EXTEND ACCESS FOR TRUNCATE) BCS 140$ ; IF CS, OPEN ERROR CALL .TRNCL ; CLOSE THE FILE AND TRUNCATE IT BCS 140$ ; IF CS, TRUNCATE ERROR MOV #MS1NAM,R0 ; Get address for name MOV #9.,R1 ; Clear it out first ; 130$: CLRB (R0)+ ; Clear out the name area SOB R1,130$ ; MOV #MS1NAM,R0 ; Get the start address back again MOV #LOGNB+N.FNAM,R3 ; Get address of filename MOV (R3)+,R1 ; Convert & insert it CALL $C5TA ; MOV (R3)+,R1 ; CALL $C5TA ; MOV (R3)+,R1 ; CALL $C5TA ; PRINT MSG1 ; PRINT READY MESSAGE CLR TIMOUT ; RESET POSSIBLE TIMEOUT SWITCH QIOW$S #IO.KIL,#VT1LUN,#GENEFN ; KILL ANY PENDING IO JMP LOOP ; DEQUE NEXT REQUEST OR EXIT ; 140$: JMP FILERR ; GO REPORT FILE ERROR .PAGE .SBTTL ATPRC Handle processing via AT. ; ; This routine specifies a command to the virtual terminal driver to ; invoke AT. and then merely sits back, logging the action, waiting ; for @ to occur. ; ATPRC: MOV #FILNM+1,R1 ; See how long the filename is MOVB #40,FILNM+10. ; Make sure we stop in time ; 10$: CMPB (R1)+,#40 ; End of string? BNE 10$ ; If NE no - carry on MOVB #12,FILNM-1 ; Stuff in a (Log File only) MOVB #15,-(R1) ; Yes - stuff in a SUB #FILNM-1,R1 ; Get the length MOV #FILNM,VT1WRT+Q.IOPL ; Set up QIO MOV R1,VT1WRT+Q.IOPL+2 ; INC R1 ; Count for File output PUT$ #LOG,#FILNM-1,R1 ; Stuff it in the log file DIR$ #VT1WRT ; EXECUTE COMMAND ; 20$: DSCP$S ; Disable checkpointing for duration of read DIR$ #VT1RD ; ISSUE FIRST READ FOR OUTPUT FROM AT. ; DON'T ISSUE ANY MARK TIMES. ENCP$S ; Re-enable checkpointing TST VTSTAT+2 ; An IE.EOF? BEQ 20$ ; If EQ yes - error CALL PUTBUF ; 30$: CALL CHKEOF ; CHECK TO SEE IF END OF PROCEDURE COMMAND FILE TSTB EOFFLG ; HAVE WE RECIEVED AN @ FROM ...AT.? BEQ 20$ ; IF EQ, NO, CONTINUE TO ISSUE READS TO VT: ; 50$: ; REF LABEL CALL VTREAD ; Try to read something from VT1 BCS 60$ ; If CS - we timed out, or got IE.EOF CALL PUTBUF ; Output whatever we got BR 50$ ; Else try again ; 60$: RETURN .PAGE .SBTTL CHKEOF Check for @ ;+ ; **-CHKEOF ; ; CHECK TO SEE IF ...AT. HAS OUTPUT AN @ ; IF SO SET EOFFLG ;- CHKEOF: ; REFERENCE LABEL MOV R0,-(SP) ; Save R0 & R1 MOV R1,-(SP) ; MOV R2,-(SP) ; MOV R3,-(SP) ; CMPB LOGBUF+4,#'A ; An error-message from AT? BNE 5$ ; If NE no - carry on CMPB LOGBUF+5,#'T ; Sure? BNE 100$ ; If NE no - carry on CMPB LOGBUF+6,#'. ; Positive BNE 100$ ; If NE no - carry on MOV #ATMSG,R0 ; Get address of table ; 1$: MOV (R0)+,R1 ; Get address of string BEQ 30$ ; If EQ not found - must be real error MOV (R0)+,R2 ; Get length as well BEQ 30$ ; Shouldn't happen - but what the hell MOV #LOGBUF+11.,R3 ; Get address of what really happened ; 2$: CMPB (R1)+,(R3)+ ; Same? BNE 1$ ; If NE no - check next one SOB R2,2$ ; Keep checking BR 100$ ; We found it - carry on ; 5$: MOV #LOGBUF,R0 ; ADDRESS OF BUFFER TO CHECK MOV #8.,R1 ; ONLY CHECK FIRST 8 CHARACTERS ; 10$: CMPB #'@,(R0)+ ; HAVE WE GOT AN '@' ? BEQ 20$ ; YES, CHECK SOME MORE SOB R1,10$ ; LOOP UNTIL R1=0 BR 100$ ; IF NEVER FIND AN '@' GIVE UP ; 20$: CMPB (R0)+,#' ; Next character a space? BNE 100$ ; If NE no - wasn't this one CMPB (R0)+,#'< ; IS IT A '<'? BNE 100$ ; NO, NO GOOD CMPB (R0)+,#'E ; IS IT AN 'E'? BNE 100$ ; NO NO GOOD CMPB #'O,(R0)+ ; IS IT AN 'O' BNE 100$ ; NO, NO GOOD CMPB #'F,(R0)+ ; IS IT AN 'F' BNE 100$ ; NO, NO GOOD CMPB #'>,(R0) ; IS IT AN '>' BNE 100$ ; NO , NO GOOD, BUT CLOSE ; 30$: INCB EOFFLG ; SET EOFFLG ; 100$: MOV (SP)+,R3 ; MOV (SP)+,R2 ; MOV (SP)+,R1 ; Restore R1 & R0 MOV (SP)+,R0 ; RETURN ; .PAGE .SBTTL BATPRC Process file directly in BAT ; ; This routine reads an input file, executes each command via the ; virtual terminal driver and logs everything that happens ; BATPRC: GET$ #INPFDB,#LOGBUF ; Read an input record BCS 90$ ; If error - must be the end MOV #LOGBUF,R0 ; Get address of input MOV INPFDB+F.NRBD,R1 ; Get size of input CLR R4 ; Initialize data flag CMPB (R0),#'! ; Data record? BNE 20$ ; If ne no - carry on INC R4 ; set data record flag CLRB (R0)+ ; And omit ! MOVB #15,LOGBUF(R1) ; Insert a trailing for log file DEC R1 ; And don't count it BISB #TF.WBT,VT1WRT+Q.IOFN ; Set for 'Solicited Write' CMPB (R0),#'^ ; Control character? BNE 30$ ; If NE no - carry on INC R0 ; Yes - skip over it DEC R1 ; Don't count it BICB #140,(R0) ; and convert to control character BR 30$ ; Omit non-data bit ; 20$: MOVB #15,LOGBUF(R1) ; Insert a trailing INC R1 ; And increment it a bit BICB #TF.WBT,VT1WRT+Q.IOFN ; Clear 'Solicited Write' ; 30$: MOV R0,VT1WRT+Q.IOPL ; Stuff parameters in QIO DPB MOV R1,VT1WRT+Q.IOPL+2 ; DIR$ #VT1WRT ; Output it TST R4 ; Data line? BEQ 40$ ; If EQ no - carry on ADD #2,R1 ; Yes - bit more as well CMPB LOGBUF+1,#'^ ; Was it a control character? BNE 40$ ; If NE no - carry on BISB #100,LOGBUF+2 ; Yes - reset it INC R1 ; and count it ; 40$: PUT$ #LOG,#LOGBUF,R1 ; Output the log file record DSCP$S ; Disable checkpointing while waiting for ; write to complete MRKT$S #VTWEFN,#VTTIMO*3,#2 ; SET TIMEOUT TRAP FOR VTTIMO*3 SECS WTSE$S #VTWEFN ; Wait for write (might have been solicited) QIOW$S #IO.KIL,#VT1LUN,#5 ; Kill the write in case it timed out ENCP$S ; Enable checkpoining again ; 50$: CALL VTREAD ; Try to read something from VT1 BCS BATPRC ; If CS - we timed out, or got IE.EOF CALL PUTBUF ; Output whatever we got MOV VTSTAT+2,R1 ; Get length of reply CMPB LOGBUF(R1),#'> ; Last byte a >? BEQ BATPRC ; If EQ yes - get next record BR 50$ ; and get some more ; 90$: BICB #TF.WBT,VT1WRT+Q.IOFN ; Clear 'Solicited Write' MOV #CTRLZ,VT1WRT+Q.IOPL ; Kill any outstanding reads MOV #1,VT1WRT+Q.IOPL+2 ; AND BYTE COUNT CLRB LOGFLG ; Don't echo these replies CALL SBMCMD ; ISSUE KILL COMMAND MOVB #1,LOGFLG ; RETURN .PAGE .SBTTL PUTBUF Format a Buffer and output to the Log File ; ; PUTBUF - Set up and output the buffer ; PUTBUF: MOVB LOGBUF+1,R0 ; Get carriage-control character from VT MOV #VFCTAB,R3 ; Get decode table MOV #LOGBUF,R1 ; Get buffer address MOV #VFCNUM,R2 ; Get number to check ; 10$: CMPB R0,(R3)+ ; This one? BEQ 20$ ; If EQ yes - handle it ADD #3,R3 ; No - set to next one SOB R2,10$ ; If any more check next SUB #3,R3 ; Couldn't find one - assume null ; 20$: MOVB (R3)+,(R1)+ ; Insert the VFC characters MOVB (R3)+,(R1)+ ; ADD VTSTAT+2,R1 ; Set to the end DEC R1 ; MOVB (R3)+,(R1)+ ; Insert trailing VFC character ADD #2,VTSTAT+2 ; Count them all PUT$ #LOG,#LOGBUF,VTSTAT+2 ; LOG THE MCR OUTPUT BCC 30$ ; If CC OK - carry on TST (SP)+ ; Kill return address JMP FILERR ; log the error ; 30$: RETURN .PAGE .SBTTL SBMCMD Issue a line to VT1: and wait for EOF ;+ ; **-SBMCMD ; ; THIS ROUTINE FIRST ISSUES THE PREPARED COMMANDLINE ; TO VT1: (EITHER HELLO OR BYE) AND READS THE ; MCR OUTPUTS AND PUTS IT IN THE LOG FILE if LOGFLG is non-zero. ; ;- SBMCMD: DIR$ #VT1WRT ; ISSUE COMMAND SET UP BICB #TF.WBT,VT1WRT+Q.IOFN ; Clear 'Solicited Write' ; 10$: CALL VTREAD ; Try to read something from VT1 BCS 50$ ; If CS - we timed out, or got IE.EOF TSTB LOGFLG ; Echo replies? BEQ 20$ ; If EQ no - jump over output CMPB LOGBUF+1,#'$ ; Is it a password prompt? BNE 15$ ; If NE no - carry on BISB #TF.WBT,VT1WRT+Q.IOFN ; Set for 'Solicited Write' BR SBMCMD ; And output last line as answer ; 15$: CALL PUTBUF ; Clear out non-printing chars & handle VFC ; 20$: MOV #LOGBUF-2,R0 ; a '>' at the end? ADD VTSTAT+2,R0 ; CMPB (R0),#'> ; BEQ 50$ ; Yes - end of file CMPB LOGBUF+3,#'H ; HELLO Error Message BNE 40$ ; If NE no - carry on CMPB LOGBUF+4,#'E ; Sure? BNE 40$ ; If NE no - carry on INCB HELERR ; SHOW WE HAVE A LOGON ERROR ; 40$: BR 10$ ; And try again ; 50$: RETURN ; ALL DONE .PAGE .SBTTL AST Mark Time AST Routines ;+ ; **-MKAST1 ; ; THIS AST SERVICE ROUTINE IS NECESSARY TO COVER THE PROBLEMS, WHEN ; ISSUING A BYE COMMAND. IF THE SUBMIT REQUEST SPECIFIED AN ; ACCOUNT WHICH DOESN'T EXIST, THE CODE FOR THE BYE COMMAND ; (SBMCM1) CANNOT DETECT THE "MCR -- NOT LOGGED IN" ERROR ; MESSAGE. THIS ( AND SOME OTHER PROBLEMS) ARE MAINLY CAUSED ; BY THE FACT, THAT MCR ISSUES THE PROMPT (>) IN VERY DIFFERENT WAYS. ; THIS IS A BIT INCOSISTENT AND SHOULD BE ADDRESSED TO FUTURE ; RELEASES. ; ;- MKAST1: TST (SP)+ ; REMOVE EVENTFLAG FROM STACK MOV MRKRET,2(SP) ; MODIFY RETURN ADDDRESS QIOW$S #IO.KIL,#VT1LUN,#GENEFN ; KILL THE READ PENDING ON VT1 ASTX$S ; AND LEAVE AST ROUTINE .PAGE .SBTTL ERR Error Routines ;+ ; **-FILERR ; **-ATTERR ; ; SOME SORT OF INTELLIGENT ERROR HANDLING SHOULD ; BE DONE THERE, HOWEVER: ; ENTRY AT FILERR >> PRINT ERROR AND START OVER ; ENTRY AT ATTERR >> PRINT ERROR AND EXIT ( NO VT AVAILABLE) ; ;- ; FILERR: MOVB F.ERR(R0),LOGBUF ; PRESERVE FILE SYSTEM ERROR CLOSE$ #LOG ; CLOSE THE LOG FILE CLOSE$ #INPFDB ; Close the input file, just in case MOV #MS2NAM,R0 ; Where file type goes MOV LOGNB+N.FTYP,R1 ; File type CALL $C5TA ; Convert it MOV #MSG2+31.,R0 ; ADDR OF WHERE ERROR CODE GOES MOVB LOGBUF,R1 ; ERROR CODE CLR R2 ; SUPRESS LEADING ZEROS CALL $CBDSG ; CONVERT BINARY ERROR CODE TO SIGNED DECIMAL PRINT MSG2 ; PRINT THE ERROR MESSAGE JMP LOOP ; START OVER AGAIN ; ATTERR: ; REFERENCE LABEL PRINT MSG3 ; PRINT ERROR MESSAGE EXIT$S ; AND LEAVE PROGRAM .PAGE .SBTTL CKLOG Check to see if VT logged on ;+ ; CHECK LOG BIT TO SEE IF VT LOGGED ON ALRIGHT ; CC - SET IF FAILED ; CC - CLEAR IF SUCCESS ;- ; CKLOG: CLR LOGCNT ; RESET THE LOGON TRIES ; 10$: MRKT$S #VTREFN,#1,#2 ; MARK TIME FOR 1 SECOND GLUN$S #VT0LUN,#LUNINF ; READ LUN INFO FOR VT0: BIT #U2.LOG,LUNINF+6 ; IS VT: LOGGED ON YET BEQ 100$ ; IF EQ, YES, SO EXIT WITH CARRY CLEAR INC LOGCNT ; INCREMENT THE NUMBER OF TIMES TRIED TO LOGON CMP #4,LOGCNT ; ARE WE AT 3 YET BEQ 75$ ; YES, GO SET CARRY AND EXIT BR 10$ ; AND TRY AGAIN 75$: SEC ; SET CARRY 100$: RETURN ; ALL DONE .PAGE .SBTTL VTREAD Read a line from VT1 with timeout ; ; This routine will read a line from VT1:, timing it out if it has ; not completed within VTTIMO seconds ; VTREAD: DSCP$S ; Disable checkpointing during read ; (Else Exec might do 'checkpoint during terminal I/O) MRKT$S #VTREFN,#VTTIMO,#2 ; SET TIMEOUT TRAP FOR VTTIMO SECS DIR$ #VT1RD ; READ line from VT1 TSTB VTSTAT ; Timed out? BNE 20$ ; If NE no - check for End-of-File QIOW$S #IO.KIL,#VT1LUN,#5 ; Yes - kill the read ; 10$: ENCP$S ; Enable checkpointing again SEC ; Set the carry BR 90$ ; and return ; 20$: CMKT$S ; CANCEL MARKTIME CMPB VTSTAT,#IE.EOF ; End of file? BEQ 10$ ; If EQ yes - treat as timeout ENCP$S ; Enable checkpointing again CLC ; No - show success ; 90$: RETURN ; Return .PAGE .SBTTL PNTLIN Output a Line ;+ ; PNTLIN ; ; THIS ROUTINE WILL PRINT AN ASCIZ LINE ;- PNTLIN: MOV #-1,R1 ; GET COUNT INITIALIZED MOV R0,QIODPB+Q.IOPL ; STORE BUFFER ADDRESS 170$: INC R1 ; INCREMENT COUNTER TSTB (R0)+ ; IS THIS THE LAST BYTE? BNE 170$ ; NO. KEEP GOING MOV R1,QIODPB+Q.IOPL+2 ; STORE BYTE COUNT DIR$ #QIODPB RETURN .END START