.TITLE ACC_Convert - System Accounting Record Conversion. .IDENT /1.5/ ; This program converts System accounting records to fixed format for ; processing by Datatrieve (or other languages which would have a hard ; time with the "screwy" un-normalized accounting file format). ; ; B. Z. Lederman 15-Apr-1987 .ENABLE SUPPRESSION ; Macro library calls $ACRDEF ; Accounting record definitions $NAMDEF ; RMS Name Block Definitions .PSECT RWDATA, WRT, NOEXE, LONG ; RMS control blocks - these are first to make them longword aligned ; ; Input FAB ; ACC_FAB: $FAB FAC = GET, - ; Only GETs are required DNM = , - ; default file name SHR = , - ; shared FOP = SQO ; Sequential access only ; Input RAB ACC_RAB: $RAB FAB = ACC_FAB, - ; Associated FAB ROP = RAH, - ; Read ahead UBF = ACC_REC, - ; User buffer address USZ = ACC_REC_LEN ; User buffer size ; Output FAB ; ; The output file is ACCOUNTING.FIX in the current default directory OUT_FAB: $FAB FAC = PUT, - ; Access for $PUTs DNM = , - ; File name FOP = , - ; Sequential access only RAT = CR, - ; CR carriage control RFM = VAR ; Variable length records ; Output RAB OUT_RAB: $RAB FAB = OUT_FAB, - ; Associated FAB RBF = OUT_REC, - ; Output buffer RSZ = OUT_REC_LEN, - ; Record size ROP = WBH ; Write behind ; Input file name stuff ACC_FSPEC: .LONG NAM$C_MAXRSS .LONG ACC_FSPEC_BUF ACC_FSPEC_BUF: .BLKB NAM$C_MAXRSS ACC_FSPEC_LEN: .BLKW 1 ACC_FILE_QUAL: .ASCID /INPUT_FILE/ ; Output file name stuff OUT_FSPEC: .LONG NAM$C_MAXRSS .LONG OUT_FSPEC_BUF OUT_FSPEC_BUF: .BLKB NAM$C_MAXRSS OUT_FSPEC_LEN: .BLKW 1 OUT_FILE_QUAL: .ASCID /OUTPUT_FILE/ ; Accounting record buffer ACC_REC_LEN == 512 ACC_REC: .BLKB ACC_REC_LEN ; Output record buffer: ; fields are named to make moves easier and ; to make re-arraingement of fields easier. ; This version has the ID fields first, ; then (termination) fields. OUT_REC:: ; Start Record TYPE: .BLKW 1 ; packet type SYSTIME: ; end time .BLKQ 1 PID:: .BLKL 1 ; start ID packet PIDOWN: .BLKL 1 UIC: .BLKL 1 PRIV: .BLKQ 1 PRIO: .BLKB 1 USERNAME: .BLKB 12 ACCOUNT: .BLKB 8 NODE: .BLKB 6 TERMINAL: .BLKB 6 JOBNAME: .BLKB 12 JOBID: .LONG 0 QUEUE: .BLKB 32 NODEADDR: .BLKW 1 REMID: .BLKB 16 STARTIME:: ; start resource packet .BLKQ 1 ; start time STATUS: .BLKL 1 ; final status IMGCNT: .BLKL 1 ; execution count or sequence number CPUTIME: .BLKL 1 ; total CPU time FAULTS: .BLKL 1 ; Page Fault Count FAULTIO: .BLKL 1 ; Fault I/O Count WSPEAK: .BLKL 1 ; Peak Working Set PAGEFL: .BLKL 1 ; peak page file usage DIOCNT: .BLKL 1 ; Direct I/O Count BIOCNT: .BLKL 1 ; Buffered I/O Count VOLUMES: .BLKL 1 ; Volumes Mounted OUT_REC_LEN == .-OUT_REC .PSECT CODE, NOWRT, EXE, LONG ; The program opens the input and output files. ; It then loops through each record moving the fields. ; ; Any error status returned from a system service or an RMS service ; is emitted on exit, otherwise SS$_NORMAL .ENTRY ACC_BINARY, ^M<> ; See if user specified an input file PUSHAL ACC_FILE_QUAL ; is there an input (P1) parameter? CALLS #1, G^CLI$PRESENT BLBC R0, 10$ ; branch if not PUSHAL ACC_FSPEC ; get the file specification PUSHAL ACC_FILE_QUAL CALLS #2, G^CLI$GET_VALUE ; check and skip if error PUSHAL ACC_FSPEC_LEN PUSHAL ACC_FSPEC PUSHAL ACC_FSPEC CALLS #3, G^STR$TRIM ; trim off trailing blanks $FAB_STORE - ; put real name into FAB FAB = ACC_FAB, - FNA = @ACC_FSPEC+4, - ; address FNS = ACC_FSPEC_LEN ; real length 10$: ; Open accounting file $OPEN FAB = ACC_FAB BSBW ERROR $CONNECT - RAB = ACC_RAB BSBW ERROR ; See if user specified an output file PUSHAL OUT_FILE_QUAL ; is there an /OUTPUT qualifier? CALLS #1, G^CLI$PRESENT BLBC R0, 20$ ; branch if not PUSHAL OUT_FSPEC ; get the file specification PUSHAL OUT_FILE_QUAL CALLS #2, G^CLI$GET_VALUE ; check and skip if error PUSHAL OUT_FSPEC_LEN PUSHAL OUT_FSPEC PUSHAL OUT_FSPEC CALLS #3, G^STR$TRIM ; trim off trailing blanks $FAB_STORE - ; put real name into FAB FAB = OUT_FAB, - FNA = @OUT_FSPEC+4, - ; address FNS = OUT_FSPEC_LEN ; real length 20$: ; Open output file $CREATE FAB = OUT_FAB BSBW ERROR $CONNECT - RAB = OUT_RAB BSBW ERROR ; Main loop NEXT_RECORD:: $GET RAB = ACC_RAB ; Read record BLBS R0, 20$ ; If LBS - read was ok CMPL R0, #RMS$_EOF ; Is it end of file ? BNEQ 10$ ; If EQL - all done BRW FINISH 10$: BSBW ERROR ; Show the error 20$: ; Check if this is a record we want CMPZV #ACR$V_VERSION, #ACR$S_VERSION, - ACC_REC+ACR$W_TYPE, #ACR$K_VERSION3 ; Is this a format I understand ? BNEQ NEXT_RECORD ; If NE - no CMPZV #ACR$V_TYPE, #ACR$S_TYPE, - ACC_REC+ACR$W_TYPE, #ACR$K_prcdel ; Is this a process record ? BNEQ NEXT_RECORD ; If NE - no ; (may also want ACR$K_IMGDEL, image deletion) ; There are 5 subtypes: Interactive, Subprocess, Detached, Batch, ; and Network: we want all of them. ; CMPZV #ACR$V_SUBTYPE, #ACR$S_SUBTYPE, - ; ACC_REC+ACR$W_TYPE, #ACR$K_xxxx ; ; Is it a particular sub-type? ; BNEQ NEXT_RECORD ; If NE - no ; It is a termination record ; ; Find the start of the termination packet MOVZWL ACC_REC+ACR$W_LENGTH, R8 ; Length of record ADDL2 #ACC_REC, R8 ; End of the record MOVAB ACC_REC+ACR$K_HDRLEN, R7 ; Start of the first packet 30$: CMPZV #ACR$V_TYPE, #ACR$S_TYPE, - ACR$W_TYPE(R7), #ACR$K_resource ; resource packet ? BNEQ 40$ ; If NE - no, try again MOVAB (R7), R9 ; Save start of packet BRB 50$ 40$: CMPZV #ACR$V_TYPE, #ACR$S_TYPE, - ACR$W_TYPE(R7), #ACR$K_ID ; ID packet ? BNEQ 50$ ; If NE - no, try again MOVAB (R7), R10 ; Save start of ID packet 50$: MOVZWL ACR$W_LENGTH(R7), R1 ; Length of this packet ADDL2 R1, R7 ; Try next packet CMPL R7, R8 ; End of record ? BLSS 30$ ; If LS - not end of record, try again MOVAB ACC_REC, R8 ; Get start of record in register ; R8 = start address of record ; R9 = start address of resource packet ; R10 = start address of ID packet ; ; Move data from input to output area. MOVEIT:: MOVC5 #0, #0, #32, #OUT_REC_LEN, OUT_REC ; blank fill record MOVW ACR$W_TYPE(R8), TYPE ; packet type MOVQ ACR$Q_SYSTIME(R8), SYSTIME ; System (finish) time ; Start ID packet MOVL ACR$L_PID(R10), PID ; process ID MOVL ACR$L_OWNER(R10), PIDOWN ; owning process ID MOVL ACR$L_UIC(R10), UIC ; UIC MOVQ ACR$Q_PRIV(R10), PRIV ; privileges at termination MOVB ACR$B_PRI(R10), PRIO ; priority MOVZWL ACR$W_USERNAME(R10), R1 ; Offset of username (ID packet) BEQL 10$ ; if zero, field is blank ADDL2 R10, R1 ; Add base of ID packet to ; obtain address MOVZBL (R1)+, R0 ; get length of string MOVC5 R0, (R1), #32, #12, USERNAME ; move characters blank fill 10$: MOVZWL ACR$W_ACCOUNT(R10), R1 ; Offset of account BEQL 20$ ADDL2 R10, R1 ; Address of account MOVZBL (R1)+, R0 ; get length of string MOVC5 R0, (R1), #32, #8, ACCOUNT ; move characters blank fill 20$: MOVZWL ACR$W_NODENAME(R10), R1 ; Offset of nodename BEQL 30$ ADDL2 R10, R1 ; Address MOVZBL (R1)+, R0 ; get length of string MOVC5 R0, (R1), #32, #6, NODE ; move characters blank fill 30$: MOVZWL ACR$W_TERMINAL(R10), R1 ; Offset of terminal BEQL 40$ ADDL2 R10, R1 ; Address MOVZBL (R1)+, R0 ; get length of string MOVC5 R0, (R1), #32, #6, TERMINAL ; move characters blank fill 40$: MOVZWL ACR$W_JOBNAME(R10), R1 ; Offset of jobname BEQL 50$ ADDL2 R10, R1 ; Address MOVZBL (R1)+, R0 ; get length of string MOVC5 R0, (R1), #32, #12, JOBNAME ; move characters blank fill 50$: MOVL ACR$L_JOBID(R10), JOBID MOVZWL ACR$W_QUEUE(R10), R1 ; Offset of queue (always blank) BEQL 60$ ADDL2 R10, R1 ; Address MOVZBL (R1)+, R0 ; get length of string MOVC5 R0, (R1), #32, #32, QUEUE ; move characters blank fill 60$: MOVW ACR$W_NODEADDR(R10), NODEADDR ; node address MOVZWL ACR$W_REMOTEID(R10), R1 ; Offset of remote process BEQL 70$ ADDL2 R10, R1 ; Address MOVZBL (R1)+, R0 ; get length of string MOVC5 R0, (R1), #32, #16, REMID ; move characters blank fill ; Start Resource Packet 70$: MOVQ ACR$Q_LOGIN(R9), STARTIME MOVL ACR$L_STATUS(R9), STATUS MOVL ACR$L_IMGCNT(R9), IMGCNT MOVL ACR$L_CPUTIME(R9), CPUTIME MOVL ACR$L_FAULTS(R9), FAULTS MOVL ACR$L_FAULTIO(R9), FAULTIO MOVL ACR$L_WSPEAK(R9), WSPEAK MOVL ACR$L_PAGEFL(R9), PAGEFL MOVL ACR$L_DIOCNT(R9), DIOCNT MOVL ACR$L_BIOCNT(R9), BIOCNT MOVL ACR$L_VOLUMES(R9), VOLUMES ; ready to write record MOVAB OUT_REC, OUT_RAB+RAB$L_RBF ; Fill in record buffer address MOVW #OUT_REC_LEN, OUT_RAB+RAB$W_RSZ ; and size ; Output the record $PUT RAB = OUT_RAB BSBW ERROR BRW NEXT_RECORD ; get next record FINISH:: $CLOSE FAB = ACC_FAB BSBW ERROR ; Close the output file $CLOSE FAB = OUT_FAB BSBW ERROR $EXIT_S CODE = #1 ; SS$_NORMAL ; If any errors occur, the program exits with the error status ERROR:: ; Check system service status (in R0) BLBC R0, ERR ; If low bit clear then error occurred RSB ; No errors so return ERR:: $EXIT_S - ; Error occurred so exit CODE = R0 ; with status .END ACC_BINARY ; Start of main routine