1 EXTEND 1000 & ! BAT VER 6B EDIT 00 22-JUN-77 JIM CONDICT & ! MIDDLEBURY COLLEGE, MIDDLEBURY, VT. & ! & ! THIS PROGRAM IS A BATCH PROCESSING PROGRAM THAT DETACHES & ! FROM THE USER'S TERMINAL, LOGS THE USER BACK IN, AND & ! PROCESSES A CONTROL FILE. FOR DOCUMENTATION, SEE THE & ! USER'S GUIDE TO BAT AND INSTALLATION NOTES. & ! & ! AN ATTEMPT HAS BEEN MADE TO WRITE THE CODE IN THIS PROGRAM & ! TO REQUIRE A MINIMUM OF TRANSLATION TO BASIC-PLUS-II. & ! & ! & ! S T A R T O F P R O G R A M & ! & ! & DIM COM$(12%),P%(30%) !COMMANDS, SYS CALLS & \ ON ERROR GOTO 19000 !STANDARD ERROR TRAP. & \ CH3$=CHR$(3%) & \ CH6$=CHR$(6%) !DEFINE USEFUL "CONSTANTS". & \ LF$=CHR$(10%) & \ CR$=CHR$(13%) & \ CH255$=CHR$(255%) & \ NULL$=CHR$(0%) & \ CRLF$=CR$+LF$ & \ LFCR0$=LF$+CR$+NULL$ & \ LIM=1800. !DEFAULT RUN TIME LIMIT. & \ R%=4% !PK STATUS CHECK RECORD NO. & \ S%=600% !NORMAL SLEEP INTERVAL. & \ A$=SYS(CH6$+CHR$(9%)) & \ JOB%=ASCII(A$) & \ KB%=(CVT$%(A$) AND 255%)/2% & \ SYSID$=MID(A$,3%,INSTR(3%,A$,NULL$)-3%) & \ A$=SYS(CH6$+CHR$(-21%)+CH255$) !TEMP. DROP PRIV. & & & ! **** OPEN THE PSEUDO KEYBOARD **** & & \ I%=0% 1100 OPEN "PK"+NUM1$(I%)+":" AS FILE 3% !OPEN THE PK. & \ IF CCL% THEN 1400 !TRY TO OPEN CTRL FILE. & & & & ! **** OPEN CTRL+LOG FILES **** & 1200 PRINT "BAT - ";SYSID$ !IDENTIFY PROGRAM. 1300 PRINT "*"; !PROMPT FOR CTRL FILE. & \ OPEN "KB:" AS FILE 4% !OPEN KB: FOR PROMPT. & \ INPUT LINE #4%, B$ !GET FILENAME [/SWITCH] & 1400 B$=CVT$$(B$,255%) !CLEAN IT UP. & \ I%=INSTR(1%,B$+"/","/") !FIND SWITCHES. & \ J%=INSTR(1%,"x/Mx/Lx/M/L/M",RIGHT(B$,I%)) !DECODE. & \ IF J%=0% OR (LEN(B$)-I% AND 1%)=0% THEN !BAD SWITCH(ES).& PRINT "BAD SWITCH FIELD - ";RIGHT(B$,I%) & \ IF CCL% THEN 32767 ELSE 1300 !EXIT IF CCL ENTRY. & !OTHERWISE RE-PROMPT. & 1500 MES%=(J% AND 10%) !END WITH MESSAGE. & \ LOW%=(J% AND 12%) !LOWER PRIORITY. & \ B$=LEFT(B$,I%-1%) !FILENAME. & \ CHANGE SYS(CH6$+CHR$(-10%)+B$) TO P% !FILENAME STRING SCAN. & \ JOBNAM$=CVT$$(RAD$(P%(7%)+SWAP%(P%(8%))) & +RAD$(P%(9%)+SWAP%(P%(10%))),2%) !JOBNAME. & \ I%=P%(28%) !FLAG BYTE. & \ B$=B$+".BAT" IF (I% AND 2%)=0% !DEFAULT EXTENSION. & \ JOBNAM$="BATJOB" IF (I% AND 1%)=0% !DEFAULT JOB NAME. & \ B$="BATJOB.BAT" IF (I% AND 1%)=0% !DEFAULT CONTROL FILE. & \ OPEN B$ FOR INPUT AS FILE 1% !OPEN CTRL FILE & \ OPEN JOBNAM$+".LOG" FOR OUTPUT AS FILE 2% !OPEN LOG FILE. & & & 2000 ! **** LOOK UP MORE USEFUL INFO **** & & A$=SYS(CH6$+CHR$(-21%)+NULL$) !REGAIN PRIV. & \ CHANGE SYS(CH6$+CHR$(-3%)) TO P% !MON TBL PART I. & \ DEVPTR%=P%(7%)+SWAP%(P%(8%)) & \ JOBTBL%=P%(11%)+SWAP%(P%(12%)) & \ PKKB2%=PEEK(PEEK(PEEK(PEEK(JOBTBL%+JOB%))+6%)+8%) AND 255% & \ DEF FNJ2%=PEEK(PEEK(DEVTBL%+PKKB2%)+2%) AND 255% & !JOB*2 CURRENTLY ON PSEUDO KEYBOARD. & \ CHANGE SYS(CH6$+CHR$(-12%)) TO P% !MON TBL PART II. & \ DEVTBL%=PEEK(DEVPTR%+P%(9%)+SWAP%(P%(10%))) & \ KBDDB%=PEEK(DEVTBL%+KB%*2%) & \ CHANGE SYS(CH6$+CHR$(14%)) TO P% !ACCOUNT. DATA. & \ PROJ%=P%(8%) & \ PN%=P%(7%) & \ PPN%=SWAP%(PROJ%)+PN% & \ PPN$="["+NUM1$(PROJ%)+","+NUM1$(PN%)+"]" & \ BATID$="BAT Job"+NUM$(JOB%/2%)+"- "+JOBNAM$ & \ LOGIN$="HELLO"+NUM1$(PROJ%)+"/"+NUM1$(PN%)+";" & +RAD$(P%(9%)+SWAP%(P%(10%))) & +RAD$(P%(11%)+SWAP%(P%(12%)))+CR$ & !FOR LOGGING IN: HELLOnn/nn;Password+ & & & ! **** DETACH AND LOG USER BACK IN **** & & \ PRINT BATID$;" Detaching ...";CRLF$;"Please wait ..." & \ A$=SYS(CH3$) !DISABLE ECHO. & \ A$=SYS(CHR$(11%)) !CANCEL TYPE AHEAD. & \ A$=SYS(CH6$+CHR$(7%)+CHR$(128%)) !DETACH & \ A$=SYS(CH6$+CHR$(-4%)+CHR$(KB%) !FORCE TO TERMINAL. & +CHR$(21%)+LOGIN$) !^U + LOGIN$ & \ A$=SYS(CH6$+CHR$(-7%)) !SET ^C TRAP. & \ A$=SYS(CH6$+CHR$(12%)) !DEASSIGN ALL DEV. & & & & ! **** LOG IN PK **** & & \ A$=CHR$(21%) !^U TO CLEAR BUFFER. & +"SET FORM;WIDTH 132;LC INPUT"+CR$ !SET PK CHARS. & +LOGIN$ !LOGIN USER ON PK. & \ GOSUB 10000 !GO DO IT. & \ L%=-1% !LOG REPORTING ON. & \ PRINT #2%, SYSID$;" ";PPN$;" Job";FNJ2%/2%; & "- ";JOBNAM$;" KB";NUM1$(PKKB2%/2%);" "; & DATE$(0%);" ";TIME$(0%);LF$ & \ GOSUB 7000 IF LOW% !LOWER PRIORITY. & & & & ! **** READ IN COMMANDS **** & & \ READ COM$(I%) FOR I%=0% TO 12% & \ DATA "!","$","&",":","^",LIMIT,NOLIMIT, & LOG,NOLOG,KILLLOG,PAGE,STOP,LOW & & & 4000 ! **** MAIN PROCESSING LOOP **** & & INPUT LINE #1%, A$ !GET CONTROL FILE LINE. & \ B$=CVT$$(A$,255%) !CLEAN FOR SYNTAX ANALYSIS. & \ IF LEFT(B$,1%)="$" THEN GOSUB 5000 !DECODE COMMAND. & ELSE GOSUB 10000 !NORMAL LINE TO PK. & 4010 GOTO 4000 !CONTINUE UNTIL END-OF-FILE. & & & 5000 ! **** BRANCH ON COMMAND **** & & I%=12% !# OF COMMANDS. & \ I%=I%-1% UNTIL INSTR(2%,B$,COM$(I%))=2% !FIND THE MATCH.& \ A$=B$ IF I%>3% !WANT CLEANED-UP STRING.& \ A$=RIGHT(A$,INSTR(1%,A$,RIGHT(COM$(I%),LEN(COM$(I%))))+1%) & IF I%<6% !STRIP COMMAND OF BEGINNING OF LINE. & !BUT "$$" WILL REDUCE TO "$". & \ ON I%+1% GOSUB 6000,10000,6100,15000,6200,6300,6400, & 6500,6600,6700,6800,6900,7000 !GOSUB THE COMMAND. & \ RETURN & 6000 ! **** $Exclamation point COMMAND **** & & RETURN & !CONTROL FILE COMMENT - IGNORE IT. & !ALSO USED AS A GENERAL RETURN. & & & 6100 ! **** $& COMMAND **** & & PRINT #2%, A$; & \ RETURN & ! PRINT LINE IN LOG FILE. & & & 6200 ! **** $^ COMMAND **** & & A$=CHR$( ASCII(A$) AND -65% ) & \ GOSUB 10000 & \ RETURN & ! TAKE FIRST CHARACTER OF STRING AND UNSET & ! BIT 64 IF PRESENT TO MAKE IT A CTRL CHARACTER.& ! THIS CTRL CHARACTER WILL GO TO THE PK. & & & 6300 ! **** $LIMIT COMMAND **** & & A$=RIGHT(A$,2%) IF INSTR(1%,"=-:",LEFT(A$,1%)) & \ LIM=60.*VAL(A$) & \ LIM=1800. IF LIM<=0. & \ S%=600% & \ S%=LIM IF LIM<600% & \ S%=1% IF S%=0% & \ RETURN & ! SET LIMIT TO NUMBER FOUND AFTER $LIMIT. & ! DELIMITERS MAY BE "=","-",":", OR NOTHING. & ! DEFAULT IS 30 MINUTES; DON'T ALLOW 0. & ! DON'T SLEEP FOR LONGER THAN THE LIMIT. & & & 6400 ! **** $NO LIMIT COMMAND **** & & NOLIM% = -1% & \ RETURN & ! FLAG NO LIMIT. & & & 6500 ! **** $LOG COMMAND **** & & L%=-1% & \ RETURN & ! FLAG NORMAL LOG REPORTING ON. & & & 6600 ! **** $NO LOG COMMAND **** & & L%=0% & \ RETURN & ! FLAG NORMAL LOG REPORTING OFF. & & & 6700 ! **** $KILL LOG COMMAND **** & & KILOG%=-1% & \ RETURN & ! FLAG TO KILL LOG ON NORMAL TERMINATION. & & & 6800 ! **** $PAGE COMMAND **** & & PRINT #2%, CHR$(12%)+CR$; & \ RETURN & ! PRINT TO LOG FILE FOR NEW PAGE. & & & 6900 ! **** $STOP COMMAND **** & & R%=6% !WAIT MUST BE EDITOR WAIT. & \ J%=S% !REMEMBER NORMAL SLEEP TIME. & \ ON ERROR GOTO 10190 !SUBROUTINE ERROR TRAP. & \ S%=-1% !FLAG STATUS CHECK ONLY. & \ GOSUB 10130 !DO A STATUS CHECK. & \ GOTO 6920 UNLESS ERR=28% OR ERR=3% !NO PROGRAM TO STOP. & \ S%=1% !WANT SHORT SLEEP INTERVAL. & \ A$=CHR$(26%) \ GOSUB 6910 UNLESS E% !FORCE CTRL/Z. & \ GOTO 6920 IF T=120. & \ A$=SYS(CH6$+CHR$(-13%)+CHR$(J%/2%)+CH255$ & +CHR$(I%)+STRING$(4%,0%)) !SET THE NEW LEVEL. & \ RETURN & & & 8000 ! **** ^C TRAP ROUTINE **** & & OPEN "KB:" AS FILE 4%, MODE 1% !PREVENT FURTHER ^C'S. & \ PRINT #2%, CRLF$;"??? ";BATID$;" Halted with ^C." & \ TRAP%,E%=-1% !FLAG TRAP. & \ L=0 !FLAG TIME'S UP. & 9000 ! **** FINISH UP **** & & ON ERROR GOTO 19000 !RESET ERROR TRAP. & \ GOSUB 6900 !$STOP COMMAND. & \ J%=FNJ2% !CURRENT PK JOB NUMBER. & \ IF J%>0% THEN !MAKE SURE IT'S REAL. & JDB2%=PEEK(PEEK(JOBTBL%+J%)+8%) & \T=PEEK(JDB2%+2%) !LOW ORDER OF RUN TIME. & \T=T+65536. IF T<0. !WANT IT UNSIGNED. & \T=T+65536.*(SWAP%(PEEK(JDB2%+10%)) AND 255%) !RUN TIME. & \I%=T/36000. \T=T-36000.*I% !HOURS. & \K%=T/600 \T=T-600%*K% !MINUTES. & \T=.1*INT(T) !SECONDS. & \PRINT #2%, CRLF$;"Job";J%/2%;;"terminated ";DATE$(0%); & " at ";TIME$(0%);". Run time was "; & NUM1$(I%);":";RIGHT(NUM1$(100%+K%),2%);":"; & RIGHT(NUM1$(100.+T),2%);LF$ & \A$=SYS(CH6$+CHR$(8%)+CHR$(J%/2%)+STRING$(24%,0%) & +CH255$) !KILL THE PK JOB. & \KILL "TEMP"+RIGHT(NUM1$(100%+J%/2%),2%)+".TMP" & !KILL THE JOB'S TEMP FILE. & 9010 IF MES% THEN !IF WE ARE TO SEND A MESSAGE. & A$="Job terminating" & \ A$=A$+" abnormally" IF E% !TELL USER ABOUT ERROR. & \ A$=A$+"."+CRLF$ !FINISH UP MESSAGE. & \ GOSUB 15000 !AND SEND IT. & 9020 CLOSE 2% & \ KILL JOBNAM$+".LOG" IF KILOG% AND NOT E% & \ KILL "TEMP"+RIGHT(NUM1$(100%+JOB%/2%),2%)+".TMP" UNLESS TRAP% & !KILL YOUR OWN TEMP FILE. & 9030 A$=SYS(CH6$+CHR$(5%)) UNLESS TRAP% !LOGOUT UNLESS ^C TRAP. & \ GOTO 32767 & & & 10000 ! & ! S U B R O U T I N E S & ! & ! & ! **** PUT TO PK AND COLLECT OUTPUT **** & & L=TIME(0%)+LIM !LIMIT TIME. & 10100 ON ERROR GOTO 10190 !SUBROUTINE ERROR TRAP. & \ K%=LEN(A$) & \ K%=K%-1% IF RIGHT(A$,K%-1%)=CRLF$ !STRIP OFF EXCESS LF. & \ K%=K%-2% IF RIGHT(A$,K%-2%)=LFCR0$ !EXCESS CR-NULL. & \ FIELD #3%, K% AS B$ !SET UP BUFFER. & \ LSET B$=A$ !MOVE STRING TO BUFFER. & \ PUT #3%, RECORD 9%, COUNT K% !PUT STRING TO PK. & 10110 GET #3% !GET FROM PK. & \ IF L% THEN !IF LOG REPORTING ON. & FIELD #3%, RECOUNT AS B$ & \ PRINT #2%, B$; !REPORT IN LOG. & 10120 GOTO 10110 IF NOLIM% AND R%=4% !NO LIMIT CHECK. & \ T1=T !LAST TIME. & \ T=TIME(0%) !NEW TIME. & \ L=L-86400. IF T0% AND TRAP%=0% !CTRL/C FROM TERMINAL. & THEN RESUME 8000 ELSE !HANDLE IMMEDIATELY. & IF ERR=11% THEN RESUME 10130 ELSE !EOF ON PK. & IF ERR=5% THEN RESUME 10140 ELSE !NO USER ON PK. & IF ERR=3% THEN RESUME 10195 ELSE !JOB BUSY ON PK. & IF ERR<>28% THEN 19040 ELSE !UNEXPECTED ERROR. & !$STOP COMMAND CAUSED ONLY PROGRAM WAIT STATE. & L=T !FLAG IT DIDN'T WORK. & \ RESUME 10140 !RETURN TO $STOP COMM. & 10195 IF S%<0% THEN 10140 ELSE !$STOP COM. STAT. CHECK.& SLEEP S% !WAIT FOR PK INPUT WAIT.& \ GOTO 10110 !AND TRY AGAIN. & & & 15000 ! **** BROADCAST TO TERMINAL **** & & ! BROADCAST WILL SUCCEED IF USER WHO STARTED THE BAT JOB IS & ! STILL ON THE TERMINAL OR HE WAS PRIVILEGED OR IT WAS KB0: & & A$=SYS(CH6$+CHR$(-5%)+CHR$(KB%)+CRLF$ & +BATID$+" Message:"+CRLF$+A$) & IF PROJ%=1% OR KB%=0% OR PPN%=PEEK(PEEK(PEEK((PEEK & (KBDDB%+2%) AND 255%)+JOBTBL%)+8%)+24%) & \ RETURN & & & 19000 ! & ! E R R O R T R A P R O U T I N E & ! & ! & IF ERR=28% THEN RESUME 8000 ELSE !CTRL/C TRAP ROUTINE. & IF ERL=4000% THEN RESUME 9000 ELSE !END OF CONTROL FILE. & IF ERL=9000% THEN RESUME 9010 ELSE !TEMPnn.TMP NOT FOUND. & IF ERL=9020% THEN RESUME 9030 ELSE !TEMPnn.TMP NOT FOUND. & IF ERR=8% THEN I%=I%+1% !PK NOT AVAILABLE. & \ RESUME 1100 !TRY NEXT PK. & 19010 IF ERL=15000% THEN RESUME 6000 ELSE !BROADCAST FAILED. & IF ERL=1500% THEN 19050 ELSE !USER FILESPEC. ERROR. & IF ERL=1300% THEN 32767 ELSE !USER ^Z TO PROMPT. & IF ERR=6% THEN !NO PK'S AVAILABLE. & PRINT "No pseudo keyboards available for BAT run." & \ RESUME 32767 !EXIT. & 19020 IF ERL=6300% THEN !ILLEGAL LIMIT. & PRINT #2%, CRLF$;"??? Invalid $LIMIT command number - ";& A$;CRLF$;"Limit set to 30 minutes." & \ LIM=1800 !SET THE LIMIT. & \ S%=600% !AND STANDARD SLEEP TIME& \ RESUME 6000 !GO TO A "RETURN". & 19030 IF ERR=55% THEN !UNRECOGNIZED COMMAND. & PRINT #2%, CRLF$;"??? Unrecognized command - ";A$ & \ RESUME 6000 !GO TO A "RETURN". & & 19040 ! **** UNEXPECTED ERROR (FATAL) **** & & PRINT #2%, CRLF$;"??? BAT FATAL ERROR - ";FNE$;CRLF$; & "ERR";NUM$(ERR);"at line";NUM$(ERL);CRLF$ & \ IF F% THEN RESUME 9030 ELSE !SECOND FATAL ERROR. & E%,F%=-1% !FLAG IT. & \ RESUME 9000 !CLOSE UP SHOP. & & 19050 ! **** TROUBLE OPENING FILES **** & & IF CCL% AND K% THEN !NO ARGUEMENT GIVEN ON CCL. & CCL%=0% !TREAT AS RUN ENTRY NOW. & \ RESUME 1200 !GO PRINT HEADER AND PROMPT. & 19060 PRINT FNE$;" - ";B$ !REPORT THE ERROR. & \ IF CCL% THEN RESUME 32767 ELSE !EXIT IF CCL. & RESUME 1300 !OTHERWISE, REPROMPT. & 19070 DEF FNE$=RIGHT(SYS(CH6$+CHR$(9%)+CHR$(ERR)),3%) !ERROR MESSAGE. & & & 30000 ! & ! C C L E N T R Y & ! & ! & ! CCL ENTRY IS "BAT [] [/M] [/L]" & ! DEFAULT FILENAME IS "SY:BATJOB.BAT" IF NOT PRESENT. & ! DEFAULT EXTENSION IS ".BAT" IF NOT SPECIFIED. & & B$=RIGHT(SYS(CHR$(7%)),6%) !STRIP OFF "BATCH". & \ CCL%=-1% !FLAG CCL ENTRY. & \ K%= (B$="") !FLAG NO ARGS GIVEN. & \ GOTO 1000 !START PROGRAM. & & & 32767 A$=SYS(CHR$(9%)) !EXIT TO USER'S RTS. & \ END !T H E E N D . &