1! LAWRENCE UNIVERSITY COMPUTER CENTER APPLETON, WISCONSIN 54911 PROGRAM NAME, VERSION AND TITLE: TIMOUT, VERSION 1A, 10-JUN-74 PROGRAM AUTHORSHIP: 2! TIMOUT, ONE OF THE PROGRAMS IN THE TIMER PACKAGE, WAS DESIGNED AND WRITTEN BY PAUL KONING OF THE LAWRENCE UNIVERSITY COMPUTER CENTER. PURPOSE OF PROGRAM: 3! TIMOUT IS A PROGRAM TO CONVERT THE CONTENTS OF A TIMER OUTPUT FILE INTO A FORM THAT IS READBLE TO HUMAN BEINGS. IT ALSO COMPRESSES AND SUMMARIZES THE DATA, AND DERIVES FROM IT SYSTEM UPTIME AND DOWNTIME, NUMBER OF CRASHES AND THE LIKE. 4! LANGUAGE AND OPERATING SYSTEM: TIMOUT IS WRITTEN IN BASIC-PLUS FOR OPERATION UNDER RSTS V4A-12 ON A PDP11/20 OR PDP11/35 WITH 28K OF CORE. IT REQUIRES A USER AREA OF AT LEAST 7K, BUT MAY NOT RUN IN 7K UNLESS COMMENTS 5! ARE DELETED. IT MAY BE CHANGED TO OPERATE UNDER RSTS/E BY CHANGING LINE 680 TO PEEK IN THE RIGHT LOCATION TO FIND THE DATE. APART FROM THIS, AND THE USE OF THE 'ENABLE OUTPUT' 6! SYS FUNCTION CALL [SYS(CHR$(0%))] NO FUNCTIONS PECULIAR TO RSTS V4A-12 ARE USED. 10! AVAILABILITY: TIMOUT IS A NON-PROPRIETARY PROGRAM PRODUCT OF LAWRENCE UNIVERSITY. IT IS DISTRIBUTED AT COST FOR EDUCATIONAL USE, ON THE CONDITION THAT IT NOT BE SOLD, RENTED OR LEASED FOR PROFIT. LIMITATIONS: 11! CURRENTLY, THE PERIOD FOR WHICH THE OUTPUT HAS TO BE PRODUCED CAN ONLY BE SPECIFIED IN TERMS OF DAYS, AND STARTS AND ENDS AT MIDNIGHT. THIS RESTRICTION MAY BE REMOVED IN A FUTURE VERSION. 12! AS OF NOW, TIMOUT WILL NOTT RUN UNDER RSTS/E, BUT MODIFICATIONS TO MAKE THAT POSSIBLE SHOULD BE MINOR. A RSTS/E VERSION OF THE WHOLE TIMER PACKAGE (TIMER,TIMOUT AND CREATE) SHOULD BE READY BY 1-OCT-74. FURTHER DOCUMENTATION: 13! FOR MORE INFORMATION PLEASE REFER TO THE TIMER DOCUMENTATION, RUN INSTRUCTIONS AND USER'S GUIDE, MSPD # PDP11/74/010, OR TO THE AUTHOR OF THE TIMER PACKAGE AT THE ADDRESS MENTIONED ABOVE. 20! DISCLAIMER: NEITHER THE AUTHOR OF THIS PROGRAM NOR LAWRENCE UNIVERSITY ASSUME ANY LIABILITY, EXPRESSED OR IMPLIED, WITH RESPECT TO THE CORRECTNESS OR PERFORMANCE OF THIS PROGRAM. 100 DIM T7%(24%),C7%(24%),T8(24%),O1%(4%,2%),O7%(2%),O8%(2%),O9%(2%), T$(4%):MAT T7%=ZER:MAT C7%=ZER:MAT T8=ZER:MAT O1%=ZER: MAT O7%=ZER:MAT O8%=ZER:MAT O9%=ZER:D7%=-1%:DIM Q%(12%):MATREAD Q% 101! THIS SETS UP SOME OF THE ARRAYS USED FOR HOURLY STATISTICS, UPTIME AND DOWNTIME, AND TOTAL COUNTS. 115 DIM O2%(4%),M8%(24%),M9%(24%),M8(24%),M9(24%):MAT M9%=ZER:MAT M9=ZER: FOR S9%=1% TO 24%:M8%(S9%)=32767%:M8(S9%)=1E10:NEXT S9%: DIM L%(16%):O3%,O4%,L9%=0%:MAT L%=ZER: DATA 31,28,31,30,31,30,31,31,30,31,30,31 116! THIS SETS UP SOME MORE ARRAYS, FOR MINIMA AND MAXIMA AND LOGIN COUNT. 140 GOSUB 670:%,CHR$(12%);CHR$(13%);: DIM K%(16%):MATREAD K%:DIM C%(16%):MAT C%=ZER:DIM K2%(16%): K2%(16%)=K%(16%):K2%(I%)=K2%(I%+1%)+K%(I%) FOR I%=15% TO 1% STEP -1% 141! THIS SETS UP THE ARRAYS USED FOR DATE DECODING. 200 MATREAD T$:DATA 1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192, 16384,-32768,"CRASH COUNT","SHUTDOWN COUNT","'TIMER' ERROR COUNT", "^C COUNT" 201! THE TEXT ARRAY IS USED IN PRINTING OUT TOTAL COUNTS. 210 OPEN F$ FOR INPUT AS FILE 1%:DIM #1%,X%(5%),D%(4%,2000%): %,TAB(9%);"DUMP OF TIMER OUTPUT FILE -- ";DATE$(0%);" "; TIME$(0%):%,TAB(16%);"FILE CREATED ";DATE$(D%(1%,0%));" "; TIME$(D%(0%,0%)) 211! OPEN THE DATA FILE AND PRINT THE HEADER INFORMATION. 220 %,TAB(13%);"SPECIFIED PERIOD ";DATE$(Q1%);" TO ";DATE$(Q2%) IF S$>="Y":%:%," DATE TIME";TAB(14%);"# JOBS";TAB(22%); "TRANSFER";TAB(33%);" KB NUMBERS 1 1 1 1 1 1" 221! THE TABLE HEADER FOR THE FIRST TABLE. 240 %,TAB(13%);"DET NORM";TAB(24%);"TIME";TAB(33%); "0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5":%:Z%=X%(3%):GOSUB 880 260 D1%=D%(0%,J%):D2%=D%(1%,J%):D3%=D%(2%,J%):D4%=D%(3%,J%):D,D8%=D%(4%,J%): GOTO 490 UNLESS D4%:GOTO 750 261! PUT THE DATA FROM THE VIRTUAL CORE ARRAY INTO SOME IN-CORE VARIABLES FOR FASTER ACCESS (SINCE THEY ARE NOT AT ALL CLOSE TOGETHER IN THE ARRAY). THEN SEE IF THIS ENTRY IS WITHIN THE RANGE OF THE SPECIFIED DATES. 295 IF D3%<961% AND D3%>240% THEN S9%=1% ELSE S9%=2% 296! IF THE ENTRY IS IN RANGE, SEE IF IT IS DAY OR NIGHT (S9%=1 FOR DAY, S9%=2 FOR NIGHT) 300 IF (D1% AND D2%)<>-1% THEN 320 ELSE %,"********* ";:%,"CRASH"; IF D8%=-1%:%,"SHUTDOWN";UNLESS D8%:%, "'TIMER' ERROR";IF D8%=1%:%,"^C";IF D8%=2%: %," OCCURRED HERE ON ";DATE$(D4%);" AT "TIME$(D3%);" *********" 301! FOR THE SPECIAL CASE OF A CRASH-ENTRY OR WHATEVER, PRINT OUT THE APPROPRIATE MESSAGE. 310 O1%(D8%+2%,S9%)=O1%(D8%+2%,S9%)+1%:D7%=0%:D3%=1440%-D3%: O7%(S9%)=O7%(S9%)+FNF%:GOTO 480 311! INCREMENT THE APPROPRIATE COUNT, SET SOME FLAGS AND MAKE SURE THAT THE UPTIME IS KEPT IN A CORRECT MANNER. 320 D3%=1440%-D3%:C7%=D3%/60%:H1%=-1%:IF H%=0% THEN IF D7% AND D%(0%,J%+1%)<>-1% THEN H1%=0%:GOTO 420 321! CHANGE THE TIME ENTRY TO MINUTES SINCE MIDNIGHT, FIND OUT THE HOUR AND SET THE NO-PRINT FLAG UNLESS THE LAST OR NEXT ENTRY IS ONE OF THE SPECIALS OR WE WANT A FULL PRINTOUT. 340 D5%=ASCII(CHR$(D2%)):T9%=D3%-60%*C7%: T1$=NUM$(C7%):T2$=NUM$(T9%+100%): %,FND$(D4%);:%," ";IF LEN(T1$)<4%: %,LEFT(T1$,LEN(T1$)-1%);":";: %,RIGHT(T2$,3%);:D9%=D5%/32% 341! PRINT OUT DATE, TIME AND JOBS (DETACHED AND NORMAL). 350 %,TAB(12%);D9%;TAB(17%);D5%-32%*D9%;TAB(22%);:% USING "###.###", D/60;:%,TAB(33%); 351! PRINT OUT THE I/O TIME 420 T7%=0%:L%(K%)=L%(K%)+1% IF K%(K%) AND D1% AND NOT L9% FOR K%=1% TO 16%: L9%=D1%:FOR K%=1% TO 16%:GOTO 460 UNLESS D1% AND K2%(K%): IF D1% AND K%(K%) THEN 430 ELSE %," ";IF H1%:GOTO 450 421! LOOK UP TERMINALS, FIGURE OUT IF THERE ARE ANY MORE TO BE PRINTED AND ACCUMULATE LOGINS FOR EACH 430 %,"* ";IF H1%:T7%=T7%+1%:D1%=D1%-K%(K%):C%(K%)=C%(K%)+1% 431! IF THE TERMINAL IS ACTIVE, PRINT A * AND COUNT IT. 450 NEXT K% 460 % IF H1%:D=D/60:C7%=C7%+1% 461! GO TO A NEW LINE IF PRINTING, AND INCREMENT THE HOUR NUMBER. 470 C7%(C7%)=C7%(C7%)+1%:T8(C7%)=T8(C7%)+D:T7%(C7%)=T7%(C7%)+T7%: IF D7% THEN O7%(S9%)=O7%(S9%)+FNF% ELSE O8%(S9%)=O8%(S9%)+FNF% IF V1%=-1%:O9%(S9%)=O9%(S9%)+FNF% UNLESS V1%:D7%=-1% 471! ACCUMULATE # OF TERMINALS IN USE, I/O TIME AND NUMBER OF SCANS IN THE HOUR, AND ACCUMULATE UPTIME, CRASHED TIME OR DOWNTIME. 475 M8%(C7%)=T7% IF T7%S2% THEN V1%=S1%:S2%=C%(S1%) 521! THIS FINDS THE TERMINAL # WITH THE LARGEST # OF STARS. 530 S1%=S1%+1%:GOTO 520 IF S1%<17%:% USING"##"+SPACE$(10%)+"####"+ SPACE$(15%)+"###.#"+SPACE$(18%)+"####",V1%-1%,C%(V1%),.166667*C%(V1%), L%(V1%):T9%=T9%+C%(V1%):L9%=L9%+L%(V1%):C%(V1%)=-1%:NEXT I%: %,"-";FOR I%=1% TO 60% 535 %:% USING"TOTALS #####"+SPACE$(14%)+"####.#"+SPACE$(17%)+"#####", T9%,.166667*T9%,L9%:A$=SYS(CHR$(0%)) 540 %:%,"SYSTEM USAGE AND I/O TIME HOURLY STATISTICS";:GOSUB 1000: %," FROM TO NUMBER OF JOBS DISK I/O"; " TIME RATIO OF":%,TAB(23%);"MIN MEAN MAX "; "MIN MEAN MAX MEANS" 550 FOR I%=1% TO 24%:T7%=1440%-60%*I%:%,TIME$(T7%+60%);" - ";: T7%=1440% UNLESS T7%:%,TIME$(T7%);:C7,C7%=C7%(I%):GOTO 560 UNLESS C7%:% USING" ## ##.## ## ##.## ##.## ##.##", M8%(I%),T7%(I%)/C7,M9%(I%),M8(I%),T8(I%)/C7,M9(I%); 555 IF T7%(I%) THEN % USING" ##.##",T8(I%)/T7%(I%) ELSE %," ---" 556! IF THE # OF JOBS (AVERAGE) IS 0, PRINT --- , ELSE PRINT THE RATIO 557 GOTO 570 560 %," -- --- -- --- --- --- ---" 561! THIS LINE OF --- IS PRINTED IF THERE ARE NO ENTRIES AT ALL. 570 NEXT I%:%:A$=SYS(CHR$(0%)):% 580 %,"TOTAL COUNTS";:GOSUB 1000:%,TAB(20%);"SINCE CREATION";TAB(40%); "DURING SPECIFIED PERIOD":%,TAB(18%);DATE$(D%(1%,0%));" "; TIME$(D%(0%,0%));" DAY(8AM-8PM) NIGHT(8PM-8AM)":% 585 O2%(1%)=X%(4%):O2%(2%)=X%(5%)-1%:O2%(3%)=X%(1%):O2%(4%)=X%(2%): % USING"\ \ ###"+SPACE$(14%)+"###"+ SPACE$(12%)+"###",T$(V1%),O2%(V1%),O1%(V1%,1%),O1%(V1%,2%) FOR V1%=1% TO 4% 586! PRINT OUT THE COUNTS FROM THE ARRAY AND USE THE T$ ARRAY FOR LINE HEADER. 600 A$=SYS(CHR$(0%)):%:%,"TOTAL TIMES (HH:MM)";:GOSUB 1000: %,TAB(21%);"DURING SPECIFIED PERIOD":%,TAB(19); "DAY(8AM-8PM) NIGHT(8PM-8AM)":% 610 % USING"SYSTEM UPTIME ###:\\ ###:\\",O7%(1%)/60%, RIGHT(NUM$(O7%(1%)-O7%(1%)/60%*60%+100%),3%),O7%(2%)/60%, RIGHT(NUM$(O7%(2%)-O7%(2%)/60%*60%+100%),3%) 615 % USING"SYSTEM SHUT DOWN ###:\\ ###:\\",O9%(1%)/60%, RIGHT(NUM$(O9%(1%)-O9%(1%)/60%*60%+100%),3%),O9%(2%)/60%, RIGHT(NUM$(O9%(2%)-O9%(2%)/60%*60%+100%),3%) 620 % USING"SYSTEM CRASHED ###:\\ ###:\\",O8%(1%)/60%, RIGHT(NUM$(O8%(1%)-O8%(1%)/60%*60%+100%),3%),O8%(2%)/60%, RIGHT(NUM$(O8%(2%)-O8%(2%)/60%*60%+100%),3%) 625 Q1%=O7%(1%)+O8%(1%)+O9%(1%):Q2%=O7%(2%)+O8%(2%)+O9%(2%): % USING"TOTAL"+SPACE$(16%)+"###:\\ ###:\\",Q1%/60%, RIGHT(NUM$(Q1%-Q1%/60%*60%+100%),3%),Q2%/60%, RIGHT(NUM$(Q2%-Q2%/60%*60%+100%),3%):A$=SYS(CHR$(0%)):% 626! LINES 610-625 PRINT OUT A TIME IN THE FORMAT HHHH:MM. 630 %,"PERCENTAGES";:GOSUB 1000:% USING"SYSTEM UPTIME ###.#%" +" ###.#% OF SCHEDULED UPTIME",100*O7%(1%)/ (O7%(1%)+O8%(1%)),100*O7%(2%)/(O7%(2%)+O8%(2%)) 635 % USING"SYSTEM SHUT DOWN ###.#% ###.#% OF TOTAL TIME", 100*O9%(1%)/Q1%,100*O9%(2%)/Q2%:%,CHR$(26%);:CLOSE 1%,2%: GOTO 32767 650 DEF FND$(D%) 651! THIS FUNCTION IS USED TO PRINT OUT A DATE WITHOUT THE HYPHENS IN IT. 660 V$=DATE$(D%):FND$=LEFT(V$,2%)+MID(V$,4%,3%)+RIGHT(V$,8%):FNEND 670 &"INPUT FILE NAME";:INPUT LINE F$:F$="[254,254]TIMOUT.TMR"IF LEN(F$) <3%:&"OUTPUT FILE";:INPUT LINE O$:O$="KB:"IF LEN(O$)<3%: OPEN O$ FOR OUTPUT AS FILE 2% 671! THIS SUBROUTINE DOES THE INITIAL DIALOGUE. 680 INPUT"PRINTOUT OF YESTERDAY ONLY";S$:IF S$>="Y" THEN Q1%,Q2%=PEEK(2048%)-1%:Q1%,Q2%=FNQ%("31-DEC-7"+NUM$(Q1% /1000%-1%)) IF Q1%=Q1%/1000%*1000%:H%=0%:RETURN 681! FOR 'YESTERDAY ONLY' THIS LINE LOOKS UP THE DATE AND DOES DOMETHING SPECIAL IN CASE WE'RE ABOUT TO GET 00-JAN-.. 690 INPUT"DO YOU WANT A FULL PRINTOUT";A$:IF A$<"Y" THEN H%=0% ELSE H%=-1% 700 INPUT"DO YOU WANT SELECTIVE PRINTOUT";S$:RETURN IF S$<"Y" 710 &"STARTING AND ENDING DATES (FORMAT IS DD-MMM-YY,DD-MMM-YY)": &"DATES...";:INPUT D1$,D2$:Q1%=FNQ%(D1$):Q2%=FNQ%(D2$):GOTO 710 UNLESS Q1% AND Q2%<>0%:IF Q2%=Q1% AND D4%<=Q2%:IF D4%3% THEN 870 771! THIS FUNCTION DECODES DATES FROM THE FORMAT IN WHICH RSTS TYPES THEM OUT AND THE USER HAS TO TYPE THEM IN. 810 V1%=INSTR(1%,"JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC",D$)+2%: IF V1%<>V1%/3%*3% THEN 870 ELSE V1%=V1%/3% 811! FIGURE OUT WHICH MONTH IT IS IN. 830 GOTO 870 IF V%>Q%(V1%) OR V%<1% OR W%<73% OR W%>99%:ON ERROR GOTO 0: FNQ%=1000%*(W%-70%)+V%+FNQ2%(W%,V1%):GOTO 875 860 RESUME 870 870 &"ILLEGAL DATE FORMAT, TRY AGAIN":FNQ%=0% 871! IN CASE OF A ERRONEOUS DATE, THE DATE RETURNED IS 0. 875 FNEND 880 J%=2%:RETURN IF S$<"Y" OR D%(3%,10%)>=Q1% :J%=Z%/2%:Z1%=Z%/4% 881! THIS IS THE SEARCH ROUTINE. IF WE WANT NO SEARCH (NON-SELECTIVE) THEN THIS ROUTINE RETURNS IMMEDIATELY. OTHERWISE, A BINARY SEARCH IS PERFORMED. (THIS ASSUMES THE DATA IS ORDERED, WHICH IT OUGHT TO BE). 900 IF D%(3%,J%)>=Q1% THEN J%=J%-Z1%-2%:Z1%=Z1%/2%:GOTO 900 910 IF Z1%<30% THEN RETURN ELSE J%=J%+Z1%:Z1%=Z1%/2%:GOTO 900 920 DEF FNQ2%(Y%,M%):Q4%=0%:Q4%=Q4%+Q%(Q3%-1%) FOR Q3%=2% TO M%:Q4%=Q4%+1% UNLESS M%<3% OR Y% AND 3%:FNQ2%=Q4%:FNEND 921! THIS FUNCTION FIGURES OUT THE NUMBER OF DAYS PRECEDING THE GIVEN MONTH, IN THE GIVEN YEAR (TAKES CARE OF LEAP YEARS). 950 DEF FNF%:V1%=0%:GOTO 980 UNLESS O3% OR O4%: V1%=D3%-O3%:V2%=D4%-O4%:IF V2% THEN V1%=V1%+1440%*V2% 980 O3%=D3%:O4%=D4%:FNF%=V1%:FNEND 1000 %," ";:%,"*"; WHILE POS(2%)<72%:%:%:RETURN 1001! PRINT OUT *S TILL YOU ARE AT THE END OF THE LINE. ***** BEWARE: IF THE LINE WIDTH IS <72 CHARACTERS THIS ROUTINE WILL NEVER END. (A TEELETYPE IS 72 CHARACTERS WIDE). 32767 END