! This file contains system management processing and reports ! originally designed for the DECUServe system. They include ! recording how often various users log onto the system, ! when users last logged in, and an Erlang traffic study of ! connections (to determine if there are enough dial-up lines ! to the system). It uses the System Accounting conversion ! program (in [DTRSIG.ACCOUNTING]). The ACC_RECORD definition ! and SYSUAF_RECORD definition duplicate definitions in other ! sections of the [DTRSIG...] collection. ! ! B. Z. Lederman 28-Jan-1988 ! DELETE ACC; REDEFINE DOMAIN ACC USING ACC_RECORD ON ! ! Note the use of a logical name because the ! accounting file changes daily. ! ACCOUNTING_FILE; DELETE ACC_RECORD; REDEFINE RECORD ACC_RECORD !! OPTIMIZE 01 ACC_REC. ! ! This record definition reads the fields produced by the ! program which "fixes" System Accounting records by putting them ! into fixed format fields. ! ! B. Z. Lederman 15-Apr-1987 ! 20-Jan-1988 Latest revision for login sessions ! plus image names ! Stripped for no user functions and old DTR ! 05 ROOT. 10 TYPE USAGE BYTE. 10 SUB_TYPE USAGE BYTE. 10 SYSTEM_DATE USAGE DATE. 10 EBIN REDEFINES SYSTEM_DATE. ! used for elapsed time 20 EQUAD USAGE QUAD. ! computations 05 INFO. 10 RECORD COMPUTED BY TYPE VIA ACC_TYPE_TABLE. 10 PACKET COMPUTED BY SUB_TYPE VIA ACC_SUBTYPE_TABLE. 10 SYSTEM_TIME COMPUTED BY FN$TIME(SYSTEM_DATE) EDIT_STRING X(12). ! ! Begin fields from ID packet ! 05 ID. 10 IDENT. 20 DIN. 30 FILLER PIC X(20). 20 DECIMALS REDEFINES DIN. 30 DPID USAGE LONG. ! process ID 30 DPIDOWN USAGE LONG. ! Owner process ID 30 DUIC USAGE LONG. 30 DPRIV1 USAGE LONG. 30 DPRIV2 USAGE LONG. 20 PID COMPUTED BY FN$HEX(DPID) EDIT_STRING X(8). 20 PIDOWN COMPUTED BY FN$HEX(DPIDOWN) EDIT_STRING X(8). ! ! The next two fields require a user-defined function supplied ! on the DTR/4GL SIG Library Collection (also found on the VAX SIG Tapes. ! It formats the binary UIC into meaningful information. ! !! 20 NUIC COMPUTED BY FN$FAO("!%I",DUIC,"","","","","","","") !! EDIT_STRING X(14). !! 20 OUIC COMPUTED BY FN$FAO("!%U",DUIC,"","","","","","","") !! EDIT_STRING X(9). 20 PRIVILEGES. 30 PRIV1 COMPUTED BY FN$HEX(DPRIV1) EDIT_STRING X(8). 30 PRIV2 COMPUTED BY FN$HEX(DPRIV2) EDIT_STRING X(8). 20 PRIORITY USAGE BYTE EDIT_STRING Z9. 10 USER. 20 USERNAME PIC X(12). 20 ACCOUNT PIC X(8). 20 NODE PIC X(6). 20 TERMINAL PIC X(6). 10 JOB. 20 JOBNAME PIC X(12). 20 JOBID USAGE LONG EDIT_STRING ZZ,ZZ9. 20 QUEUE PIC X(32) EDIT_STRING T(16). 20 NODEADDR USAGE WORD EDIT_STRING ZZ,ZZ9. 20 REMOTE_ID PIC X(16). ! ! Start process deletion fields (also image deletion, logfail, etc.) ! 05 PROCESS_DELETION. 10 TIMES. 20 SD. ! used to "hide" the starting date 30 FILLER PIC X(8). ! because we don't need two dates 20 SDATE REDEFINES SD. 30 START_DATE USAGE DATE. 30 SBIN REDEFINES START_DATE. 40 SQUAD USAGE QUAD. 20 START_TIME COMPUTED BY FN$TIME(START_DATE) EDIT_STRING X(12). ! ! Compute the elapsed connect time in seconds (for user session reports) ! Easier to compute here than in the report. ! 20 ELAPSED COMPUTED BY (EQUAD - SQUAD) / 10000000 EDIT_STRING ZZ,ZZ9.99. 20 ELAPSED_MINUTES COMPUTED BY ELAPSED / 60 EDIT_STRING ZZ,ZZ9.99. 10 STATUS. 20 FSTAT. 30 FILLER PIC XXXX. 20 RSTAT REDEFINES FSTAT. 30 DSTAT USAGE LONG. 30 HSTAT COMPUTED BY FN$HEX(DSTAT) EDIT_STRING X(8). ! ! The following field requires a user-define function (see FN$FAO). ! It converts the exit status from a number into a system message. ! !! 20 STATUS_TEXT COMPUTED BY FN$GETMSG(DSTAT,0) EDIT_STRING T(32). ! 10 COUNTS. 20 IMAGE_COUNT USAGE LONG EDIT_STRING Z,ZZ9. 20 CPU_TIME USAGE LONG PIC 9(10)V99 EDIT_STRING Z,ZZZ,ZZ9.99. 20 FAULTS USAGE LONG EDIT_STRING ZZZ,ZZ9. 20 FAULT_IO USAGE LONG EDIT_STRING ZZZ,ZZ9. 20 WS_PEAK USAGE LONG EDIT_STRING Z,ZZ9. 20 PAGE_FILE USAGE LONG EDIT_STRING ZZ,ZZ9. 20 DIO_COUNT USAGE LONG EDIT_STRING ZZZ,ZZ9. 20 BIO_COUNT USAGE LONG EDIT_STRING ZZZ,ZZ9. 20 VOLUMES USAGE LONG. ! ! The following is needed for calculating Erlang traffic ! figures by each minute of the day. ! 10 MOD. ! Minute of Day (0 to 1439) 20 START_MOD COMPUTED BY (FN$HOUR(START_DATE) * 60) + FN$MINUTE(START_DATE) EDIT_STRING ZZZ9. 20 END_MOD COMPUTED BY (FN$HOUR(SYSTEM_DATE) * 60) + FN$MINUTE(SYSTEM_DATE) EDIT_STRING ZZZ9. ! ! Image name length must be adjusted to match the NAM_LEN ! value in the ACC_CONVERT program. ! 10 IMAGE_NAME PIC X(32). ! trimmed version ; DELETE ACC_SUBTYPE_TABLE; REDEFINE TABLE ACC_SUBTYPE_TABLE ! ! This converts the (byte) System Accounting sub-type into text ! ! B. Z. Lederman ! 32 : "Logfail", 33 : "Interactive", 34 : "Subprocess", 35 : "Detached", 36 : "Batch", 37 : "Network" ELSE "Undefined" END_TABLE DELETE ACC_TYPE_TABLE; REDEFINE TABLE ACC_TYPE_TABLE ! ! This is the single byte type, not the System Accounting word type ! which would include the sub-type. ! ! B. Z. Lederman ! ! I haven't seen a System Init record so I haven't put it in here. ! 2 : "Process Deletion", 6 : "Image Deletion", 14 : "Login Failure" ELSE "Undefined" END_TABLE DELETE INITIALIZE_MOD; REDEFINE PROCEDURE INITIALIZE_MOD ! ! Create a new Minute-of-Day file for processing traffic data. ! This should not be needed very often. ! ! B. Z. Lederman 11-Sep-1987 ! 27-Jan-1988 Both types of files ! ! On a system with FN$DCL, need only MOD_SEQ and then use CONVERT. ! On a system without FN$DCL, need to create MOD externally from ! MOD_SEQ or internally here. ! DEFINE FILE FOR MOD_SEQ ALLOCATION=20; ! remember to purge old files ! DEFINE FILE FOR MOD KEY = M_OF_D (NO DUP), ALLOCATION=40; ! remember to purge old files ! READY MOD_SEQ WRITE READY MOD WRITE DECLARE MINUTE USAGE INTEGER. DECLARE HOUR USAGE INTEGER. DECLARE HOUR_COUNTER USAGE INTEGER. MINUTE = 0 HOUR = 0 HOUR_COUNTER = 0 ! ! Make one record for each minute of the day, sequentially numbered. ! WHILE MINUTE LE 1439 BEGIN STORE MOD_SEQ USING BEGIN M_OF_D = MINUTE H_OF_D = HOUR TIME_BUSY = 0 NUMBER_BUSY = 0 END STORE MOD USING BEGIN M_OF_D = MINUTE H_OF_D = HOUR TIME_BUSY = 0 NUMBER_BUSY = 0 END MINUTE = MINUTE + 1 HOUR_COUNTER = HOUR_COUNTER + 1 ! ! Also mark the hour of the day for summarizing. ! IF HOUR_COUNTER = 60 THEN BEGIN HOUR = HOUR + 1 HOUR_COUNTER = 0 END END END_PROCEDURE DELETE LOGFAIL_REPORT; REDEFINE PROCEDURE LOGFAIL_REPORT ! ! This reports on login failures in an accounting file. ! ! B. Z. Lederman ! READY ACC REPORT ACC WITH PACKET = "Logfail" ON *."File or TT" SET REPORT_NAME = "Login Failures" SET NO DATE AT TOP OF PAGE PRINT REPORT_HEADER, SYSTEM_DATE(-), SKIP, COLUMN_HEADER PRINT SYSTEM_TIME, USERNAME, ACCOUNT, NODE, TERMINAL, REMOTE_ID END_REPORT END_PROCEDURE DELETE LOGIN28; REDEFINE PROCEDURE LOGIN28 ! ! Report on login performance for the previous 28 days. ! ! B. Z. Lederman 27-Jan-1988 ! DECLARE SELECT_DATE USAGE DATE. SELECT_DATE = "TODAY" SELECT_DATE = SELECT_DATE + (-28) ! Go back 28 days from today ! READY LOGIN_HISTORY REPORT LOGIN_HISTORY WITH LOGIN_DATE GE SELECT_DATE SORTED BY ACCOUNT, USERNAME ON *."File or TT" SET REPORT_NAME = "Login Performance"/"for the previous 28 days" AT TOP OF ACCOUNT PRINT COL 5, ACCOUNT AT BOTTOM OF USERNAME PRINT COL 15, USERNAME, SPACE 1, COUNT ("Number"/"of Days"/"Logged In"), SPACE 1, MIN(LOGINS) USING Z9, SPACE 1, AVERAGE(LOGINS) USING ZZ9, SPACE 1, MAX(LOGINS) USING ZZ9 END_REPORT END_PROCEDURE DELETE LOGIN72; REDEFINE PROCEDURE LOGIN72 ! ! Find users who have logged in in the past 72 hours. ! ! B. Z. Lederman ! DECLARE SELECT_DATE USAGE DATE. DECLARE SELECT_QUAD USAGE QUAD. ! SELECT_DATE = "NOW" ! ! Convert date to clunks, subtract 72 hours in clunks, convert back to date. ! SELECT_QUAD = SELECT_DATE SELECT_QUAD = SELECT_QUAD - 72 * 60 * 60 * 10000000 SELECT_DATE = SELECT_QUAD ! READY SYSUAF ! ! Read the SYSUAF.DAT file (requires the user to have the proper <--! privileges). <--! REPORT SYSUAF WITH DATE_LAST_INTERACTIVE_LOGIN GE SELECT_DATE SORTED BY ACCOUNT, USERNAME ON *."Filename or TT" SET REPORT_NAME = "Logins in the past 72 hours" PRINT ACCOUNT, USERNAME USING T(20), DATE_LAST_INTERACTIVE_LOGIN, FN$TIME(DATE_LAST_INTERACTIVE_LOGIN) ("TIME"/"LAST"/"LOGIN") USING X(11) AT BOTTOM OF ACCOUNT PRINT SKIP 1 END_REPORT END_PROCEDURE DELETE LOGIN_ACCOUNT_TABLE; REDEFINE TABLE LOGIN_ACCOUNT_TABLE ! ! This table is used to select the accounts which are wanted when ! accumulating login history, etc. It's not needed if everyone ! is collected. (Currently not used here). ! ! B. Z. Lederman ! QUERY_HEADER IS "Account" "ASD" : "ASD", "CIE" : "CIE", "EGW" : "EGQ", "FIELD" : "FIELD", "INTOPS" : "INTOPS", "SYSMGR" : "SYSMGR", "TELEXENG" : "TLXENG", "WORLDNET" : "WNET" ELSE "Undefined" END_TABLE DELETE LOGIN_HISTORY; REDEFINE DOMAIN LOGIN_HISTORY USING LOGIN_HISTORY_RECORD ON ! ! This file has the login history and needs a file definition that ! will let the system and the user know where it is. ! SYS$SYSROOT:[SYSMGR.LEDERMAN]LOGIN_HISTORY.DOM; DELETE LOGIN_HISTORY_BAR; REDEFINE DOMAIN LOGIN_HISTORY_BAR USING LOGIN_HISTORY_BAR_RECORD ON LOGIN_HISTORY_BAR.SEQ; DELETE LOGIN_HISTORY_BAR_RECORD; REDEFINE RECORD LOGIN_HISTORY_BAR_RECORD !! OPTIMIZE ! ! This is used to create a "graph" of the login history ! of any number of users. ! ! B. Z. Lederman ! 01 LOGIN_HISTORY_BAR_REC. 10 USERNAME PIC X(16). 10 ACCOUNT PIC X(8). 10 MONTH PIC 99. 10 YEAR PIC 9999. 10 BAR PIC X(62) QUERY_HEADER " ". ; DELETE LOGIN_HISTORY_FROM_ACC; REDEFINE PROCEDURE LOGIN_HISTORY_FROM_ACC ! ! Create a history of number of times each user logged in on ! each date by reading the processed System Accounting Files ! ! B. Z. Lederman 25-Jan-1988 ! 27-Jan-1988 More efficient check of existing history rec. ! READY ACC READY LOGIN_HISTORY WRITE ! DECLARE N PIC 99. DECLARE DATE_ONLY USAGE DATE. DECLARE DATE_STRING PIC X(11). ! ! Count interactive sessions only (could later separate logfails ! with the same pass if desired). ! FOR ACC WITH PACKET = "Interactive" BEGIN ! ! Must extract date only portion (no time) ! DATE_STRING = FN$UPCASE(FORMAT(ACC_REC.SYSTEM_DATE) USING DD_MMM_YYYY) DATE_ONLY = FN$DATE(DATE_STRING | " 00:00:00.00") ! ! Check to see if this person has a history record. ! If so, update it. ! N = 0 FOR LOGIN_HISTORY WITH LOGIN_HISTORY.USERNAME = ACC_REC.USERNAME AND LOGIN_HISTORY.LOGIN_DATE = DATE_ONLY BEGIN ! ! This person logged in before, so the record can be updated. ! MODIFY USING LOGINS = LOGINS + 1 N = N + 1 END ! IF N = 0 THEN BEGIN ! ! No login history record for this person, create one ! STORE LOGIN_HISTORY USING BEGIN USERNAME = ACC_REC.USERNAME ACCOUNT = ACC_REC.ACCOUNT LOGIN_DATE = DATE_ONLY LOGINS = 1 END END ! ! This shouldn't happen. ! IF N > 1 PRINT "Error with login history, N = ", N, USERNAME, ACCOUNT ! END END_PROCEDURE DELETE LOGIN_HISTORY_GRAPH; REDEFINE PROCEDURE LOGIN_HISTORY_GRAPH ! ! This procedure reads a login history and creates a graph ! of the days each user logged in. ! ! B. Z. Lederman ! READY LOGIN_HISTORY_BAR REPORT LOGIN_HISTORY_BAR SORTED BY ACCOUNT, USERNAME ON *."File or TT" SET COLUMNS_PAGE = 80 SET REPORT_NAME = "Login History" SET NO DATE AT TOP OF PAGE PRINT REPORT_HEADER, COL 5, MONTH VIA MONTH_NAMES(-), SPACE 1, YEAR (-), SKIP, COL 17, " 1 1 2 2 3", SKIP, COL 17, " 5 0 5 0 5 0" ! AT TOP OF ACCOUNT PRINT COL 9, ACCOUNT(-), COL 17, " + | + | + |" ! PRINT COL 1, USERNAME, COL 17, BAR ! AT BOTTOM OF PAGE PRINT COL 17, " 1 1 2 2 3", SKIP, COL 17, " 5 0 5 0 5 0" END_REPORT END_PROCEDURE DELETE LOGIN_HISTORY_RECORD; REDEFINE RECORD LOGIN_HISTORY_RECORD !! OPTIMIZE ! ! This record tracks the login history of a user. There should be ! one record for each user/account per day logged in. ! ! B. Z. Lederman ! 01 LOGIN_HISTORY_REC. 10 USERNAME PIC X(16) QUERY_HEADER "User Name". 10 ACCOUNT PIC X(8) QUERY_HEADER "Account". 10 LOGIN_DATE USAGE DATE. 10 LOGINS PIC 99 EDIT_STRING Z9 QUERY_HEADER "Times"/"Logged"/"In". ; DELETE LOGIN_HISTORY_STRING; REDEFINE DOMAIN LOGIN_HISTORY_STRING USING LOGIN_HISTORY_STRING_RECORD ON LOGIN_HISTORY_BAR.SEQ; DELETE LOGIN_HISTORY_STRING_RECORD; REDEFINE RECORD LOGIN_HISTORY_STRING_RECORD !! OPTIMIZE ! ! This gives an alternate access to the login history graph record ! so that the individual days can be filled in. ! ! B. Z. Lederman ! 01 LOGIN_HISTORY_STRING_REC. 10 USERNAME PIC X(16). 10 ACCOUNT PIC X(8). 10 MONTH PIC 99. 10 YEAR PIC 9999. 10 STRING OCCURS 31 TIMES. 20 CHAR PIC XX. 20 NUMBERS REDEFINES CHAR. 30 FILLER PIC X. 30 NUM PIC 9. ; DELETE MAKE_LOGIN_HISTORY_GRAPH; REDEFINE PROCEDURE MAKE_LOGIN_HISTORY_GRAPH ! ! Plot login history for a month. ! ! B. Z. Lederman 25-Jan-1988 ! ! 26-Jan-1988 Expand to two characters per day. ! READY LOGIN_HISTORY DECLARE BLANK PIC X(62). DECLARE INC PIC 999. DECLARE TMP PIC 999. DECLARE TDAY PIC 99. DECLARE TMONTH PIC 99. DECLARE TYEAR PIC 9999. ! ! Fill in the plot pattern. ! BLANK = " + | + | + | " INC = 1 ! ! Prompt the user for the desired month and year ! TMONTH = *."Month (numeric)" TYEAR = *."Year (4 digits)" ! ! The following is a fast way to make a new empty file, if you ! remember to purge old files. ! DEFINE FILE FOR LOGIN_HISTORY_BAR KEY = USERNAME (DUP), KEY = ACCOUNT(DUP); ! ! FN$DCL("SPAWN/NOWAIT PURGE/NOLOG LOGIN_HISTORY_BAR.SEQ") ! READY LOGIN_HISTORY_BAR WRITE READY LOGIN_HISTORY_STRING MODIFY ! FOR LOGIN_HISTORY WITH ! get the correct data FN$MONTH(LOGIN_DATE) = TMONTH AND FN$YEAR(LOGIN_DATE) = TYEAR BEGIN ! ! Find out if there is a plot record for this person/account already. ! TMP = 0 FOR LOGIN_HISTORY_BAR WITH USERNAME = LOGIN_HISTORY_REC.USERNAME AND ACCOUNT = LOGIN_HISTORY_REC.ACCOUNT BEGIN TMP = TMP + 1 END ! IF TMP = 0 STORE LOGIN_HISTORY_BAR USING BEGIN ! no record, must create one USERNAME = USERNAME ACCOUNT = ACCOUNT MONTH = TMONTH YEAR = TYEAR BAR = BLANK ! Put in a "blank" line. END TDAY = FN$DAY(LOGIN_DATE) ! ! Retrieve the corresponding user/account record ! FOR LOGIN_HISTORY_STRING WITH USERNAME = LOGIN_HISTORY_REC.USERNAME AND ACCOUNT = LOGIN_HISTORY_REC.ACCOUNT BEGIN TMP = INC ! start at beginning of line ! ! Now move along the string and mark of the current day ! FOR STRING MODIFY USING BEGIN IF TMP = TDAY CHOICE OF ! if correct day LOGINS GT 9 THEN CHAR = " *" ! too many logins LOGINS BETWEEN 1, 9 THEN NUM = LOGINS ! number of logins END_CHOICE TMP = TMP + INC ! increment to next day END END END FINISH LOGIN_HISTORY_BAR FINISH LOGIN_HISTORY_STRING END_PROCEDURE DELETE MOD; REDEFINE DOMAIN MOD USING MOD_RECORD ON SYS$SYSROOT:[SYSMGR.LEDERMAN]MOD.DOM; DELETE MOD_ERLANG_REPORT; REDEFINE PROCEDURE MOD_ERLANG_REPORT ! ! Totalize the amount of time busy during each clock hour, and ! report. ! ! B. Z. Lederman 11-Sep-1987 ! READY MOD REPORT MOD ON *."TT or file name" SET REPORT_NAME = "Hourly Traffic Summary" AT BOTTOM OF H_OF_D PRINT H_OF_D("Hour"), SPACE 2, FORMAT(TOTAL(TIME_BUSY) / 60) USING Z,ZZ9.99 ("Erlangs"), SPACE 2, MAX(NUMBER_BUSY) ("Maximum"/"Number"/"of"/"Users") END_REPORT END_PROCEDURE DELETE MOD_FROM_ACC; REDEFINE PROCEDURE MOD_FROM_ACC ! ! Calculate traffic statistics from Accounting Records. ! ! This procedure marks the minutes of the day when a terminal line ! was in use. ! Also get a count of how many users there were on the system ! at any given moment (not of much use, but some people like ! to look at it). ! ! B. Z. Lederman 11-Sep-1987 ! 28-Jan-1988 Add consideration for partial midnights ! READY ACC DECLARE SMOD USAGE INTEGER. DECLARE M_FLAG USAGE INTEGER. ! flag used over midnight ! ! We have to clear out any old data: this can be slow. ! READY MOD MODIFY FOR MOD MODIFY USING BEGIN TIME_BUSY = 0 NUMBER_BUSY = 0 END ! ! If FN$DCL is available, there is a MUCH faster way to create an empty file. ! !FN$DCL("CONVERT/FDL=MOD MOD.SEQ MOD.DOM") !FN$DCL("PURGE/NOLOG MOD.DOM") !READY MOD MODIFY ! ! Read the accounting data (use only those records that are relevant: ! in this case, only "real" terminals, not DECnet remote terminals, ! and not Batch jobs, etc. ! ! For DECUServe, the selection criteria may be by account or group ! rather than terminal type. ! FOR ACC WITH PACKET = "Interactive" AND TERMINAL STARTING "VT","LT" BEGIN ! ! Get the time the session started. ! SMOD = START_MOD ! ! Must guard against people who were logged in over midnight (?) ! (sometime in the future) ! ! M_FLAG = 0 ! IF END_MOD < START_MOD BEGIN ! SMOD = 0 ! M_FLAG = 1 ! END ! ! For each minute this session was busy add: ! 1 minute of use for each full minute, ! or the fraction of the minute occupied in the first or last minute ! WHILE SMOD LE END_MOD BEGIN FOR MOD WITH M_OF_D = SMOD MODIFY USING BEGIN IF SMOD = START_MOD BEGIN ! starting portion TIME_BUSY = TIME_BUSY + (1 - (FN$SECOND(START_DATE) / 60)) END ELSE IF SMOD = END_MOD BEGIN ! end portion of time TIME_BUSY = TIME_BUSY + (FN$SECOND(SYSTEM_DATE) / 60) END ELSE BEGIN TIME_BUSY = TIME_BUSY + 1 ! one full minute END NUMBER_BUSY = NUMBER_BUSY + 1 END SMOD = SMOD + 1 END END END_PROCEDURE DELETE MOD_RECORD; REDEFINE RECORD MOD_RECORD !! OPTIMIZE 01 MOD_REC. ! ! Define one record for each minute of the day for processing ! traffic data. ! ! B. Z. Lederman 11-Sep-1987 ! 10 M_OF_D USAGE INTEGER EDIT_STRING ZZZ9 QUERY_HEADER "Minute"/"of"/"Day". 10 H_OF_D USAGE INTEGER EDIT_STRING Z9 QUERY_HEADER "Hour"/"of"/"Day". 10 NUMBER_BUSY USAGE INTEGER EDIT_STRING Z,ZZ9. 10 TIME_BUSY USAGE REAL EDIT_STRING Z,ZZ9.99. ; DELETE MOD_SEQ; REDEFINE DOMAIN MOD_SEQ USING MOD_RECORD ON ! ! Used for fast reload of MOD if FN$DCL is present ! SYS$SYSROOT:[SYSMGR.LEDERMAN]MOD.SEQ; DELETE MONTH_NAMES; REDEFINE TABLE MONTH_NAMES ! ! Used to convert numeric months in some reports to month names ! ! B. Z. Lederman ! QUERY_HEADER IS "Month" 1 : "January", 2 : "February", 3 : "March", 4 : "April", 5 : "May", 6 : "June", 7 : "July", 8 : "August", 9 : "September", 10 : "October", 11 : "November", 12 : "December" ELSE "Undefined" END_TABLE DELETE NEW_LOGIN_HISTORY_FILE; REDEFINE PROCEDURE NEW_LOGIN_HISTORY_FILE ! ! Just so I can remember which fields are keyed. There should also ! be an FDL file somewhere. ! ! B. Z. Lederman ! DEFINE FILE FOR LOGIN_HISTORY KEY=USERNAME(DUP), KEY=LOGIN_DATE(DUP); END_PROCEDURE DELETE REPORT_LAST_LOGIN; REDEFINE PROCEDURE REPORT_LAST_LOGIN ! ! Quick report of who logged in when. ! ! B. Z. Lederman ! READY SYSUAF REPORT SYSUAF WITH USERNAME NOT CONT "System+Password" SORTED BY ACCOUNT, USERNAME ON *."Filename or TT" SET REPORT_NAME = "Date of Last Login" PRINT ACCOUNT, USERNAME USING T(20), DATE_LAST_INTERACTIVE_LOGIN, DIRECTORY USING T(24) AT BOTTOM OF ACCOUNT PRINT SKIP 1 END_REPORT END_PROCEDURE DELETE REPORT_USER_SESSIONS; REDEFINE PROCEDURE REPORT_USER_SESSIONS ! ! Report the number of user interactive sessions, and the amount ! of time spent (in total). ! ! B. Z. Lederman 20-Jan-1988 ! READY ACC ! ! The *."File or TT" can be replaced with a fixed file name. ! REPORT ACC WITH PACKET = "Interactive" SORTED BY ACCOUNT, USERNAME ON *."File or TT" ! SET REPORT_NAME = "Interactive"/"User"/"Sessions" ! AT BOTTOM OF USERNAME PRINT ACCOUNT, USERNAME, COUNT ("Number"/"of"/"Sessions"), TOTAL(ELAPSED_MINUTES) USING ZZZ,ZZ9 ! AT BOTTOM OF ACCOUNT PRINT SKIP ! END_REPORT END_PROCEDURE DELETE REPORT_USER_SESSION_DETAILS; REDEFINE PROCEDURE REPORT_USER_SESSION_DETAILS ! ! Report the number of user interactive sessions, and the amount ! of time spent (in detail). ! ! B. Z. Lederman 20-Jan-1988 ! READY ACC ! ! A fixed file name may replace the *."File or TT" prompt ! REPORT ACC WITH PACKET = "Interactive" SORTED BY ACCOUNT, USERNAME ON *."File or TT" ! PRINT ACCOUNT, USERNAME, ELAPSED_MINUTES ! AT BOTTOM OF USERNAME PRINT SKIP, "Totals", TOTAL(ELAPSED_MINUTES) USING ZZZ,ZZ9, COUNT ("Number"/"of"/"Sessions"), SKIP AT BOTTOM OF ACCOUNT PRINT SKIP END_REPORT END_PROCEDURE DELETE SYSUAF; REDEFINE DOMAIN SYSUAF USING SYSUAF_RECORD ON SYS$SYSTEM:SYSUAF.DAT; DELETE SYSUAF_RECORD; REDEFINE RECORD SYSUAF_RECORD USING !! OPTIMIZE ! ! The SYSUAF.DAT file. Has user accounts, etc. Normally accessed through ! AUTHORIZE, but if done read-only interesting data may be obtained. ! ! The user must have the proper privileges to access SYSUAF.DAT ! ! B. Z. Lederman ! 01 SYSUAF. 10 FILLER PIC X(4). 10 USERNAME PIC X(32). 10 UIC_WORDS. 20 MEMBER USAGE WORD. 20 GROUP USAGE WORD. 10 FILLER PIC X(12). 10 ACCOUNT PIC X(8). 10 FILLER PIC X(24). 10 OWNER_FIELD_LENGTH USAGE BYTE. 10 OWNER PIC X(31). 10 DEVICE_FIELD_LENGTH USAGE BYTE. 10 DEVICE PIC X(31). 10 DIRECTORY_FIELD_LENGTH USAGE BYTE. 10 DIRECTORY PIC X(63). 10 LGICMD_FIELD_LENGTH USAGE BYTE. 10 LGICMD PIC X(63). 10 CLI_FIELD_LENGTH USAGE BYTE. 10 CLI PIC X(31). 10 TABLES_FIELD_LENGTH USAGE BYTE. 10 TABLES PIC X(31). 10 PASSWORD_STUFF. 20 PASSWORD_DEPENDENT USAGE QUAD. 20 FILLER USAGE QUAD. 20 LOGFAILS USAGE WORD. 20 FILLER PIC X(4). 20 PWDMINIMUM USAGE BYTE. 20 FILLER USAGE BYTE. 20 EXPIRATION USAGE DATE. 20 TIME_EXPIRATION COMPUTED BY FN$TIME(EXPIRATION) EDIT_STRING X(11). 20 FILLER PIC X(8). 20 PWDCHANGE USAGE DATE. 20 FILLER PIC X(8). 10 LOGIN_DATES. 20 DATE_LAST_INTERACTIVE_LOGIN USAGE DATE QUERY_NAME IS DLIL. 20 TIME_LAST_INTERACTIVE_LOGIN COMPUTED BY FN$TIME(DLIL) EDIT_STRING X(11). 20 DATE_LAST_NONINTERACTIVE_LOGIN USAGE DATE QUERY_NAME IS DLNL. 20 TIME_LAST_NONINTERACTIVE_LOGIN COMPUTED BY FN$TIME(DLNL) EDIT_STRING X(11). 10 AUTHORIZE_PRIV_QUADWORD USAGE QUAD. 10 DEFAULT_PRIV_QUADWORD USAGE QUAD. 10 FILLER PIC X(40). 10 LOGIN_FLAGS_WORD USAGE WORD. 10 FILLER PIC X(2). 10 ACCESS_DAYS. 20 NETWORK_ACCESS_BYTES OCCURS 6 TIMES. 30 NETWORK_ACCESS_BYTE USAGE BYTE. 20 BATCH_ACCESS_BYTES OCCURS 6 TIMES. 30 BATCH_ACCESS_BYTE USAGE BYTE. 20 LOCAL_ACCESS_BYTES OCCURS 6 TIMES. 30 LOCAL_ACCESS_BYTE USAGE BYTE. 20 DIALUP_ACCESS_BYTES OCCURS 6 TIMES. 30 DIALUP_ACCESS_BYTE USAGE BYTE. 20 REMOTE_ACCESS_BYTES OCCURS 6 TIMES. 30 REMOTE_ACCESS_BYTE USAGE BYTE. 20 FILLER PIC X(12). 20 PRIME_DAYS_BITS USAGE BYTE. 20 FILLER USAGE BYTE. 10 QUOTAS. 20 PRIO USAGE BYTE. 20 QUEPRIO USAGE BYTE. 20 MAXJOBS USAGE WORD. 20 MAXACCTJOBS USAGE WORD. 20 MAXDETACH USAGE WORD. 20 PRCLM USAGE WORD. 20 DIOLM USAGE WORD. 20 BIOLM USAGE WORD. 20 TQELM USAGE WORD. 20 ASTLM USAGE WORD. 20 ENQLM USAGE WORD. 20 FILLM USAGE WORD. 20 SHRFILLM USAGE WORD. 20 WSQUO USAGE LONG. 20 WSDEF USAGE LONG. 20 WSEXT USAGE LONG. 20 PGFLQUO USAGE LONG. 20 CPU USAGE LONG. 20 BYTLM USAGE LONG. 20 PBYTLM USAGE LONG. 20 JTQUO USAGE LONG. 10 FILLER PIC X(844). ! a LOT of unused space! ; DELETE T132; REDEFINE PROCEDURE T132 SET COLUMNS_PAGE=132 FN$WIDTH(132) ![?3h END_PROCEDURE DELETE T80; REDEFINE PROCEDURE T80 SET COLUMNS_PAGE=80 FN$WIDTH(80) ![?3l END_PROCEDURE