.TITLE BATSAVE .IDENT /V2.35/ ;***************************************************************************** ; ; BATSAVE.TSK --- BATCH QUEUE SAVE PROGRAM ; ; This task saves the batch queue (that resides in pool) in a disk ; file LB:[1,54]BATQUEUE.BAT. BATSAVE should be activated with the ; command: ; ; BAT /SAVE ; ; BATSAVE will print a warning message if the queue is not in the ; CLOSEDOWN state, since users may submit jobs to the batch queue ; after the save has occurred, and before the batch system is shut ; down. This would result in the loss of these jobs. To restore ; the batch queue from the disk file, the batch queue restore program, ; BATREST.TSK should be run with the command: ; ; RUN LB:[10,25]BATREST ; ;***************************************************************************** .MCALL FDBF$A,FDOF$L, FDRC$A, QUEDF$ .MCALL FSRSZ$,OPEN$W,CLOSE$,DELET$ .MCALL FDBDF$,FDAT$A,FDOP$A,NMBLK$ .MCALL EXIT$S,QIOW$,DIR$,PUT$,GTIM$S .MCALL TCBDF$,UCBDF$ QUEDF$ ; DEFINE QUEUE PACKET OFFSETS ; THIS MACRO IS PART OF THE BATCH SYSTEM. ; ALL OTHER MACROS LISTED IN .MCALL DIRECTIVES ; ABOVE ARE STANDARD RSX11M SYSTEM MACROS. TCBDF$ ; DEFINE TASK CONTROL BLOCK OFFSETS UCBDF$ ; DEFINE UCB OFFSETS FDOF$L ; DEFINE FILE DESCRIPTOR BLOCK OFFSETS .PAGE P$$ARM = 10. ; IF THIS SYMBOL IS DEFINED, BAT WILL ALLOW THE ; CONSTRUCTION OF A PARAMETER LIST FOR THE ; BATCH JOB. THE VALUE OF P$$ARM IS THE MAXIMUM ; ALLOWED LENGTH OF EACH PARAMETER. ; THIS SYMBOL SHOULD BE DEFINED ACCORDINGLY IN THE ; SOURCE CODE FOR BATMAN. NPARM = 4. ;NUMBER OF PARAMETERS--NOT ALWAYS SYMBOLICALLY ;REFERENCED!!! L$$CNT = 0 ; DEFINE IF LINE COUNTS ARE TO BE USED (SEE THE ; COMMENTS IN THE SOURCE FOR BATMAN.TSK) ;S$$AVE = 0 ; FOR FUTURE EXPANSION - DON'T DEFINE THIS SYMBOL ;T$$URN = 0 ; DEFINE THIS SYMBOL TO INCLUDE CODE FOR THE ; TURNROUND (/TU) SWITCH. IT DOESN'T WORK RIGHT ; AT THE MOMENT. MAXDEP = 1 ; MAXIMUM NESTING DEPTH FOR INDIRECT COMMAND FILES MAXJOB = 15. ; NUMBER OF ENTRIES IN LIST BUFFER ; MAXJOB SHOULD BE AT LEAST AS BIG AS THE ; MAXIMUM QUEUE SIZE. IF NOT, QUEUE LISTINGS ; WILL BE INCOMPLETE AND IT WILL NOT BE ; POSSIBLE TO COMPUTE A TURNROUND TIME FOR ; JOBS TOWARDS THE END OF THE QUEUE. PASSIZ = 6 ; SIZE OF PASSWORD FIELD LNKSIZ = 2 ; SIZE OF LINK WORD FIELD IN BYTES MRKSIZ = 2 ; SIZE OF END-BUFFER MARKER COMLUN = 1 ; COMMAND I/O LUN ERRLUN = 2 ; ERROR MESSAGES LUN SFLLUN = 3 ; SAVE FILE LUN SFLEFN = 32. ; EVENT FLAG FOR PUT$ CR = 15 ; CARRIAGE RETURN LF = 12 ; LINEFEED DPT = '. ; PERIOD .PAGE ; THESE ARE DEFINITIONS FOR THE FILE PROTECTION BITS FOR RSX VERSION 3.2 WDEL= 100000 ;WORLD DELETE WEXT= 040000 ;WORLD EXTEND WWRI= 020000 ;WORLD WRITE WREA= 010000 ;WORLD READ GDEL= 004000 ;GROUP DELETE GEXT= 002000 ;GROUP EXTEND GWRI= 001000 ;GROUP WRITE GREA= 000400 ;GROUP READ ODEL= 000200 ;OWNER DELETE OEXT= 000100 ;OWNER EXTEND OWRI= 000040 ;OWNER WRITE OREA= 000020 ;OWNER READ SDEL= 000010 ;SYSTEM DELETE SEXT= 000004 ;SYSTEM EXTEND SWRI= 000002 ;SYSTEM WRITE SREA= 000001 ;SYSTEM READ FSRSZ$ 2. DEFSIZ = -1 ; INITIAL SIZE FOR Q SAVE FILE IN BLOCKS EXTSIZ = -1 ; EXTEND SIZE FOR Q SAVE FILE IN BLOCKS ; (NEGATIVE NUMBERS INDICATE NONCONTIGUOUS) $SVFDB: FDBDF$ ; FDB FOR BATCH QUEUE SAVE FILE FDAT$A R.VAR,,,DEFSIZ,EXTSIZ FDRC$A ; DEFINE RECORD MODE. BUFFERS SPEC'ED LATER FDOP$A SFLLUN, SFLNAM, , FO.WRT FDBF$A SFLEFN, , 1. .EVEN SFLNAM: .WORD DEVLN, DEVNM ; DEVICE NAME .WORD UICLN, UICSP ; UIC .WORD SFLLN, SFLNM ; FILE NAME .NLIST BEX .ENABL LC DEVNM: .ASCII /LB0:/ DEVLN= .-DEVNM UICSP: .ASCII /[1,54]/ UICLN= .-UICSP SFLNM: .ASCII /BATQUEUE.BAT/ SFLLN= .-SFLNM .PAGE ; ; MACROS ; .MACRO PRINT$ MSG,MSGSZ MOV MSG,QIOW+Q.IOPL MOV MSGSZ,QIOW+Q.IOPL+2 DIR$ #QIOW .ENDM .MACRO ERROR$ ERR,ERRA MOVB F.ERR(R0),R1 MOV ERRA,R0 CALL $FCSER SUB ERR,R0 PRINT$ ERR,R0 .ENDM ; ; SWITCH MASK TABLE ; ; *IMPORTANT* DO NOT CHANGE THESE BIT DEFINITIONS WITHOUT ; MAKING A CORRESPONDING CHANGE IN THE SOURCE CODE FOR BATMAN.TSK. ; IN ANY EVENT, THE DEFINITIONS OF 'MRKABO' AND 'MRKEXE' MUST ; NOT BE CHANGED. ; TLMASK = 1 ; /TL (TIME LIMIT) PAMASK = 2 ; /PA (PASSWORD) IMMASK = 4 ; /IM (IMMEDIATE MODE) EVMASK = 10 ; /EV (EXPLICIT VERSION) EXMASK = 20 ; /EX (EXPRESS JOB) TRMASK = 40 ; /TR (TRACE JOB EXECUTION) DEMASK = 100 ; /DE (DELETE COMMAND FILE AT END OF JOB) HFMASK = 200 ; /HF (HOLD FOR SWITCH) HUMASK = 400 ; /HU (HOLD UNTIL SWITCH) LNMASK = 1000 ; /LN (LINE COUNT) RSMASK = 2000 ; /RS (RESTART JOB ON CRASH) KEMASK = 4000 ; /KE (KEEP LOG FILE IN USER DIRECTORY) NOMASK = 10000 ; /NO (DON'T SPOOL LOG FILE PMMASK = 20000 ; /PM (PARAMETER LIST) ; THE REMAINING 2 BITS IN THE MASK WORD ; ARE USED BY BATMAN AND MUST NOT BE USED ; BY BAT FOR SWITCH MASKS. LIMASK = 1 ; /LI (LIST BATCH QUEUE) FUMASK = 2 ; /FU (FULL LISTING) ALMASK = 4 ; /AL (LIST ALL THE QUEUE, NOT JUST MY JOBS) CAMASK = 1 ; /CA (CANCEL JOB) ABMASK = 2 ; /AB (ABORT JOB IF RUNNING) RLMASK = 1 ; /RL (RELEASE JOB FROM HOLD) TUMASK = 1 ; /TU (JOB TURNROUND) SQMASK = 1 ; /SAVE (SAVE QUEUE) RQMASK = 2 ; /RESTORE (RESTORE QUEUE) QSMASK = 4 ; /QUESIZE (QUEUE SIZE) RDMASK = 10 ; /RUNDOWN (PUT QUEUE IN RUNDOWN) RJMASK = 20 ; /RUNJOBS (CLEAR RUNDOWN CONDITION) IDMASK = 40 ; /ID (BATCH VERSION NUMBER) CLMASK = 100 ; /CLOSEDOWN (DON'T ACCEPT NEW JOBS) NXMASK = 200 ; /NEXTJOB (SET NEXT JOB NUMBER) XTMASK = 400 ; /STOP (SET RUNDOWN AND MARK FOR EXIT) MRKABO = 100000 ; FLAG FOR MARK-FOR-ABORT MRKEXE = 40000 ; JOB RUNNING FLAG MSG4: .ASCII /BATSAVE -- Queue is empty/ MSG4SZ=.-MSG4 MSG5: .ASCII /BATSAVE -- Jobs in queue: / MSG5A: .BLKB 6. CLSWA: .ASCII /BATSAVE -- *WARNING* Batch queue not in closedown/ CLSLN= .-CLSWA DONMSG: .ASCII /BATSAVE -- Batch queue save complete/ DONLN= .-DONMSG PUTER: .ASCII /BATSAVE -- BATQUEUE.SAV write error, FCS: / PUTE1: .BLKB 6. PROMSG: .ASCII /BATSAVE -- File protection error, FCS: / PROM1: .BLKB 6. OPNMSG: .ASCII /BATSAVE -- File open error, FCS: / OPNM1: .BLKB 6. CLSMSG: .ASCII /BATSAVE -- File close error, FCS: / CLSM1: .BLKB 6. GTIMER: .ASCII /BATSAVE -- GTIM$ error/ GTIMLN= .-GTIMER .EVEN ;BUFFERS TIMDAT: .BLKW 8. ;DATE/TIME BUFFER TIMDLN= .-TIMDAT SAVBF: .BLKW Q.LGTH ;BLOCK LONG ENOUGH FOR A PACKET SAVLN= Q.LGTH .IF DF P$$ARM PARBF: .BLKB +10. ;BUFFER FOR PARAMETERS .ENDC ;DF P$$ARM ; DIRECTIVE PARAMETER BLOCKS ; QIOW: QIOW$ IO.WVB,ERRLUN,1,,IOSB,,<0,0,40> ATT: QIOW$ IO.ATT,ERRLUN DET: QIOW$ IO.DET,ERRLUN IOSB: .BLKW 2 ; I/O STATUS BLOCK .IF DF M$$MUP SYSMBR = 54 .IFF SYSMBR = 50 .ENDC .LIST BEX,MEB .SBTTL PRELIMINARY QUEUE SAVE PROCESSING ;+ ; ; *** $PLIS ; ; ;- $PLIS: MOV #,R1 ;FILE PROT BITS CALL .WDFFP ; PROTECT THE FILE FROM PRYING EYES OPEN$W #$SVFDB ; OPEN THE FILE BCC 13$ ; NO ERROR ERROR$ #PROMSG, #PROM1 ; PROCESS OPEN ERROR BR CLEX ; CLOSE FILE AND EXIT 13$: GTIM$S #TIMDAT ; GET THE DATE AND TIME BCC 14$ ; SUCCESS PRINT$ #GTIMER, #GTIMLN ; PRINT ERROR BR CLEX ; CLOSE FILE AND EXIT 14$: PUT$ #$SVFDB, #TIMDAT, #TIMDLN ; WRITE OUT THE DATE AND TIME BCC 15$ ; NO ERROR JMP PAKER ; ERROR ON PUT$ 15$: BIT #QQ.CLS,$QSTAT ; IS QUEUE IN CLOSEDOWN? BNE 16$ ; YES PRINT$ #CLSWA,#CLSLN ; NO, WARN USER 16$: CALL $QLOCK ; LOCK BATCH QUEUE LISTS PUT$ #$SVFDB, #$NUMQ, #2. ;OUTPUT NUMBER OF JOBS IN QUEUE BCC 20$ ;WRITE OK JMP PAKER ; ERROR ON THE PUT$ 20$: PUT$ #$SVFDB, #$JOBN, #2. ;OUTPUT NEXTJOB NUMBER BCC 21$ ;WRITE OK JMP PAKER ; ERROR ON PUT$ 21$: MOV $NUMQ,R1 ; GET NUMBER OF JOBS IN QUEUE BNE 25$ ; NE MEANS IT IS NON-ZERO PRINT$ #MSG4,#MSG4SZ ; PRINT QUEUE EMPTY MESSAGE BR PLISR ; AND RETURN 25$: MOV #MSG5A,R0 ; GET BUFFER ADDRESS FOR FORMATTED NUMBER CALL $DECML ; CONVERT TO DECIMAL SUB #MSG5,R0 ; GET MESSAGE LENGTH DIR$ #ATT ; ATTACH THE TERMINAL PRINT$ #MSG5,R0 ; TYPE IT OUT CALL $SAVEM ; SAVE THE QUEUES PLISR: CALL $QUNLK ; UNLOCK QUEUE LISTS CLEX: CLOSE$ #$SVFDB ;CLOSE THE FILE BCC EXT ;EXIT IF NO ERROR ERROR$ #CLSMSG, #CLSM1 EXT: PRINT$ #DONMSG, #DONLN ; PRINT DONE MESSAGE EXIT$S ; AND EXIT .SBTTL ALL QUEUES SAVE $SAVEM: MOV #$CURJ,R0 ; EXECUTING JOBS QUEUE CALL $QSAVE ; SAVE THE QUEUE MOV #$EXPRQ,R0 ; EXPRESS JOBS QUEUE CALL $QSAVE ; SAVE THE QUEUE MOV #$QUEHD,R0 ; NORMAL JOBS QUEUE CALL $QSAVE ; SAVE THE QUEUE MOV #$HOLDQ,R0 ; HELD JOBS QUEUE CALL $QSAVE ; SAVE THE QUEUE RETURN ; FINISHED .SBTTL SINGLE QUEUE SAVE $QSAVE: MOV (R0),R0 ; NEXT PACKET IN QUEUE BEQ QSAVER ; 0 IS END OF QUEUE CALL $ECOPY ; COPY THE PACKET CALL $PSAVE ; SAVE IT (AND ITS PARAMETERS IF ANY) BR $QSAVE ; DO NEXT PACKET QSAVER: RETURN .SBTTL PACKET SAVE PROCESSOR ; ; *** $PSAVE ; ; THIS ROUTINE IS CALLED TO SAVE A JOB PACKET AND ITS PARAMETERS ; IN THE QUEUE SAVE FILE ; ; $PSAVE: MOV R0,-(SP) ;SAVE PACKET ADDRESS PUT$ #$SVFDB, #SAVBF, #SAVLN ;WRITE OUT THE JOB PACKET BCS PAKER ;SERVICE THE ERROR .IF DF P$$ARM MOV #SAVBF,R0 ;SAVED PACKET ADDRESS BIT #PMMASK,Q.MASK(R0) ;JOB HAVE ANY PARAMETERS? BEQ PSAVER ; NO, JUST RETURN CALL $PCOPY ; YES, COPY PARAMETERS TO BUFFER PUT$ #$SVFDB, #PARBF, R1 ;WRITE PARAMETER PACKET TO FILE, R1 ;HAS LENGTH FROM $PCOPY BCS PAKER ;ERROR ON PUT$ .ENDC ; DF P$$ARM PSAVER: MOV (SP)+,R0 ;RESTORE PACKET ADDRESS RETURN ;ERROR ON PUT$, CLOSE FILE AND EXIT PAKER: CALL $QUNLK ;UNLOCK BATCH QUEUE ERROR$ #PUTER, #PUTE1 ;ERROR MESSAGE TO CONSOLE CLOSE$ #$SVFDB ;CLOSE QUEUE SAVE FILE EXIT$S ;EXIT PROGRAM .SBTTL ERROR CODE FORMATTING ROUTINE ;+ ; ; *** $FCSER ; ; THIS ROUTINE FORMATS THE FCS ERROR CODE ; ; INPUTS: ; R0 BUFFER POINTER ; R1 ERROR CODE ;- $FCSER: CLR R2 ; SET NO LEADING ZEROES CALL $CBDSG ; CONVERT TO DECIMAL (SIGNED) MOVB #DPT,(R0)+ ; INSERT DECIMAL POINT RETURN ; .SBTTL PARAMETER COPY ROUTINE ;+ ; *** $PCOPY ; ; THIS ROUTINE SAVES A JOB'S PARAMETER LIST ; WE HAVE TO MAKE A CHECK TO SEE IF THE PARAMETER LIST IS STILL ; THERE, IN CASE THE JOB'S STATUS HAS CHANGED RECENTLY. ; ; INPUTS: ; R0 POINTER TO JOB IN INTERNAL BUFFER FORM ; ; OUTPUTS: ; R1 NUMBER OF BYTES OF PARAMETERS ; ALL OTHER REGISTERS PRESERVED ; ;- .IF DF P$$ARM $PCOPY: CLR R1 ; ZERO PARAMETER COUNT BIT #PMMASK,Q.MASK(R0) ; DID JOB HAVE ANY PARAMETERS? BEQ LPARMR ; NO, JUST RETURN CALL $SWSTK,LPARMR ;; SWITCH STACKS MOV Q.JOBN(R0),R0 ;; GET JOB NUMBER CALL $GETJ1 ;; LOCATE ITS PACKET BCS LPARMR ;; JUST IN CASE BIT #MRKEXE,Q.MASK(R1) ;; IS IT EXECUTING NOW (IT MIGHT BE!) BNE LPARMR ;; YES, NO CAN DO THEN MOV Q.PARM(R1),R2 ;; GET FIRST PARAMETER PACKET ADDRESS BEQ LPARMR ;; IF EQ THERE AREN'T ANY MOV #PARBF,R0 ;; GET BUFFER ADDRESS 10$: MOV R2,R3 ;; COPY PARAMETER PACKET ADDRESS TO R3 ADD #4,R3 ;; POINT TO ACTUAL PARAMETER 15$: MOVB (R3)+,(R0)+ ;; MOVE A BYTE OF THE PARAMETER BNE 15$ ;; IF NE THEN MORE TO MOVE DEC R0 ;; REMOVE NULL BYTE MOV (R2),R2 ;; POINT TO NEXT PARAMETER BEQ 20$ ;; IF EQ THERE ISN'T ONE MOVB #':,(R0)+ ;; INSERT A COLON BR 10$ ;; THEN DO THE NEXT PARAMETER 20$: SUB #PARBF,R0 ;; NUMBER OF CHARACTERS OF PARAMETERS MOV R0,4(SP) ;; SET UP USER R1 LPARMR: RETURN ;; RETURN TO USER LEVEL AND CALLER .ENDC ; DF P$$ARM .SBTTL SINGLE QUEUE ENTRY COPY ROUTINE ;+ ; *** $ECOPY ; ; THIS ROUTINE COPIES A SINGLE QUEUE ENTRY INTO THE ; INTERNAL BUFFER. ; ; INPUT: ; R0 JOB PACKET ADDRESS ; OUTPUT: ; ALL REGISTERS PRESERVED ;- $ECOPY: MOV R0,-(SP) ; SAVE PACKET POINTER MOV R4,-(SP) ;SAVE REGISTER MOV #SAVBF,R4 ;BUFFER FOR COPY MOV (R0)+,(R4)+ ; COPY LINK WORD MOV (R0)+,(R4)+ ; COPY VT: UCB ADDRESS MOV (R0)+,(R4)+ ; COPY JOB NUMBER MOV (R0)+,(R4)+ ; AND LOGON UIC MOV (R0)+,(R4)+ ; AND DIRECTORY UIC MOV (R0)+,(R4)+ ; AND MASK WORD MOV (R0)+,(R4)+ ; AND DEVICE NAME MOV (R0)+,(R4)+ ; AND UNIT NUMBER MOV (R0)+,(R4)+ ; COPY... MOV (R0)+,(R4)+ ; ... FILE.... MOV (R0)+,(R4)+ ; ... NAME MOV (R0)+,(R4)+ ; AND FILE TYPE MOV (R0)+,(R4)+ ; AND VERSION NUMBER MOV (R0)+,(R4)+ ;COPY... MOV (R0)+,(R4)+ ;...THE... MOV (R0)+,(R4)+ ;.........PASSWORD MOV (R0)+,(R4)+ ; COPY JOB TIME MOV (R0)+,(R4)+ ; MOV (R0)+,(R4)+ ; AND HOLD TIME MOV (R0)+,(R4)+ ; MOV (R0)+,(R4)+ ; COPY PARAMETER LIST POINTER MOV (R0)+,(R4)+ ; MOV (R0)+,(R4)+ ; LINES OUTPUT SO FAR MOV (R0)+,(R4)+ ; AND LINE LIMIT MOV (SP)+,R4 ;RESTORE THE REGISTER MOV (SP)+,R0 ; RESTORE PACKET POINTER RETURN ; AND RETURN .SBTTL GET JOB NUMBER ROUTINE ;+ ; *** $GETJ1 ; ; THIS ROUTINE LOCATES THE JOB PACKET THAT MATCHES THE ; SPECIFIED JOB NUMBER, IT DOES NOT SCAN THE EXECUTING JOBS QUEUE ; ; INPUT: ; R0 JOB NUMBER TO LOOK FOR ; OUTPUT: ; CARRY SET JOB NOT IN QUEUE ; CARRY CLEAR JOB FOUND ; R1 JOB PACKET ADDRESS ; R2 PACKET ADDRESS OF PREVIOUS JOB ; ;- $GETJ1: MOV #$QUEHD,R1 ; TRY NORMAL JOB QUEUE CALL $QSRCH ; SEARCH THE QUEUE BCC GETJR ; OK, WE GOT IT MOV #$HOLDQ,R1 ; IT MIGHT BE ON HOLD.. CALL $QSRCH ; IS IT? BCC GETJR ; YES MOV #$EXPRQ,R1 ; NO, TRY THE EXPRESS QUEUE CALL $QSRCH ; HOPE THE USER ISN'T WAITING FOR THIS GETJR: RETURN ; .SBTTL QUEUE SEARCH ROUTINE ;+ ; *** $QSRCH ; ; THIS ROUTINE SEARCHES A SPECIFIED JOB QUEUE FOR A PACKET ; THAT MATCHES THE SPECIFIED JOB NUMBER. ; ; INPUT: ; R0 JOB NUMBER TO SEARCH FOR ; R1 LISTHEAD ADDRESS OF JOB QUEUE ; ; OUTPUT: ; CARRY SET JOB NOT IN QUEUE ; CARRY CLEAR JOB FOUND OK ; R1 ENTRY ADDRESS ; R2 PREVIOUS ENTRY ADDRESS ; R5 LISTHEAD ADDRESS ; ;- $QSRCH: MOV R1,R2 ; COPY LISTHEAD ADDRESS MOV R1,R5 ; ALSO TO R5 (NEEDED BY $CANJ) 5$: MOV (R2),R1 ; GET ADDRESS OF NEXT ENTRY BEQ 20$ ; IF EQ, END OF LIST CMP R0,Q.JOBN(R1) ; IS THIS THE RIGHT JOB? BEQ 10$ ; YES MOV R1,R2 ; NO, POINT TO NEXT ENTRY BR 5$ ; AND TRY IT 10$: CLC ; SET SUCCESSS BR QSRCHR ; AND RETURN 20$: SEC ; SET FAILURE QSRCHR: RETURN ; AND RETURN .END $PLIS