! ! Connect Count Monitoring Routines. ! ------- ----- ---------- -------- ! ! These routines are intended to provide the ability to monitor ! the number of times a given file is connected during a given time ! period. ! Each file on the system has an associated file descriptor one ! of whose fields is the connect count (CCT) which is incremented ! every time the file is connected. The CCT field is a single ! byte therefore values may range from 0 - 255. When the byte reaches ! 255 then further connections leave its value unchanged - the ! field must be reset. In essence the monitoring routines read the ! current value of CCT for the files monitored then reset the field ! back to zero. ! The monitoring programs comprise 4 external routines - CCTMON, ! ALTERCCT,CCTOUT and LOOKCCT - and an associated but separately set up ! monitor file whose name is compiled as a constant in the code. ! Each of the routines is described below along with operating ! instructions and instructions on setting up a monitor file. ! ! 1. Overview. ! The monitor file is a series of records, one for each file ! monitored. These contain fields for the name of the file, its fsys ! the date monitoring started, the value of CCT the last time it ! was read, the accumulated CCT, and the number of 'busy days' i.e. ! the number of days the CCT was >=255. ! Files are added or removed from the monitor file by the routine ! ALTERCCT. The same routine can reset counters for individual files. ! The monitoring information is written in to the monitor file ! by the routine CCTMON which reads and resets the CCT field in ! the file descriptors of the files to be monitored. CCTMON detaches ! itself automatically to run again after midnight n days hence ! (n = 1 currently). ! Information in the monitor file is displayed by the routine ! CCTOUT which produces a summary of monitoring to date. ! ! 2. Operating Instructions. ! ALTERCCT and CCTMON will only run in the owner process ! and require sufficient privilege to read and reset CCT ! fields. LOOKCCT and CCTOUT will run in any process with ! read access to the monitor file. LOOKCCT, however, requires ! the user process to have sufficient privilege to read ! CCT fields. ! ! 2.1 Setting up a monitor file. ! The routines currently expect a monitor file of 1Epage which ! allows 127 monitor records. The filename must be ! compiled in as a constant into the code. ! This file can easily be set up using one of the system ! editors and inserting 4064 characters (which will exactly ! fill 1 Epage) then cherishing and permitting it to those users ! allowed to read the file. If desired some extra protection ! can be supplied by changing the file type to non-standard ! (by using #SNAP on the 4th word of the header). ! The file should be zeroed before use by using option 'ZAP' ! in routine ALTERCCT. ! ! 2.2 CCTMON. ! This routine requires no parameters. When run it prints ! the document number of the job it has detached. When ! running for the first time the routine should be called ! interactively which will reset the CCTs of the files to ! be monitored to zero and detach a job to run next day. ! ! 2.3 ALTERCCT. ! This routine issues prompts for all commands and is used to ! make alterations to the monitor file. ! The command options are : ! HELP,ADD,DEL,REP,RES,TERM,XRES,ZAP,? and .END ! HELP - explains the commands ! ADD - adds a new member to the monitor file - will further ! prompt for <user> and <file>. Also resets the ! file descriptor CCT to 0. ! DEL - deletes a member from the monitor file - will further ! prompt for <user> and <file> ! REP - replaces <user> and <file> for one member of ! the monitor file. No resetting of counters. Should ! be used when a new version of a file with a different ! name (e.g. version number) is introduced. Previous ! monitoring is thus retained. Prompts for <user> and ! <file> to be replaced then new values of <user> and ! <file>. See also TERM. ! RES - resets CCT counters to 0 and the monitor start field to ! today's day number. Resets file descriptor CCT to 0. ! Will further prompt for <user> and <file>. ! TERM - updates counters for a given member for values ! accumulated since the last run of CCTMON. Intended ! to be used in conjunction with REP (q.v.) so that ! CCT values on old versions of a file can be added ! to the monitoring statistics before replacement ! by a new version. Prompts for <user> and <file>. ! XRES - effect is RES for all monitor file members. No <user>, ! <file> prompts. ! ZAP - zeroes the entire monitor file (all information destroyed ! ? - prints list of current members of monitor file. ! .END - terminates requests for another option ! ! 2.3 CCTOUT. ! This routine prints out a summary of the information held ! in the monitor file in a six column table of the form: ! User.file/ date monitoring began/number of days since monitoring ! began/ last value of CCT read for this file/ cumulative CCT/ ! number of days when CCT>=255. ! N.B. No privilege required. ! ! 2.4 LOOKCCT. ! This routine prints a table of the current values of CCT ! for each member of the monitor file by reading the file ! descriptors directly. No alterations are made to the ! monitor file. The table therefore represents today's ! values of CCT from the last run of CCTMON till the ! moment of running the routine. ! Requires enough privilege to read CCT fields. ! ! Colin McCallum June 1981. ! !> ! RECORDFORMAT PF(INTEGER DEST,SRCE,P1,P2,P3,P4,P5,P6) RECORDFORMAT MONF(STRING (6) USER, STRING (11) FILE, C BYTEINTEGER LASTCCT, INTEGER CUMCCT,BUSYDAYS,MONSTART) RECORDFORMAT RF(INTEGER CONAD,FTYPE,DATASTART,DATAEND) RECORDFORMAT DFINFOF(INTEGER NKB,RUP,EEP,APF,USE,ARCH, C FSYS,CONSEG,CCT,CODES, C BYTEINTEGER SP1,DAYNO,POOL,CODES2, C INTEGER SSBYTE,STRING (6) TRAN) EXTERNALROUTINESPEC UDERRS(INTEGER FLAG) EXTERNALINTEGERFNSPEC DFSTATUS(STRING (6) USER,STRING (11) FILE,C INTEGER FSYS,ACT,VALUE) EXTERNALROUTINESPEC RSTRG(STRINGNAME S) EXTERNALROUTINESPEC PROMPT(STRING (15) S) EXTERNALINTEGERFNSPEC DSPOOL(RECORD (PF)NAME P, INTEGER LEN,ADR) EXTERNALINTEGERFNSPEC DFINFO(STRING (6) USER, STRING (11) FILE, C INTEGER FSYS,ADR) SYSTEMROUTINESPEC OUTFILE(STRING (31) S, INTEGER SIZE,MAXBYTES, C PROT, INTEGERNAME CONAD,FLAG) SYSTEMROUTINESPEC MOVE(INTEGER LEN,FROM,TO) SYSTEMROUTINESPEC PSYSMES(INTEGER I, FLAG) SYSTEMROUTINESPEC CONNECT(STRING (31)S,INTEGER ACC,MAXB,PRO, C RECORD (RF)NAME RR, INTEGERNAME FLAG) EXTERNALSTRINGFNSPEC DATE EXTERNALSTRINGFNSPEC TIME SYSTEMINTEGERFNSPEC PACKDATEANDTIME(STRING (8) DATE,TIME) SYSTEMSTRING (8)FNSPEC UNPACKDATE(INTEGER I) SYSTEMSTRING (8)FNSPEC UNPACKTIME(INTEGER I) EXTERNALROUTINESPEC DISCONNECT(STRING (255) S) SYSTEMSTRINGFNSPEC ITOS(INTEGER I) CONSTINTEGER MAXREC=127 CONSTSTRING (255) HELP= C " Options are: ADD - Add a new member DEL - Delete a member REP - Replace member name RES - Reset counters for a single member " CONSTSTRING (255) HELP2= C "TERM - Update counters for one member XRES - Reset counters for all members ZAP - Zero the entire file (destroys all info) ? - Print out files currently being monitored " CONSTSTRING (15) MONFILE="MANAGR.CCTMFILE" OWNRECORD (MONF)ARRAYFORMAT MONAF(0:MAXREC-1) OWNRECORD (MONF)ARRAYNAME TAB OWNRECORD (DFINFOF) FINF OWNRECORD (RF) RR ROUTINE KDATE(INTEGERNAME D,M,Y,INTEGER K) !*********************************************************************** !* K IS DAYS SINCE 1ST JAN 1900 * !* RETURNS D, M, Y 2 DIGIT Y ONLY * !*********************************************************************** ! %INTEGER W ! K=K+693902; ! DAYS SINCE CEASARS BDAY ! W=4*K-1 ! Y=W//146097 ! K=W-146097*Y ! D=K//4 ! K=(4*D+3)//1461 ! D=4*D+3-1461*K ! D=(D+4)//4 ! M=(5*D-3)//153 ! D=5*D-3-153*M ! D=(D+5)//5 ! Y=K *LSS_K; *IAD_693902 *IMY_4; *ISB_1; *IMDV_146097 *LSS_TOS ; *IDV_4; *IMY_4; *IAD_3 *IMDV_1461; *ST_(Y) *LSS_TOS ; *IAD_4; *IDV_4 *IMY_5; *ISB_3; *IMDV_153 *ST_(M); *LSS_TOS *IAD_5; *IDV_5; *ST_(D) IF M<10 THEN M=M+3 ELSE START M=M-9 IF Y=99 THEN Y = 0 ELSE Y=Y+1 FINISH END ; ! OF KDATE INTEGERFN DDAYNO CONSTLONGINTEGER JMS=X'141DD76000' INTEGER RES *RRTC_0 *USH_-1 *SHS_1 *USH_1 *IDV_JMS *STUH_B ! *AND_255 *ST_RES ! RES=1 %IF RES=0 RESULT =RES END ; ! OF DDAYNO STRINGFN MYDATE(INTEGER DAYNO) INTEGER D,M,Y STRING (3) DD,MM,YY KDATE(D,M,Y,DAYNO) DD=ITOS(D) DD="0".DD IF LENGTH(DD)=1 MM=ITOS(M) MM="0".MM IF LENGTH(MM)=1 YY=ITOS(Y) YY="0".YY IF LENGTH(YY)=1 RESULT =DD."/".MM."/".YY END ; ! OF MYDATE INTEGERFN GETCCT(STRING (15) USER,FILE) INTEGER FLAG ! GET CCT FLAG=DFINFO(USER,FILE,-1,ADDR(FINF)) PRINTSTRING(USER.".".FILE." ") AND C UDERRS(FLAG) UNLESS FLAG=0 RESULT =FLAG END ; ! OF GETCCT INTEGERFN RESET CCT(INTEGER I) INTEGER FLAG ! RESET CCT TO 0 FLAG=DFSTATUS(TAB(I)_USER,TAB(I)_FILE,-1,9,0) PRINTSTRING(TAB(I)_USER.".".TAB(I)_FILE." ") AND C UDERRS(FLAG) UNLESS FLAG=0 RESULT =FLAG END ; ! OF RESET CCT ROUTINE AUTOJOB(STRING (255) COMMANDS, INTEGER INTERVAL,CPU) INTEGER COMMAD,FLAG,DAYNO,CONAD,NEWSIZE STRING (255) MESSAGE RECORD (PF) P COMMAD=ADDR(COMMANDS) NEWSIZE=LENGTH(COMMANDS)+32 OUTFILE("S#AUTO",NEWSIZE,NEWSIZE,0,CONAD,FLAG) IF FLAG#0 THEN PSYSMES(10,FLAG) AND RETURN INTEGER(CONAD)=NEWSIZE INTEGER(CONAD+4)=32 INTEGER(CONAD+12)=3 MOVE(NEWSIZE-32,COMMAD+1,CONAD+32) DISCONNECT("S#AUTO") DAYNO=DDAYNO+INTERVAL MESSAGE="DOCUMENT SRCE=S#AUTO,DEST=BATCH,NAME=AUTO,AFTER=". C MYDATE(DAYNO).",DELIV=R.D.Eager CUR022 CUR022,".C "TIME=".ITOS(CPU).",START=32". C ",LENGTH=".ITOS(NEWSIZE) NEWLINE P=0 FLAG=DSPOOL(P,LENGTH(MESSAGE),ADDR(MESSAGE)+1) UNLESS FLAG=0 THEN START UDERRS(FLAG) PRINTSTRING(MESSAGE) PRINTSTRING("Error at or around char") WRITE(P_P3,1) NEWLINE FINISH ELSE START PRINTSTRING("CCTMON Batch queue ident :") WRITE(P_P2&X'FFFFFF',1) NEWLINE FINISH RETURN END ; ! OF AUTOJOB EXTERNALROUTINE CCTMON(STRING (255) S) STRING (8) TODAY,NOW INTEGER FLAG,TOP,I CONNECT(MONFILE,3,0,0,RR,FLAG) PSYSMES(8,FLAG) AND RETURN UNLESS FLAG=0 TAB==ARRAY(RR_CONAD+RR_DATASTART,MONAF) TOP=INTEGER(RR_CONAD+28)-1 FOR I=0,1,TOP CYCLE ! GET CCT FLAG=GETCCT(TAB(I)_USER,TAB(I)_FILE) CONTINUE UNLESS FLAG=0 TAB(I)_LASTCCT=FINF_CCT TAB(I)_CUMCCT=TAB(I)_CUMCCT+FINF_CCT TAB(I)_BUSYDAYS=TAB(I)_BUSYDAYS+1 IF FINF_CCT=255 ! RESET CCT TO 0 FLAG=RESET CCT(I) REPEAT TODAY=DATE NOW=TIME INTEGER(RR_CONAD+16)=PACKDATEANDTIME(TODAY,NOW) AUTOJOB("CCTMON CCTOUT ",1,20) DISCONNECT(MONFILE) RETURN END ; ! OF CCTMON EXTERNALROUTINE ALTERCCT(STRING (255) S) STRING (31) REPLY,USER,FILE INTEGER TOP,FLAG,FOUND,TODAYSDAYNO,I,NEXTFREE INTEGERFN FIND(STRING (6) USER, STRING (11) FILE) INTEGER I,J J=-1 FOR I=0,1,TOP CYCLE J=I AND EXIT IF TAB(I)_USER=USER AND TAB(I)_FILE=FILE REPEAT RESULT =J END ; ! OF FIND TODAYSDAYNO=DDAYNO CONNECT(MONFILE,3,0,0,RR,FLAG) PSYSMES(8,FLAG) AND RETURN UNLESS FLAG=0 TAB==ARRAY(RR_CONAD+RR_DATASTART,MONAF) NEXTFREE=INTEGER(RR_CONAD+28) TOP=NEXTFREE-1 CYCLE PRINTSTRING("Valid options are: 'HELP','ADD','DEL','REP','RES','TERM','XRES','ZAP' or '?'. Terminate with '.END' ") PROMPT("Option? : ") RSTRG(REPLY) UNTIL REPLY="ADD" OR REPLY="DEL" OR REPLY=".END" C OR REPLY="ZAP" OR REPLY="?" OR REPLY="RES" OR REPLY="XRES" C OR REPLY="HELP" OR REPLY="REP" OR REPLY="TERM" EXIT IF REPLY=".END" IF REPLY="HELP" THEN PRINTSTRING(HELP) AND C PRINTSTRING(HELP2) AND CONTINUE IF REPLY="ZAP" THEN START TAB(I)=0 FOR I=0,1,MAXREC-1 INTEGER(RR_CONAD+28)=0 NEXTFREE=0 TOP=-1 CONTINUE FINISH IF REPLY="XRES" THEN START IF TOP<0 THEN PRINTSTRING("*Table empty* ") AND CONTINUE FOR I=0,1,TOP CYCLE TAB(I)_MONSTART=TODAYSDAYNO TAB(I)_LASTCCT=0 TAB(I)_CUMCCT=0 TAB(I)_BUSYDAYS=0 FLAG=RESET CCT(I) PRINTSTRING(TAB(I)_USER.".".TAB(I)_FILE." reset ") IF FLAG=0 REPEAT CONTINUE FINISH IF REPLY="?" THEN START PRINTSTRING(TAB(I)_USER.".".TAB(I)_FILE." ") FOR I=0,1,TOP CONTINUE FINISH IF REPLY="ADD" AND NEXTFREE=MAXREC THEN PRINTSTRING("*Table full* ") AND CONTINUE IF (REPLY="DEL" OR REPLY="RES") AND TOP<0 THEN C PRINTSTRING("*Table empty* ") AND CONTINUE PROMPT("User: ") RSTRG(USER) UNTIL LENGTH(USER)=6 PROMPT("File: ") RSTRG(FILE) FLAG=GETCCT(USER,FILE); ! DOES IT EXIST? CONTINUE UNLESS FLAG=0 OR REPLY="REP" FOUND=FIND(USER,FILE) IF REPLY="ADD" THEN START IF FOUND>=0 THEN PRINTSTRING(USER.".".FILE." already in table ") AND CONTINUE TAB(NEXTFREE)=0 TAB(NEXTFREE)_USER=USER TAB(NEXTFREE)_FILE=FILE TAB(NEXTFREE)_MONSTART=TODAYSDAYNO TOP=NEXTFREE FLAG=RESET CCT(NEXTFREE) CONTINUE UNLESS FLAG=0 NEXTFREE=NEXTFREE+1 INTEGER(RR_CONAD+28)=NEXTFREE PRINTSTRING(USER.".".FILE." added to CCT monitor table ") CONTINUE FINISH ! MUST BE DELETING OR RESETTING 1 MEM IF FOUND=-1 THEN PRINTSTRING(USER.".".FILE." not in table ") AND CONTINUE IF REPLY="DEL" THEN START ! CLOSE UP TABLE TAB(FOUND)=TAB(FOUND+1) AND FOUND=FOUND+1 WHILE FOUND<TOP TAB(TOP)=0 NEXTFREE=TOP TOP=TOP-1 INTEGER(RR_CONAD+28)=NEXTFREE PRINTSTRING(USER.".".FILE." removed from CCT monitor list ") CONTINUE FINISH IF REPLY="RES" THEN START FLAG=RESET CCT(FOUND) CONTINUE UNLESS FLAG=0 TAB(FOUND)_MONSTART=TODAYSDAYNO TAB(FOUND)_LASTCCT=0 TAB(FOUND)_CUMCCT=0 TAB(FOUND)_BUSYDAYS=0 PRINTSTRING(USER.".".FILE." reset ") CONTINUE FINISH IF REPLY="REP" THEN START PRINTSTRING("To be replaced by: ") PROMPT("User: ") RSTRG(USER) UNTIL LENGTH(USER)=6 PROMPT("File: ") RSTRG(FILE) FLAG=GETCCT(USER,FILE); ! DOES IT EXIST? CONTINUE UNLESS FLAG=0 TAB(FOUND)_USER=USER TAB(FOUND)_FILE=FILE PRINTSTRING("Replacement complete ") FINISH IF REPLY="TERM" THEN START TAB(FOUND)_LASTCCT=FINF_CCT TAB(FOUND)_CUMCCT=TAB(FOUND)_CUMCCT+FINF_CCT TAB(FOUND)_BUSYDAYS=TAB(FOUND)_BUSYDAYS+1 IF FINF_CCT=255 ! RESET CCT TO 0 FLAG=RESET CCT(FOUND) PRINTSTRING("Terminated O.K. ") FINISH REPEAT DISCONNECT(MONFILE) RETURN END ; ! OF ALTERCCT EXTERNALROUTINE CCTOUT(STRING (255) S) INTEGER TOP,FLAG,I,TODAYSDAYNO TODAYSDAYNO=DDAYNO CONNECT(MONFILE,1,0,0,RR,FLAG) PSYSMES(8,FLAG) AND RETURN UNLESS FLAG=0 TAB==ARRAY(RR_CONAD+RR_DATASTART,MONAF) TOP=INTEGER(RR_CONAD+28)-1 PRINTSTRING("CCT monitor file has no entries ") AND RETURN UNLESS TOP>=0 PRINTSTRING("Monitoring file last updated - ". C UNPACKDATE(INTEGER(RR_CONAD+16))." at ". C UNPACKTIME(INTEGER(RR_CONAD+16))." ") PRINTSTRING( C "Monitor file Monstart Days Last CCT Cum CCT >=255 ") FOR I=0,1,TOP CYCLE PRINTSTRING(TAB(I)_USER.".".TAB(I)_FILE) SPACES(14-LENGTH(TAB(I)_FILE)) PRINTSTRING(MYDATE(TAB(I)_MONSTART)) WRITE(TODAYSDAYNO-TAB(I)_MONSTART,7) WRITE(TAB(I)_LASTCCT,8) WRITE(TAB(I)_CUMCCT,11) WRITE(TAB(I)_BUSYDAYS,7) NEWLINE REPEAT DISCONNECT(MONFILE) RETURN END ; ! OF CCTOUT EXTERNALROUTINE LOOKCCT(STRING (255) S) EXTERNALSTRINGFNSPEC DATE EXTERNALSTRINGFNSPEC TIME INTEGER TOP,FLAG,I PRINTSTRING("LOOKCCT at ".TIME." on ".DATE." ") CONNECT(MONFILE,1,0,0,RR,FLAG) PSYSMES(8,FLAG) AND RETURN UNLESS FLAG=0 TAB==ARRAY(RR_CONAD+RR_DATASTART,MONAF) TOP=INTEGER(RR_CONAD+28)-1 PRINTSTRING("CCT monitor file has no entries ") AND RETURN UNLESS TOP>=0 PRINTSTRING( C "Monitor file Current CCT ") FOR I=0,1,TOP CYCLE ! GET CCT FLAG=GETCCT(TAB(I)_USER,TAB(I)_FILE) IF FLAG=0 THEN PRINTSTRING(TAB(I)_USER.".".TAB(I)_FILE." ") C ELSE CONTINUE SPACES(14-LENGTH(TAB(I)_FILE)) WRITE(FINF_CCT,8) NEWLINE REPEAT DISCONNECT(MONFILE) RETURN END ; ! OF LOOKCCT ENDOFFILE