.TITLE MONFORM VMS Monitor to Mongo reformatter .SUBTITLE RMS_STRUCTURES - FABs and RABs and such TERM_FAB: $FAB - FAC=,- FNM=,- MRS=255,- ORG=SEQ,- RAT=CR,- RFM=STM,- SHR= TERM_RAB: $RAB - FAB=TERM_FAB,- RAC=SEQ,- ROP= ; ; IN_FAB: $FAB - DNM=,- FAC=,- FOP=,- MRS=255,- ORG=SEQ,- SHR= IN_RAB: $RAB - FAB=IN_FAB,- RAC=SEQ,- ROP= ; ; OUT_FAB: $FAB - DNM=,- FAC=,- FOP=,- RAT=CR,- MRS=255,- ORG=SEQ,- SHR= OUT_RAB: $RAB - FAB=OUT_FAB,- RAC=SEQ,- ROP= ; ; .SUBTITLE PROMPTS , descriptors, and stuff like that .PAGE ; ; ; IN_P1_DESC: .ASCID /INFILE/ IN_P2_DESC: .ASCID /OUTFILE/ IN_P3_DESC: .ASCID /COLUMN/ IN_NODE_DESC: .ASCID /NODE/ ; ; HEADER_LINE_DESC: .ASCID "VAX/VMS Monitor Utility" MULTI_FILE_HEADER: .ASCID "MULTI-FILE SUMMARY" ; DATE_LINE_DESC: .ASCID /To:/ NON_BLANK_DESC: .ASCID /./ TIME_SEARCH_DESC: .ASCID /:/ NODE_LINE_DESC: .ASCID /Node:/ BLANKS: .BYTE ^X20[20] NO_DATA_VALUE: ;123456789 dummy info marks records without node name .ASCII /000000.00/ CONV_DESC: .LONG 8 .ADDRESS NO_DATA_BLOCK NO_DATA_MSG: .ASCII / No data for node / NO_DATA_NODE: .ASCII /XXXXXX in segment / NO_DATA_BLOCK: .ASCII / / NO_DATA_MSG_LEN=.-NO_DATA_MSG ; ; ; .PAGE ; ; ; HEADER_CONTROL: .LONG HEADER_CONTROL_LEN .ADDRESS HEADER_CONTROL_STRING HEADER_CONTROL_STRING: .ASCII /!AD / ; blanks where date will be .ASCII /!AD / ; 1 .ASCII /!AD / ; 2 .ASCII /!AD / ; 3 .ASCII /!AD / ; 4 .ASCII /!AD / ; 5 .ASCII /!AD / ; 6 .ASCII /!AD / ; 7 .ASCII /!AD / ; 8 data for header .ASCII /!AD / ; 9 .ASCII /!AD / ; 10 .ASCII /!AD / ; 11 .ASCII /!AD / ; 12 .ASCII /!AD / ; 13 .ASCII /!AD / ; 14 .ASCII /!AD / ; 15 HEADER_CONTROL_LEN=.-HEADER_CONTROL_STRING ; ; ; DATA_CONTROL: .LONG DATA_CONTROL_LEN .ADDRESS DATA_CONTROL_STRING DATA_CONTROL_STRING: .ASCII /!AD / ; date .ASCII /!AD / ; 1 .ASCII /!AD / ; 2 .ASCII /!AD / ; 3 .ASCII /!AD / ; 4 .ASCII /!AD / ; 5 .ASCII /!AD / ; 6 .ASCII /!AD / ; 7 .ASCII /!AD / ; 8 data .ASCII /!AD / ; 9 .ASCII /!AD / ; 10 .ASCII /!AD / ; 11 .ASCII /!AD / ; 12 .ASCII /!AD / ; 13 .ASCII /!AD / ; 14 .ASCII /!AD / ; 15 DATA_CONTROL_LEN=.-DATA_CONTROL_STRING ; ; ; .SUBTITLE BUFFERS for I/O and related (e.g. size) info .PAGE ; ; ; IN_BUF_DESC: .LONG IN_BUF_SIZE .ADDRESS IN_BUF IN_BUF: ; gee, a reusable buffer IN_FILE_NAME_BUFFER: .BLKB 255 IN_FILE_NAME_BUFFER_SIZE=.-IN_FILE_NAME_BUFFER IN_BUF_SIZE=.-IN_BUF IN_FILE_NAME_SIZE: .BLKW 1 ; OUT_BUF_DESC: .LONG OUT_BUF_SIZE .ADDRESS OUT_BUF OUT_BUF: OUT_FILE_NAME_BUFFER: .BLKB 255 OUT_FILE_NAME_BUFFER_SIZE=.-OUT_FILE_NAME_BUFFER OUT_BUF_SIZE=.-OUT_BUF OUT_FILE_NAME_SIZE: .BLKW 1 P3_BUF_DESC: .ASCID / / ; ten spaces... P3_SIZE_VALUE: .BLKL 1 NODE_BUF_DESC: .ASCID / / ; six spaces... NODE_SEARCH_DESC: .BLKQ 1 ; ; ; .SUBTITLE WORKING_SPACE where thing get moved around a lot .PAGE ; ; ; LAST_REAL_STATUS: .BLKL 1 HEADER_PRINTED: .BLKL 1 MULTI_FILE: .BLKL 1 NODE_SPECIFIED: .BLKL 1 NO_DATA: .BLKL 1 BLOCK_COUNT: .BLKL 1 MONITOR_DATE: .BLKB 20 MONITOR_DATA: .BLKB 300 ; (10 char name + 10 char value) * 15 lines. DATA_PARAM_LIST: .BLKL 32 ; (2 longword * 15 lines) + date HEADER_PARAM_LIST: .BLKL 32 ; (2 longword * 15 lines) + blanks START_POS: .BLKL 1 ; result of R0 + MATCHC value plus size from header ; ; ; .SUBTITLE MONFORM mainline .PAGE ; ; ; ; ; .ENTRY MONFORM,^M CLRL BLOCK_COUNT CLRL HEADER_PRINTED CLRL MULTI_FILE CLRL LAST_REAL_STATUS JSB GET_PARAMS BLBS R0,10$ $EXIT_S R0 10$: JSB OPEN_DATA_FILES BLBS R0,20$ $EXIT_S R0 20$: INCL BLOCK_COUNT JSB READ_MONITOR_HEADER BLBS R0,30$ CMPL #RMS$_EOF,R0 BEQL 90$ $EXIT_S R0 30$: JSB LOAD_MONITOR_DATA BLBS R0,40$ $EXIT_S R0 40$: TSTL HEADER_PRINTED BNEQ 50$ INCL HEADER_PRINTED ; so we only print header once JSB WRITE_HEADER_REC BLBS R0,50$ $EXIT_S R0 50$: JSB WRITE_DATA_REC BLBS R0,60$ $EXIT_S R0 60$: CMPL #RMS$_EOF,LAST_REAL_STATUS BNEQ 20$ ; if more in file, try to read it. ; 90$: JSB CLOSE_DATA_FILES RET ; ; ; .SUBTITLE GET_PARAMS - Open terminal and get filename .PAGE ; ; ; GET_PARAMS: $OPEN FAB=TERM_FAB BLBS R0,10$ RSB 10$: $CONNECT RAB=TERM_RAB BLBS R0,20$ RSB 20$: PUSHAW IN_FILE_NAME_SIZE PUSHAQ IN_BUF_DESC PUSHAQ IN_P1_DESC CALLS #3,G^CLI$GET_VALUE BLBS R0,30$ RSB 30$: PUSHAW OUT_FILE_NAME_SIZE PUSHAQ OUT_BUF_DESC PUSHAQ IN_P2_DESC CALLS #3,G^CLI$GET_VALUE BLBS R0,40$ RSB 40$: PUSHAQ IN_P3_DESC CALLS #1,G^CLI$PRESENT CMPL #CLI$_PRESENT,R0 BEQL 45$ MOVL #7,P3_SIZE_VALUE MOVL P3_BUF_DESC+4,R0 MOVL #^A/AVER/,(R0) MOVL #^A/AGE /,4(R0) BRB 50$ 45$: PUSHAW P3_SIZE_VALUE PUSHAQ P3_BUF_DESC PUSHAQ IN_P3_DESC CALLS #3,G^CLI$GET_VALUE BLBS R0,50$ RSB 50$: MOVL P3_SIZE_VALUE,P3_BUF_DESC ; CLRL NODE_SPECIFIED PUSHAQ IN_NODE_DESC CALLS #1,G^CLI$PRESENT CMPL #CLI$_PRESENT,R0 BEQL 55$ MOVL #SS$_NORMAL,R0 BRB 60$ 55$: INCL NODE_SPECIFIED PUSHAW NODE_BUF_DESC PUSHAQ NODE_BUF_DESC PUSHAQ IN_NODE_DESC CALLS #3,G^CLI$GET_VALUE BLBS R0,60$ RSB 60$: RSB ; to mainline with status from get_value ; ; ; .SUBTITLE OPEN_DATA_FILES - Open the files we were just given .PAGE ; ; ; OPEN_DATA_FILES: MOVAB IN_FILE_NAME_BUFFER,IN_FAB+FAB$L_FNA MOVB IN_FILE_NAME_SIZE,IN_FAB+FAB$B_FNS $OPEN FAB=IN_FAB BLBS R0,10$ RSB 10$: $CONNECT RAB=IN_RAB BLBS R0,20$ RSB 20$: MOVAB OUT_FILE_NAME_BUFFER,OUT_FAB+FAB$L_FNA MOVB OUT_FILE_NAME_SIZE,OUT_FAB+FAB$B_FNS $CREATE FAB=OUT_FAB BLBS R0,30$ RSB 30$: $CONNECT RAB=OUT_RAB RSB ; with status of connect ; ; ; .SUBTITLE CLOSE_DATA_FILES - Close files when we finish. .PAGE ; ; ; CLOSE_DATA_FILES: $CLOSE IN_FAB $CLOSE OUT_FAB RSB ; nice to ignore status for a change ; ; ; .SUBTITLE READ_MONITOR_HEADER - Locate and read header from input file .PAGE ; ; ; READ_MONITOR_HEADER: 1$: MOVZWL IN_RAB+RAB$W_RSZ,IN_BUF_DESC BNEQ 30$ BRW 40$ 30$: PUSHAQ IN_BUF_DESC PUSHAQ HEADER_LINE_DESC CALLS #2,G^LIB$MATCHC TSTW R0 BNEQ 90$ BRW 40$ 40$: ; ; header is not in this line - get next line ; MOVAL IN_BUF,IN_RAB+RAB$L_UBF MOVW #IN_BUF_SIZE,IN_RAB+RAB$W_USZ 10$: $GET RAB=IN_RAB BLBS R0,20$ RSB ; either error or EOF ==> not a .SUM file 20$: BRW 1$ 90$: ; ; header has been located - get date and read past ; TSTL NODE_SPECIFIED BEQL 900$ BRW 700$ .PAGE ; ; ; 900$: ; ; type of monitor line -;- skip it ; $GET RAB=IN_RAB BLBS R0,910$ RSB 910$: ; From: line, skip this too. ; $GET RAB=IN_RAB BLBS R0,915$ RSB 915$: ; ; this line should have "To: {date}" on it ; $GET RAB=IN_RAB BLBS R0,920$ RSB 920$: MOVZWL IN_RAB+RAB$W_RSZ,IN_BUF_DESC BNEQ 930$ BRW 932$ ; TRY CHECKING LAST LINE FOR SUMMARY 930$: PUSHAQ IN_BUF_DESC PUSHAQ DATE_LINE_DESC CALLS #2,G^LIB$MATCHC TSTW R0 BNEQ 940$ 932$: MOVZBL #132,IN_BUF_DESC ; bogus up the size PUSHAQ IN_BUF_DESC PUSHAQ MULTI_FILE_HEADER CALLS #2,G^LIB$MATCHC TSTW R0 BEQL 935$ BRW 810$ 935$: MOVL #RMS$_RNF,R0 ; again, not the record we expected RSB 940$: ; ; definitely the record we expected - extract the date field ; MOVAL IN_BUF,R6 ADDL2 #5,R0 ; point past from ADDL2 R0,R6 ; within the record... MOVC3 #20,(R6),MONITOR_DATE ; ; now read past other header lines ; 950$: $GET RAB=IN_RAB BLBS R0,960$ RSB 960$: $GET RAB=IN_RAB BLBS R0,965$ RSB 965$: MOVZWL IN_RAB+RAB$W_RSZ,IN_BUF_DESC BNEQ 970$ MOVL #RMS$_RNF,R0 RSB 970$: PUSHAQ IN_BUF_DESC PUSHAQ P3_BUF_DESC CALLS #2,G^LIB$MATCHC TSTW R0 BNEQ 980$ MOVL #RMS$_RNF,R0 RSB 980$: MOVAB IN_BUF,R1 ADDL3 R1,R0,START_POS MOVL P3_BUF_DESC,R2 ADDL3 R2,#-11,R1 ADDL2 R1,START_POS 990$: MOVL #SS$_NORMAL,R0 ; now pointing to first data line RSB ; return ; .PAGE ; ; ; 810$: ; ; suddenly we find ourselves working on a multifile summary... ; INCL MULTI_FILE ; so indicate ; ; the header record containing the "To:" is four more records down. ; MOVZBL #4,R6 820$: $GET RAB=IN_RAB BLBS R0,830$ RSB 830$: SOBGTR R6,820$ ; ; we should have the record we want now - look for a "To:" ; MOVZWL IN_RAB+RAB$W_RSZ,IN_BUF_DESC PUSHAQ IN_BUF_DESC PUSHAQ DATE_LINE_DESC CALLS #2,G^LIB$MATCHC TSTW R0 BNEQ 840$ MOVL #RMS$_RNF,R0 ; again, not the record we expected RSB 840$: ; ; definitely the record we expected - extract the date field ; MOVAB IN_BUF,R6 ADDL2 #5,R0 ; point past from ADDL2 R0,R6 ; within the record... MOVC5 #18,(R6),#^A/ /,#20,MONITOR_DATE ; ; now locate the column we want, which is on the same line. How nice. ; MOVZWL IN_RAB+RAB$W_RSZ,R0 MOVL R0,IN_BUF_DESC MOVL R0,OUT_BUF_DESC MOVC3 R0,IN_BUF,OUT_BUF PUSHAQ IN_BUF_DESC PUSHAQ OUT_BUF_DESC CALLS #2,G^STR$UPCASE BLBS R0,860$ RSB 860$: PUSHAQ OUT_BUF_DESC PUSHAQ P3_BUF_DESC CALLS #2,G^LIB$MATCHC TSTW R0 BNEQ 870$ MOVL #RMS$_RNF,R0 ; not what we wanted to see RSB 870$: MOVAB IN_BUF,R1 ADDL3 R1,R0,START_POS ; now points to start of string ; figure out how far to back up.... MOVL P3_BUF_DESC,R2 ADDL3 R2,#-9,R1 ADDL2 R1,START_POS 890$: MOVL #SS$_NORMAL,R0 RSB ; all located, get out ; ; ; .PAGE 700$: ; ; working a multi-node, multi-file summary ; INCL MULTI_FILE MOVL #5,R6 705$: $GET RAB=IN_RAB ; skip three lines, locate the "Node:" line BLBC R0,709$ SOBGTR R6,705$ BRB 710$ 709$: RSB ; with status from $GET 710$: MOVZWL IN_RAB+RAB$W_RSZ,IN_BUF_DESC ; load size of buffer BNEQ 720$ MOVL #RMS$_RNF,R0 RSB 720$: PUSHAQ IN_BUF_DESC PUSHAQ NODE_LINE_DESC CALLS #2,G^LIB$MATCHC TSTL R0 BNEQ 730$ MOVL #RMS$_RNF,R0 RSB 730$: CLRL NO_DATA PUSHAQ IN_BUF_DESC PUSHAQ NODE_BUF_DESC CALLS #2,G^LIB$MATCHC TSTL R0 BNEQ 740$ BRW 600$ ; node is not on this line, go handle missing node 740$: MOVAB IN_BUF,R1 ADDL3 R0,R1,NODE_SEARCH_DESC+4 ; now points to start of node ; within IN_BUF MOVZBL #12,NODE_SEARCH_DESC $GET RAB=IN_RAB BLBS R0,750$ RSB 750$: $GET RAB=IN_RAB BLBS R0,760$ RSB 760$: MOVZWL IN_RAB+RAB$W_RSZ,IN_BUF_DESC PUSHAQ NODE_SEARCH_DESC PUSHAQ TIME_SEARCH_DESC CALLS #2,G^LIB$MATCHC TSTL R0 BNEQ 770$ MOVL #RMS$_RNF,R0 RSB 770$: ADDL2 NODE_SEARCH_DESC+4,R0 ADDL3 #-7,R0,START_POS BRW 605$ ; ; ; .PAGE ; ; ; 600$: INCL NO_DATA ; indicate this stuff is bogus. $GET RAB=IN_RAB BLBS R0,601$ RSB 601$: MOVL NODE_BUF_DESC+8,NO_DATA_NODE MOVW NODE_BUF_DESC+12,NO_DATA_NODE+4 PUSHAQ CONV_DESC PUSHAL BLOCK_COUNT CALLS #2,G^OTS$CVT_L_TU BLBS R0,604$ RSB ; with value from library routine. 604$: MOVAL NO_DATA_MSG,TERM_RAB+RAB$L_RBF MOVW #NO_DATA_MSG_LEN,TERM_RAB+RAB$W_RSZ $PUT RAB=TERM_RAB BLBS R0,610$ RSB ; with value from term put. 610$: $GET RAB=IN_RAB BLBS R0,620$ RSB 620$: MOVZWL IN_RAB+RAB$W_RSZ,IN_BUF_DESC 605$: PUSHAQ IN_BUF_DESC PUSHAQ DATE_LINE_DESC CALLS #2,G^LIB$MATCHC TSTW R0 BNEQ 630$ MOVL #RMS$_RNF,R0 RSB 630$: MOVAL IN_BUF,R6 ADDL2 #5,R0 ADDL2 R0,R6 MOVC5 #18,(R6),#^A/ /,#20,MONITOR_DATE 640$: MOVZWL #SS$_NORMAL,R0 RSB ; ; ; .SUBTITLE LOAD_MONITOR_DATA - read and store data from input file .PAGE ; ; ; LOAD_MONITOR_DATA: MOVC5 #0,(SP),#^A/ /,#300,MONITOR_DATA MOVZBL #16,R6 ; max number of records in R6 MOVAB MONITOR_DATA,R7 ; pointer to text data ADDL3 #10,R7,R8 ; pointer to value data ; 10$: $GET RAB=IN_RAB BLBS R0,20$ CMPL #RMS$_EOF,R0 BNEQ 18$ MOVL R0,LAST_REAL_STATUS ; save and MOVL #RMS$_SUC,R0 ; xlate eof to success, print what we have 18$: RSB ; eof or some other kind of error, return 20$: MOVZWL IN_RAB+RAB$W_RSZ,IN_BUF_DESC ; if zero length line BNEQ 30$ BRW 80$ ; do not process 30$: PUSHAQ IN_BUF_DESC PUSHAQ HEADER_LINE_DESC ; make sure we haven't run out of data... CALLS #2,G^LIB$MATCHC TSTW R0 BEQL 32$ BRW 90$ 32$: PUSHAQ IN_BUF_DESC ; and scan for "." PUSHAQ NON_BLANK_DESC CALLS #2,G^LIB$MATCHC TSTL R0 BNEQ 40$ BRW 80$ 40$: TSTL MULTI_FILE BNEQ 60$ MOVC3 #10,IN_BUF+4,(R7) ; move data text MOVC3 #10,@START_POS,(R8) ; move data value BRB 70$ 60$: MOVC3 #10,IN_BUF,(R7) ; move data text TSTL NO_DATA BEQL 65$ MOVC3 #9,NO_DATA_VALUE,(R8) BRB 70$ 65$: MOVC3 #9,@START_POS,(R8) ; move shorter data value 70$: ADDL2 #20,R7 ADDL2 #20,R8 80$: SOBGTR R6,85$ ; if greater, back to top of loop BRB 90$ ; else exit 85$: BRW 10$ ; helper branch 90$: MOVL #RMS$_SUC,R0 ; if loop terminated, we're done successfully RSB ; ; ; .SUBTITLE WRITE_HEADER_REC - Write a header record .PAGE ; ; ; WRITE_HEADER_REC: ; ; build the parameter list: no date for header ; MOVZBL #20,HEADER_PARAM_LIST MOVAB BLANKS,HEADER_PARAM_LIST+4 ; ;load up addresses ; MOVZBL #16,R6 MOVAL HEADER_PARAM_LIST+8,R7 MOVAB MONITOR_DATA,R8 10$: MOVZBL #10,(R7) MOVL R8,4(R7) ADDL2 #8,R7 ADDL2 #20,R8 SOBGTR R6,10$ ; ; call FAOL to format the output ; MOVZWL #255,OUT_BUF_DESC $FAOL_S - CTRSTR=HEADER_CONTROL,- OUTLEN=OUT_RAB+RAB$W_RSZ,- OUTBUF=OUT_BUF_DESC,- PRMLST=HEADER_PARAM_LIST BLBS R0,20$ RSB 20$: MOVAL OUT_BUF,OUT_RAB+RAB$L_RBF $PUT RAB=OUT_RAB RSB ; return with PUT status ; ; ; .SUBTITLE WRITE_DATA_REC - Write a DATA record .PAGE ; ; ; WRITE_DATA_REC: ; ; build the parameter list: use date for data ; MOVZBL #20,DATA_PARAM_LIST MOVAB MONITOR_DATE,DATA_PARAM_LIST+4 ; ;load up addresses ; MOVZBL #15,R6 MOVAL DATA_PARAM_LIST+8,R7 MOVAB MONITOR_DATA+10,R8 10$: MOVZBL #10,(R7) MOVL R8,4(R7) ADDL2 #8,R7 ADDL2 #20,R8 SOBGTR R6,10$ ; ; call FAOL to format the output ; MOVZWL #255,OUT_BUF_DESC $FAOL_S - CTRSTR=DATA_CONTROL,- OUTLEN=OUT_RAB+RAB$W_RSZ,- OUTBUF=OUT_BUF_DESC,- PRMLST=DATA_PARAM_LIST BLBS R0,20$ RSB 20$: MOVAL OUT_BUF,OUT_RAB+RAB$L_RBF $PUT RAB=OUT_RAB RSB ; return with PUT status .END MONFORM