$ v='f$verify(f$trnlnm("SHARE_VERIFY"))' $! $! This archive created by VMS_SHARE Version 7.2-007 22-FEB-1990 $! On 18-SEP-1991 15:12:08.87 By user GOATHUNTER (@WKUVX1.BITNET) $! $! This VMS_SHARE Written by: $! Andy Harper, Kings College London UK $! $! Acknowledgements to: $! James Gray - Original VMS_SHARE $! Michael Bednarek - Original Concept and implementation $! $!+ THIS PACKAGE DISTRIBUTED IN 3 PARTS, TO KEEP EACH PART $! BELOW 31 BLOCKS $! $! TO UNPACK THIS SHARE FILE, CONCATENATE ALL PARTS IN ORDER $! AND EXECUTE AS A COMMAND PROCEDURE ( @name ) $! $! THE FOLLOWING FILE(S) WILL BE CREATED AFTER UNPACKING: $! 1. BUILD.COM;1 $! 2. MXCLD.CLD;1 $! 3. MXSUM.MAR;1 $! 4. MX_MOD.MAR;1 $! $set="set" $set symbol/scope=(nolocal,noglobal) $f=f$parse("SHARE_TEMP","SYS$SCRATCH:.TMP_"+f$getjpi("","PID")) $e="write sys$error ""%UNPACK"", " $w="write sys$output ""%UNPACK"", " $ if f$trnlnm("SHARE_LOG") then $ w = "!" $ ve=f$getsyi("version") $ if ve-f$extract(0,1,ve) .ges. "4.4" then $ goto START $ e "-E-OLDVER, Must run at least VMS 4.4" $ v=f$verify(v) $ exit 44 $UNPACK: SUBROUTINE ! P1=filename, P2=checksum $ if f$search(P1) .eqs. "" then $ goto file_absent $ e "-W-EXISTS, File ''P1' exists. Skipped." $ delete 'f'* $ exit $file_absent: $ if f$parse(P1) .nes. "" then $ goto dirok $ dn=f$parse(P1,,,"DIRECTORY") $ w "-I-CREDIR, Creating directory ''dn'." $ create/dir 'dn' $ if $status then $ goto dirok $ e "-E-CREDIRFAIL, Unable to create ''dn'. File skipped." $ delete 'f'* $ exit $dirok: $ w "-I-PROCESS, Processing file ''P1'." $ if .not. f$verify() then $ define/user sys$output nl: $ EDIT/TPU/NOSEC/NODIS/COM=SYS$INPUT 'f'/OUT='P1' PROCEDURE Unpacker ON_ERROR ENDON_ERROR;SET(FACILITY_NAME,"UNPACK");SET( SUCCESS,OFF);SET(INFORMATIONAL,OFF);f:=GET_INFO(COMMAND_LINE,"file_name");b:= CREATE_BUFFER(f,f);p:=SPAN(" ")@r&LINE_END;POSITION(BEGINNING_OF(b)); LOOP EXITIF SEARCH(p,FORWARD)=0;POSITION(r);ERASE(r);ENDLOOP;POSITION( BEGINNING_OF(b));g:=0;LOOP EXITIF MARK(NONE)=END_OF(b);x:=ERASE_CHARACTER(1); IF g=0 THEN IF x="X" THEN MOVE_VERTICAL(1);ENDIF;IF x="V" THEN APPEND_LINE; MOVE_HORIZONTAL(-CURRENT_OFFSET);MOVE_VERTICAL(1);ENDIF;IF x="+" THEN g:=1; ERASE_LINE;ENDIF;ELSE IF x="-" THEN IF INDEX(CURRENT_LINE,"+-+-+-+-+-+-+-+")= 1 THEN g:=0;ENDIF;ENDIF;ERASE_LINE;ENDIF;ENDLOOP;t:="0123456789ABCDEF"; POSITION(BEGINNING_OF(b));LOOP r:=SEARCH("`",FORWARD);EXITIF r=0;POSITION(r); ERASE(r);x1:=INDEX(t,ERASE_CHARACTER(1))-1;x2:=INDEX(t,ERASE_CHARACTER(1))-1; COPY_TEXT(ASCII(16*x1+x2));ENDLOOP;WRITE_FILE(b,GET_INFO(COMMAND_LINE, "output_file"));ENDPROCEDURE;Unpacker;QUIT; $ delete/nolog 'f'* $ CHECKSUM 'P1' $ IF CHECKSUM$CHECKSUM .eqs. P2 THEN $ EXIT $ e "-E-CHKSMFAIL, Checksum of ''P1' failed." $ ENDSUBROUTINE $START: $ create 'f' X$ MACRO MXSUM X$ MACRO MX_MOD X$ SET COMMAND/OBJECT MXCLD X$ LINK/NOTRACE MXSUM,MX_MOD,MXCLD $ CALL UNPACK BUILD.COM;1 1880234149 $ create 'f' XMODULE HAROLD XIDENT "Genesis 05/24/91" X XDEFINE VERB MXSUM X`09PARAMETER P1, LABEL=FILE, PROMPT="_FILE: "`20 X`09`09 VALUE(REQUIRED, TYPE=FILE_NAME) X XDEFINE TYPE FILE_NAME X`09KEYWORD JNET, SYNTAX=MX_JNET X`09KEYWORD LOCAL, SYNTAX=MX_LOCAL`09 X`09KEYWORD SMTP, SYNTAX=MX_SMTP X XDEFINE SYNTAX MX_JNET X`09ROUTINE MX_JNET X`09PARAMETER P1 X`09QUALIFIER DATE, VALUE(REQUIRED,TYPE=$DATETIME) X`09QUALIFIER SINCE, VALUE(REQUIRED,TYPE=$DATETIME) X`09QUALIFIER BEFORE, VALUE(REQUIRED,TYPE=$DATETIME) X`09QUALIFIER OUTPUT, VALUE(REQUIRED,TYPE=$FILE) X XDEFINE SYNTAX MX_LOCAL X`09ROUTINE MX_LOCAL X`09PARAMETER P1 X`09QUALIFIER DATE, VALUE(REQUIRED,TYPE=$DATETIME) X`09QUALIFIER SINCE, VALUE(REQUIRED,TYPE=$DATETIME) X`09QUALIFIER BEFORE, VALUE(REQUIRED,TYPE=$DATETIME) X`09QUALIFIER OUTPUT, VALUE(REQUIRED,TYPE=$FILE) X XDEFINE SYNTAX MX_SMTP X`09ROUTINE MX_SMTP X`09PARAMETER P1 X`09QUALIFIER DATE, VALUE(REQUIRED,TYPE=$DATETIME) X`09QUALIFIER SINCE, VALUE(REQUIRED,TYPE=$DATETIME) X`09QUALIFIER BEFORE, VALUE(REQUIRED,TYPE=$DATETIME) X`09QUALIFIER OUTPUT, VALUE(REQUIRED,TYPE=$FILE) X X $ CALL UNPACK MXCLD.CLD;1 1648573063 $ create 'f' X`09.TITLE`09MXSUM X`09.IDENT`09/V2.0/ X;/////////////////////////////////////////////////////////////////////////// V//// X;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ V\\\\ X; X; X;`09Programmer:`09Harold McKee X;`09Program:`09MXSUM.MAR X;`09Language:`09Macro32 X;`09Purpose:`09Compile reports from MX log files X;`09email:`09`09HMCKEE@WKUVX1.BITNET X;`09Date:`09`0922-JUL-1991 X; X; X;`09MXSUM is a program designed to compile daily reports from log files X; `09created by the MX mail utility. Data from the three log files... X; X;`09`09`09MX_JNET_DIR:MX_JNET_ACC.DAT X;`09`09 MX_LOCAL_DIR:MX_LOCAL_ACC.DAT X;`09`09`09MX_SMTP_DIR:MX_SMTP_ACC.DAT X; X;`09is used. To run the program a CLD file called MXSUM is used. The`20 X;`09following is a list of qualifiers for MXSUM. X; X;`09/DATE`09only uses records with for date X;`09/BEFORE uses all records with date less than this date X;`09/SINCE uses all records with date greater than or equal to this date X;`09/OUTPUT redirects output from terminal (default) to file name specified X; X;`09/SINCE and /BEFORE can be used together to get a daily list of`20 X;`09mail traffic starting at the since date and ending the day before X;`09the before date. If any qualifier other than /OUTPUT is used with`20 X; `09the /DATE qualifier it is ignored and only the date qualifier is used. V`20 X;`09Sample output is shown below. X; X; MX_JNET_ACC.DAT SUMMARY V `20 X; `20 V `20 X; Date Source Total Files Total Bytes V `20 X;=========================================================================== V==== X;22-JUL-1991 DINGLEMAN 1 5004 V `20 X;22-JUL-1991 FILE_FEED-MGR 127 1409580 V `20 X;22-JUL-1991 GOATBREATH 121 1420470 V `20 X;22-JUL-1991 HANDY_DANDY 1 828 V `20 X;22-JUL-1991 LIST_MAN 2 3328 V `20 X;22-JUL-1991 ZZ_TOP 1 390 V `20 X;___________________________________________________________________________ V____ X; Totals 253 2839600 V `20 X; `20 V `20 X; X;/////////////////////////////////////////////////////////////////////////// V//// X;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ V\\\\ X X`09.PSECT`09DATA,NOEXE,LONG X; X;`09ADDQ2 X; X;`09This macro will add two quadwords and return the result in`20 X;`09standard MACRO32 format. X X`09.MACRO`09ADDQ2`09OP1,OP2 X`09ADDL2`09OP1,OP2`09`09;Add the lower longwords X`09ADWC`09OP1+4,OP2+4`09;Ad with carry the upper longwords X`09.ENDM X X;/////////////////////////////////////////////////////////////////////////// V//// X;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ V\\\\ X; X;`09SUBDTE X; X;`09This macro is used to subtract two QUAD words. For the use here`20 X;`09each quadword is the binary representation of a date, but any two X;`09quadwords would do just fine. When the macro finishes FLAG will X; `09tell which date was greater or if they are equal. If FLAG = -1, then X;`09the first quadword was greater than the second. If FLAG = 1 the`20 X;`09second was greater than the first and if FLAG = 0 the quadwords were X;`09equal. X; XFLAG:`09.BYTE`09 0 X X`09.MACRO`09SUBDTE`09DATE1,DATE2,FLAG,?L,?L1,?L2,?L3 X`09CLRB`09FLAG`09`09`09;Flag = 0 for 1 = 2 X`09MOVQ`09DATE2,TEMP_QUAD X`09SUBL2`09DATE1,DATE2`09`09;Subtract the low longword X`09SBWC`09DATE1+4,DATE2+4`09`09;Subtract the high longword X`09CMPL`09#0,DATE2+4 X`09BLSS`09L2 X`09BGTR`09L1 XL:`09CMPL`09#0,DATE2 X`09BEQL`09L3 X`09BLSS`09L2 XL1:`09MOVB`09#-1,FLAG`09`09;Flag = -1 for 1 > 2 X`09BRB`09L3 XL2:`09MOVB`09#1,FLAG`09`09`09;Flag = 1 for 1 < 2`20 XL3:`09MOVQ`09TEMP_QUAD,DATE2 X`09.ENDM`09SUBDTE`09`09`09;END MACRO X;`09 X;/////////////////////////////////////////////////////////////////////////// V//// X;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ V\\\\ X; X`09`09$RMSDEF X`09`09$FABDEF X`09`09$RABDEF X.LIBRARY`09/SYS$LIBRARY:LIB.MLB/ X X X;`09The next data section contains the file names of the three input X;`09files. The byte values before each ASCII entry show the length X;`09of the ASCII string.`20 X X XDNM_JNET:`09.ASCIC`09/MX_JNET_DIR:.DAT/`09 X XFNM_JNET:`09.ASCIC`09/MX_JNET_ACC/ X X XDNM_LOCAL:`09.ASCIC`09/MX_LOCAL_DIR:.DAT/ X XFNM_LOCAL:`09.ASCIC`09/MX_LOCAL_ACC/ X X XDNM_SMTP:`09.ASCIC /MX_SMTP_DIR:.DAT/ X XFNM_SMTP:`09.ASCIC /MX_SMTP_ACC/ X X; X;=*=*=*=*=*=*=*=*=*=*=* FILE ACCESS BLOCK FOR INPUT *=*=*=*=*=*=*=*=*=*=*=*= V*=*= X; X`09`09.ALIGN LONG XINFAB:`09$FAB`09FAC=,-`09;File access = GET only X`09`09SHR= X; X;=*=*=*=*=*=*=*=*=*=*= RECORD ACCESS BLOCK FOR INPUT *=*=*=*=*=*=*=*=*=*=*=* V=*=* X; XINRAB:`09$RAB`09FAB=, -`09;INFAB is file access block X`09`09RAC=, -`09;Record access is sequential X`09`09UBF=, -`09;Input buffer address`09`09 X `09`09USZ=<512> `09;Maximum record size X; X;=*=*=*=*=*=*=*=*=*=*=* FILE ACCESS BLOCK FOR OUTPUT *=*=*=*=*=*=*=*=*=*=*=* V=*=* X; XOUTFAB:`09$FAB`09FAC=, -`09;File access = PUT only X`09`09MRS=<512>, -`09;Maximum record size X`09`09RAT=, -`09;Carriage return format X`09`09FNM= ;Output to terminal by default X; X;=*=*=*=*=*=*=*=*=*=* RECORD ACCESS BLOCK FOR OUTPUT *=*=*=*=*=*=*=*=*=*=*=* V=*=* X; XOUTRAB:`09$RAB`09FAB=OUTFAB, -`09;OUTFAB is file access block X`09`09RAC=SEQ, -`09;Record access is sequential X`09`09RBF=OUTBUF, -`09;Record buffer address X`09`09RSZ=80 X X XINBUF:`09 `09.=.+512`09`09`09;Input Buffer XOUTBUF: `09.=.+80`09`09`09;Output Buffer X X XFAO_TOT: X`09$FAO CTRSTR=5$, - X`09 OUTBUF=BUFFER, - X`09`09P1=0, - X`09`09P2=0 X X5$:`09`09.ASCID / Totals !39* !5UL !12UL/ X XFAO_CALL: X`09$FAO`09CTRSTR=5$, - X`09`09OUTBUF=BUFFER, - X`09`09P1=0, - X`09`09P2=0, - X`09`09P3=0, - X`09`09P4=0 X X5$:`09`09.ASCID`09/!11AS !16< !AC !> !4UB !9UL/ X XBUFFER:`09`09.WORD`0980 X`09`09.BYTE DSC$K_DTYPE_T X`09`09.BYTE `09DSC$K_CLASS_S X`09`09.ADDRESS .+4 X`09`09.BYTE`0932`5B80`5D X X X;`09FOREIGN_BUFF must remain right after the CMD descriptor because X;`09of the way CLI$DCL_PARSE is called to parse out the command line. X;`09The ASSUME macro in SYS$LIBRARY:LIB.MLD is used to give a compiler X;`09error if FOREIGN_BUFF does not immediately follow the CMD descriptor. X XCMD:`09`09.WORD`09 6 X`09`09.BYTE`09 DSC$K_DTYPE_T X`09`09.BYTE DSC$K_CLASS_S X`09`09.ADDRESS .+4 X`09`09.ASCII /MXSUM / XFOREIGN_BUFF: .BLKB`09 256 X XASSUME`09 FOREIGN_BUFF EQUAL X XRESLT_DESC: `09.WORD 0 `20 X`09`09.BYTE`09 DSC$K_DTYPE_T ;Type is character X`09`09.BYTE DSC$K_CLASS_D ;Class is dynamic X`09`09.ADDRESS 0 X X; X;`09The 4 descriptors below are used with CLI$PRESENT to search for`20 X;`09qualifiers on the command line. X XDATE_DESC:`09.ASCID /DATE/ X XSINCE_DESC:`09.ASCID`09 /SINCE/ X XBEFORE_DESC:`09.ASCID`09 /BEFORE/ X XOUTPUT_DESC:`09.ASCID`09 /OUTPUT/ X X X;`09Dynamic descriptors used to call various routines`20 X`09 XRET_VALUE_DESC:`09.WORD`09 0 X`09`09.BYTE`09 DSC$K_DTYPE_T X`09`09.BYTE`09 DSC$K_CLASS_D X`09`09.ADDRESS 0 X XRESLT_STRING:`09.WORD`09 0 X`09`09.BYTE`09 DSC$K_DTYPE_T`20 X`09`09.BYTE`09 DSC$K_CLASS_D X`09`09.ADDRESS 0 XTEMP_DESC:`09.ASCID`09 / 00:00:00.00/ X X X X;`09The following descriptors hold the values returned from the command X;`09line. They are then used to call $BINTIM. X XSINCE_DATE:`09.WORD`09 23 X`09`09.BYTE DSC$K_DTYPE_T X`09`09.BYTE DSC$K_CLASS_D X`09`09.ADDRESS .+4 X`09`09.ASCII / 00:00:00.00/ X XDATE:`09`09.WORD`09 23 X`09`09.BYTE DSC$K_DTYPE_T X`09`09.BYTE DSC$K_CLASS_D X`09`09.ADDRESS .+4 X`09 `09.ASCII / 00:00:00.00/ X X XBEFORE_DATE:`09.WORD`09 23 X`09`09.BYTE`09 DSC$K_DTYPE_T X`09`09.BYTE`09 DSC$K_CLASS_D X`09`09.ADDRESS .+4 X`09`09.ASCII / 00:00:00.00/ X X XBUF_DATE:`09.WORD`09 23 X`09`09.BYTE DSC$K_DTYPE_T X`09`09.BYTE DSC$K_CLASS_D X`09`09.ADDRESS .+4 X `09 .ASCII`09 / 00:00:00.00/ X X XDESC_NAME1: .WORD`09 0 X`09`09.BYTE DSC$K_DTYPE_T X`09`09.BYTE`09 DSC$K_CLASS_D X`09`09.ADDRESS NAME1 XNAME1:`09`09.BLKB 16`09 `09;Holds the user name X X XDESC_NAME:`09.WORD`09 0 X`09 .BYTE DSC$K_DTYPE_T X`09`09.BYTE`09 DSC$K_CLASS_D X`09`09.ADDRESS 0 XNAME:`09`09.BLKB`09 16`09`09;Holds the user name X X XFILE_SIZE: `09.WORD`09 0`09`09 ;Descriptor used by OTS$CVT_TU_L X`09`09.BYTE`09 DSC$K_DTYPE_T ;which converts numerical values X`09`09.BYTE`09 DSC$K_CLASS_D ;in ASCII to hex. X`09`09.ADDRESS TOTAL_BYTES XTOTAL_BYTES: .BLKB`09 8`09`09 ;Numeric ASCII string X X X XSIZE_STRING:`09.ASCII`09/SENT=/`09;Denotes the begining of the size field X`09`09`09`09;used in MX_JNET_ACC.DAT & MX_SMTP_ACC.DAT X XSOURCE:`09`09.ASCII /SOURCE="`09 ;No registers saved by call X; X;/////////////////////////////////////////////////////////////////////////// V/// X;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ V\\\ X; X;`09This entry point is the one defined by the symbol that is set up X;`09to call the program from the command line. First the command line X;`09is read by LIB$GET_FOREIGN. Next, the lengths of the string from X;`09the command line and the length of the string MXSUM are added together X;`09so that a new descriptor can be set up for the call to CLI$DCL_PARSE. X;`09CLI$DCL_PARSE is called with the CLD module name HAROLD, (because X;`09I have somewhat of an eqo problem), and the newly set up descriptor X;`09CMD. Then CLI$DISPATCH is used to find the proper routine to execute. X; X;/////////////////////////////////////////////////////////////////////////// V//// X;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ V\\\\ X; X X`09PUSHAB`09RESLT_DESC X`09CALLS`09#1,G`5ELIB$GET_FOREIGN X`09ADDW2 RESLT_DESC,CMD X`09MOVC3 RESLT_DESC,@RESLT_DESC+4,FOREIGN_BUFF X PUSHAB HAROLD X`09PUSHAB CMD X`09CALLS`09#2,G`5ECLI$DCL_PARSE X`09BLBC`09R0,BOT X`09CALLS #0,CLI$DISPATCH XBOT:`09$EXIT_S X X;/////////////////////////////////////////////////////////////////////////// V//// X;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ V\\\\ X .ENTRY MX_SMTP,`5EM<> X XS_ENT:`09MOVAB`09DNM_SMTP+1,INFAB+FAB$L_DNA`09;Set up input file name X`09MOVB`09DNM_SMTP,INFAB+FAB$B_DNS`09; in FAB. X`09MOVAB`09FNM_SMTP+1,INFAB+FAB$L_FNA X`09MOVB`09FNM_SMTP,INFAB+FAB$B_FNS X`09MOVC3`09#4,SMTP,HEADER1+31 X`09BRW`09TOP X X`09.ENTRY`09MX_JNET,`5EM<>`09 X XJ_ENT:`09MOVAB`09DNM_JNET+1,INFAB+FAB$L_DNA`09;Set up input file name X`09MOVB`09DNM_JNET,INFAB+FAB$B_DNS`09; in FAB. X`09MOVAB`09FNM_JNET+1,INFAB+FAB$L_FNA X`09MOVB`09FNM_JNET,INFAB+FAB$B_FNS X XTOP:`09MOVAB`09INFAB,R3`09`09;Put input FAB address in R3`20 X`09MOVAB`09INRAB,R4`09`09;Put input RAB address in R4 X`09BSBW`09O_FILE`09`09`09;O_FILE will open the appropriate file X`09BSBW`09SET_COMMAND`09`09;Establish command line parameters. X`09SUBDTE`09SINCE_QUAD,BEFORE_QUAD,FLAG`09;Chk relationship between`20 X`09BBS`09#7,FLAG,FINISH`09`09; /BEFORE and /SINCE, if they are equal X`09BBC`09#0,FLAG,FINISH`09`09; or before is less than since then quit X`09BSBW`09PRIME_FILE`09 `09;Find the 1st match in the file X`09BLBS`09EOF,40$`09`09`09;Was EOF reached before /DATE found? X`09BSBW`09CHK_BEFORE X`09BBC`09#7,FLAG,35$`09`09;If /BEFORE is less than date in file X`09BLBC`09FLAG,35$`09`09;then end without processing the file. X`09`09`09`09`09;FLAG is set by the SUBDTE macro. X`09`09 X30$:`09BSBW`09PROCESS`09`09`09;Go process the file with given param's X35$:`09BSBW `09FINISH`09`09`09;All processing complete, go finish X40$:`09BSBW`09NO_FILES`09`09;Report no files found X XFINISH:`09$EXIT_S`09`09`09`09;Return to VMS`09 X X X X;/////////////////////////////////////////////////////////////////////////// V//// X;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ V\\\\ X X X X`09.ENTRY`09MX_LOCAL,`5EM<>`09 XTOP1:`09MOVAB`09DNM_LOCAL+1,INFAB+FAB$L_DNA`09;Set up input file name X`09MOVB`09DNM_LOCAL,INFAB+FAB$B_DNS`09; in FAB X`09MOVAB`09FNM_LOCAL+1,INFAB+FAB$L_FNA X`09MOVB`09FNM_LOCAL,INFAB+FAB$B_FNS X`09MOVAB`09INFAB,R3`09`09;Put input FAB address in R3`20 X`09MOVAB`09INRAB,R4`09`09;Put input RAB address in R4 X`09BSBW`09O_FILE`09`09`09;O_FILE will open the appropriate file X`09BSBW`09SET_COMMAND X`09SUBDTE`09SINCE_QUAD,BEFORE_QUAD,FLAG X`09BBS`09#7,FLAG,FINISH1 X`09BBC`09#0,FLAG,FINISH1 X`09BSBW`09PRIME_FILE`09 `09;Find the 1st match in the file X`09BLBS`09EOF,40$`09`09`09;Was EOF reached before /DATE found? X`09BSBW`09CHK_BEFORE`09 X`09BBC`09#7,FLAG,35$`09`09;If /BEFORE is less than date in file X`09BLBC`09FLAG,35$`09`09;then end without processing the file. X`09`09`09`09`09;FLAG is set by the SUBDTE macro. X`09 X30$:`09BSBW`09PROCESS1 X35$:`09BSBW `09FINISH1 X40$:`09BSBW`09NO_FILES`09`09;Report no files found X;///////// XFINISH1: X`09$EXIT_S`09`09`09`09;Return to VMS`09 X X X X;/////////////////////////////////////////////////////////////////////////// V//// X;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ V\\\\ X;/////////////////////////////////////////////////////////////////////////// V//// X;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ V\\\\ X XPROCESS:`09`09`09 X`09PUSHAB`09OUTPUT_DESC`09`09;Check if /OUTPUT is on the`20 X`09CALLS`09#1,G`5ECLI$PRESENT`09; command line. X`09CMPL`09R0,#CLI$_PRESENT`09;Was /OUTPUT there? X`09BNEQ`095$`09`09`09;No, then output should go to terminal X X`09PUSHAB`09RET_VALUE_DESC X`09PUSHAB`09OUTPUT_DESC X`09CALLS`09#2,G`5ECLI$GET_VALUE X MOVL`09RET_VALUE_DESC+4,OUTFAB+FAB$L_FNA X`09MOVB RET_VALUE_DESC,OUTFAB+FAB$B_FNS X X5$:`09$CREATE FAB=OUTFAB X`09$CONNECT RAB=OUTRAB X X;`09This section writes the file header to the output file. X X`09MOVAB`09HEADER1,OUTRAB+RAB$L_RBF X`09$PUT`09RAB=OUTRAB X`09MOVAB`09BLANK_LINE,OUTRAB+RAB$L_RBF X`09$PUT`09RAB=OUTRAB X`09MOVAB`09HEADER2,OUTRAB+RAB$L_RBF X`09$PUT`09RAB=OUTRAB X`09MOVAB`09LINE,OUTRAB+RAB$L_RBF X`09$PUT`09RAB=OUTRAB X`09MOVAB`09OUTBUF,OUTRAB+RAB$L_RBF X X`09MOVAB`09SOURCE,USER_SUB X`09MOVAB`09FIND_SOURCE,FIND_SUB X`09MOVAB`09SIZE_STRING,STRING_SUB X`09BSBW`09FIRST_NODE X X`09RSB X X;/////////////////////////////////////////////////////////////////////////// V//// X;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ V\\\\ X XPROCESS1:`09`09`09 X`09PUSHAB`09OUTPUT_DESC`09`09;Check if /OUTPUT is on the`20 X`09CALLS`09#1,G`5ECLI$PRESENT`09; command line. X`09CMPL`09R0,#CLI$_PRESENT`09;Was /OUTPUT there? X`09BNEQ`095$`09`09`09;No, then output should go to terminal X X`09PUSHAB`09RET_VALUE_DESC X`09PUSHAB`09OUTPUT_DESC X`09CALLS`09#2,G`5ECLI$GET_VALUE X MOVL`09RET_VALUE_DESC+4,OUTFAB+FAB$L_FNA X`09MOVB RET_VALUE_DESC,OUTFAB+FAB$B_FNS X5$:`09$CREATE FAB=OUTFAB X`09$CONNECT RAB=OUTRAB X X;`09This section writes the file header to the output file. X X`09MOVAB`09HEADER8,OUTRAB+RAB$L_RBF X`09$PUT`09RAB=OUTRAB X`09MOVAB`09BLANK_LINE,OUTRAB+RAB$L_RBF X`09$PUT`09RAB=OUTRAB X`09MOVAB`09HEADER9,OUTRAB+RAB$L_RBF X`09$PUT`09RAB=OUTRAB X`09MOVAB LINE,OUTRAB+RAB$L_RBF X`09$PUT`09RAB=OUTRAB X`09MOVAB`09OUTBUF,OUTRAB+RAB$L_RBF X X`09MOVAB`09USER,USER_SUB X`09MOVAB`09FIND_USER,FIND_SUB X`09MOVAB`09SIZE_STRING1,STRING_SUB X`09BSBW`09FIRST_NODE X`09RSB X`20 X;/////////////////////////////////////////////////////////////////////////// V//// X;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ V\\\\ X; X;`09FIRST_NODE is called by both PROCESS and PROCESS1. FIRST_NODE actually X;`09does the processing of the input file. To call FIRST_NODE three`20 X;`09parameters must be set up.`20 X; X; X;`09USER_SUB:`09Holds the address of the string used to delimit the X;`09`09`09actual username in the input file. X; X;`09FIND_SUB:`09Holds the address of the subroutine that is called to X;`09`09`09find the username in each record. X; X;`09STRING_SUB:`09Holds the address of the string used to delimit the X;`09`09`09size of the file in bytes. X; X X XFIRST_NODE: X`09MOVC3`09#11,INBUF,@BUF_DATE+4`09;Put date in descriptor X`09PUSHAB`09DATE_QUAD`09`09;Binary rep. of current date in log file X`09PUSHAB`09BUF_DATE`09`09;Descriptor for date string X`09CALLS #2,G`5ESYS$BINTIM`09`09;Convert the string to binary X`09SUBDTE BEFORE_QUAD,DATE_QUAD,FLAG ;Macro determines which is greater X`09BBS`09#7,FLAG,25$`09 ;Branch if date is not less than before X20$:`09BRW`09END_PROCESS X X25$:`09PUSHAL`09CURRENT X`09PUSHAL`09NODE_SIZE X`09CALLS`09#2,G`5ELIB$GET_VM`09`09;Get another node from memory X`09BSBW`09CLEAR_NODE`09`09;Make sure the node is blank before use X X;`09Prepare to find the source X;`09R4 = the length of the string used as the delimiter X;`09R5 = the address of the input buffer X;`09R6 = the address of the string which is used as the delimiter X XPLACE:`09MOVL`09#9,R4 X`09MOVAB`09INBUF,R5 X`09MOVL`09USER_SUB,R6 X`09JSB`09@FIND_SUB X`09CMPL`09R4,#14`09`09`09;Is the string longer than 14 chars? X`09BLEQ`0910$`09`09`09;No, then don't adjust the length. X MOVL`09#14,R4`09`09`09;Yes, force the length to be 14 X10$:`09MOVW`09R4,DESC_NAME1 `09;Store name length in descriptor`20 X`09MOVC3`09DESC_NAME1,(R8),NAME1`09;Store name in descriptor X`09PUSHAB`09DESC_NAME1`09`09;Get ready to capitalize the source. X`09PUSHAB`09DESC_NAME X`09CALLS`09#2,G`5ESTR$UPCASE`09 X`09MOVB`09DESC_NAME,5(R10)`09;Put length of name in linked list X`09MOVC3`09DESC_NAME,@DESC_NAME+4,6(R10) ;Put name in linked list. X`09ADDB2`09#1,4(R10)`09`09;Incr. num of messages by one. X`09INCL TOTAL_FILES`09`09;Incr. total num of files that day. X`09MOVC3 `09#8,BLANKS,TOTAL_BYTES`09;Blank out byte field X X;""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" V"""" X; X;`09CALL FILE_SIZE X; X;`09R5 = the address of the buffer that contains the size information X;`09R6 = the length of the string used as the size delimiter X;`09 X;`09RETURN FROM FILE_SIZE X;`09 X;`09R4 = the length of the size string X;`09R8 = the address of the first byte where the size field was found X; X;""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" V"""" X X`09MOVAB INBUF,R5 X`09MOVL`09STRING_SUB,R6 X`09BSBW`09FIND_SIZE X`09MOVW`09R4,FILE_SIZE X`09MOVC3`09FILE_SIZE,(R8),TOTAL_BYTES X`09PUSHAL CONVRT_NUM X`09PUSHAL`09FILE_SIZE X`09CALLS`09#2,G`5EOTS$CVT_TU_L X`09ADDL2`09CONVRT_NUM,20(R10) X`09ADDL2 CONVRT_NUM,TOTAL_SIZE X XLOOP: MOVC5`09#0,#0,#0,#256,INBUF X`09MOVAB`09INRAB,R3`09`09;Start going through all the records. X`09MOVAB`09OUTRAB,R5 X`09BSBW`09GET_REC X`09MOVL`09R0,STATUS X`09CMPL`09R0,#RMS$_EOF X`09BNEQ`09SPACE`09`09`09;After CLOSE_DAY end the program X`09BRW`09CLOSE_DAY`09`09 X XSPACE:`09MOVC3`09#11,INBUF,@DATE+4`09;Put date in descriptor X`09PUSHAB`09BUF_DATE_QUAD`09`09;Binary rep. of current date in log file X`09PUSHAB`09DATE`09`09`09;Descriptor for date string X`09CALLS #2,G`5ESYS$BINTIM`09`09;Convert the string to binary X X`09SUBDTE BEFORE_QUAD,BUF_DATE_QUAD,FLAG ;Are we still within our before X `09BBS`09#7,FLAG,25$`09 ;parameter?`09 X20$:`09BRW`09END_PROCESS X X25$:`09SUBDTE`09DATE_QUAD,BUF_DATE_QUAD,FLAG ;Is it still the same day? X`09CMPB`09#0,FLAG X`09BNEQ`0928$ X`09BRB`0930$ X28$:`09BRW`09CLOSE_DAY X X30$:`09MOVL`09HEAD,R10`09`09;R10 points to the head of the list. X`09MOVL`09HEAD,R9 X X`09MOVC3`09#16,BLANKS,NAME1 X`09MOVL`09#9,R4 X`09MOVAB`09INBUF,R5 X`09MOVL`09USER_SUB,R6 X`09JSB`09@FIND_SUB X`09CMPL`09R4,#14 X`09BLEQ`0940$ X MOVL`09#14,R4 X40$:`09MOVB`09R4,DESC_NAME1 X`09MOVC3`09DESC_NAME1,(R8),NAME1`09 ;Store name X`09PUSHAB`09DESC_NAME1 X`09PUSHAB`09DESC_NAME X`09CALLS`09#2,G`5ESTR$UPCASE`09 X`09MOVC3`09DESC_NAME,@DESC_NAME+4,NAME X XNODE_CHK: X`09CMPC3`09DESC_NAME,NAME,6(R10)`09;Is the user the same in this node. X`09BNEQ`095$`09 X`09BRW`09GET_BYTES`09`09;Get the size of the file. X5$:`09CMPC3`09DESC_NAME,NAME,6(R10)`09;Is the user the same in this node. X`09BLSS`09INSERT`09`09`09; X`09CMPL`09(R10),#0`09`09;Is this the last node? X`09BNEQ`0910$ X`09BRW`09ENDSERT`09`09`09;Yes, go insert user in the list. X10$:`09CMPL`09R10,R9 `09`09;Is there only one node in the list? X`09BEQL`0915$`09`09`09;YES, only incr current pointer. X`09MOVL`09(R9),R9`09`09`09;NO, incr both pointers. X15$:`09MOVL`09(R10),R10`09`09;Get the next node. X`09BRB`09NODE_CHK`09`09;Check the next node. X XINSERT:`09 X`09PUSHAL`09CURRENT`09`09`09;Get the next node from system. X`09PUSHAL`09NODE_SIZE X`09CALLS`09#2,G`5ELIB$GET_VM X X`09CMPL`09R9,R10`09`09`09;Is there only 1 node in the list? X`09BEQL`09ONE_NODE`09`09;YES, insert new node at head of list. X`09MOVL`09CURRENT,R10`09`09;NO, R10 now points at current node.`09 X`09CLRL`0920(R10)`09`09`09;Clear the total bytes field in node. X`09CLRB`094(R10) X`09MOVC3`09#14,BLANKS,6(R10) ;Put spaces in the name field. X`09MOVB`09DESC_NAME,5(R10) X`09MOVC3`09DESC_NAME,NAME,6(R10) ;Insert name in current node X`09MOVL`09(R9),(R10) X`09MOVL`09R10,(R9) X`09BRW`09GET_BYTES XONE_NODE: X`09MOVL`09CURRENT,R10`09`09;NO, R10 now points at current node.`09 X`09CLRL`0920(R10)`09`09`09;Clear the total bytes field in node. X`09CLRB`094(R10) X`09MOVC3`09#14,BLANKS,6(R10) ;Put spaces in the name field. X`09MOVB`09DESC_NAME,5(R10) +-+-+-+-+-+-+-+- END OF PART 2 +-+-+-+-+-+-+-+- -+-+-+-+-+-+-+-+ START OF PART 3 -+-+-+-+-+-+-+-+ X`09MOVC3`09DESC_NAME,NAME,6(R10) ;Insert name in current node X`09MOVL`09HEAD,R9 X`09MOVL`09R10,HEAD X`09MOVL`09R9,(R10) X`09BRB`09GET_BYTES X`09 XENDSERT: X`09PUSHAL`09CURRENT`09`09`09;Get the next node from system. X`09PUSHAL`09NODE_SIZE X`09CALLS`09#2,G`5ELIB$GET_VM X X`09MOVL`09R10,R9 X`09MOVL`09CURRENT,R10`09`09;R10 now points at current node.`09 X`09CLRL`0920(R10)`09`09`09;Clear the total bytes field in node. X`09CLRB`094(R10) X`09MOVC3`09#14,BLANKS,6(R10) ;Put spaces in the name field. X`09MOVB`09DESC_NAME1,5(R10) X`09MOVC3`09DESC_NAME1,NAME,6(R10) ;Insert name in current node X X`09MOVL`09R10,(R9) X`09MOVL`09#0,(R10)`09 X XGET_BYTES: X`09MOVC3 `09#8,BLANKS,TOTAL_BYTES X`09MOVAB INBUF,R5 X`09MOVL`09STRING_SUB,R6 X`09BSBW`09FIND_SIZE X X`09MOVW`09R4,FILE_SIZE`09 X`09MOVC3`09FILE_SIZE,(R8),TOTAL_BYTES`09;Put file size @ TOTAL_BYTES. X`09PUSHAL CONVRT_NUM`09`09;Make call to converting routine. X`09PUSHAL`09FILE_SIZE X`09CALLS`09#2,G`5EOTS$CVT_TU_L X`09ADDL2`09CONVRT_NUM,20(R10)`09;Add file size to the previous total. X`09ADDB2`09#1,4(R10)`09`09;Incr. the num of messages field. X`09INCL`09TOTAL_FILES X`09ADDL2 CONVRT_NUM,TOTAL_SIZE X`09BRW`09LOOP`09`09`09;Get the next record. X XEND_PROCESS: X`09MOVB`09#1,DATE_PARA`09 XCLOSE_DAY: X`09MOVL`09HEAD,R10`09`09;R10 points to the head of the list. XCHK_NIL: X`09MOVAB BUF_DATE,FAO_CALL+FAO$_P1 ;Insert the date in output. X`09MOVAB`095(R10),FAO_CALL+FAO$_P2 ;Insert the user name in output. X`09CLRL`09FAO_CALL+FAO$_P3 X`09MOVB`094(R10),FAO_CALL+FAO$_P3 ;Insert the num of messages. X`09MOVL`0920(R10),FAO_CALL+FAO$_P4 ;Convert the size to ASCII X`09$FAO_G`09FAO_CALL X`09MOVC3`09BUFFER,@BUFFER+4,OUTBUF`09;Insert the size in output. X`09$PUT`09RAB=OUTRAB`09`09;Write the line out. X`09MOVC3`09#80,BLANKS,BLANK_LINE`09;Clear the buffer. X`09MOVL`09(R10),R10`09`09;Get the next node. X`09CMPL`09R10,#0`09`09 ;Is this the last node. X`09BEQL`09END_LIST X`09BRW`09CHK_NIL`09`09`09;Do it again. X XEND_LIST: X`09MOVC3`09#80,SUM_LINE,OUTBUF X`09$PUT`09RAB=OUTRAB X MOVL `09TOTAL_FILES,FAO_TOT+FAO$_P1 X`09MOVL `09TOTAL_SIZE,FAO_TOT+FAO$_P2 X`09$FAO_G`09FAO_TOT X`09MOVC3`09#80,BLANKS,OUTBUF X`09MOVC3`09BUFFER,@BUFFER+4,OUTBUF X`09$PUT`09RAB=OUTRAB X`09MOVC3`09#80,BLANKS,OUTBUF`09 X`09$PUT`09RAB=OUTRAB X`09 X5$:`09CMPL`09R10,#0`09`09`09;Is there only one node in the list? X`09BEQL`09LAST_NODE`09`09;YES, go delete it. X`09MOVL`09@HEAD,R10`09`09;R10 points to the new head of the list. X`09PUSHAL`09HEAD X`09PUSHAL`09NODE_SIZE X`09CALLS`09#2,G`5ELIB$FREE_VM X`09CMPL`09(R10),#0`09`09 `09;Is this the last node to delete? X`09BEQL`09LAST_NODE X`09MOVL`09R10,HEAD X`09BRB`095$ X XLAST_NODE: X`09MOVL`09R10,HEAD X`09PUSHAL`09HEAD X`09PUSHAL`09NODE_SIZE X`09CALLS`09#2,G`5ELIB$FREE_VM X X`09CMPL`09STATUS,#RMS$_EOF X`09BEQL`095$ X`09CMPB`09#1,DATE_PARA X`09BEQL`095$ X`09CLRL`09TOTAL_FILES X`09CLRL TOTAL_SIZE X`09BRW`09FIRST_NODE X X5$:`09MOVAB`09INFAB,R3 X`09MOVAB`09INRAB,R4 X`09MOVAB`09OUTRAB,R5 X`09MOVAB`09OUTFAB,R6 X`09BSBW`09CLOSE_FILE X XBEFORE_ERROR: X`09RSB X X X X;/////////////////////////////////////////////////////////////////////////// V//// X;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ V\\\\ X X;`09PRIME_FILE looks for the appropriate place in the file to begin the X;`09analysis. This is done by converting the date in each record to binary X;`09and comparing it to the /SINCE value which has been converted to`20 X;`09to binary. The comparison is done by the macro SUBDTE which sets FLAG X;`09to the appropriate value. If the end of file is reached before the`20 X;`09record mets the appropriate value the EOF flag is set and the subroutine X;`09is exited. X XPRIME_FILE: X`09MOVC5`09#0,#0,#0,#256,INBUF X`09$GET`09RAB=INRAB X`09BLBS`09R0,10$ X5$:`09BRW`0915$ X10$:`09MOVC3`09#11,INBUF,@BUF_DATE+4`09;Put date in descriptor X`09PUSHAB`09BUF_DATE_QUAD`09`09;Binary rep. of current date in log file X`09PUSHAB`09BUF_DATE`09`09;Descriptor for date string X`09CALLS #2,G`5ESYS$BINTIM`09`09;Convert the string to binary X`09SUBDTE`09SINCE_QUAD,BUF_DATE_QUAD,FLAG X`09BBC`09#7,FLAG,20$ X`09BRW `09PRIME_FILE X15$:`09MOVB`09#1,EOF X20$:`09CLRB`09FLAG X`09RSB X`09 X;/////////////////////////////////////////////////////////////////////////// V//// X;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ V\\\\ X XCHK_BEFORE: X`09SUBDTE`09BEFORE_QUAD,BUF_DATE_QUAD,FLAG X`09RSB X X;/////////////////////////////////////////////////////////////////////////// V//// X;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ V\\\\ X X XSET_COMMAND: X`09PUSHAB`09BEFORE_QUAD`09`09;This section will get the system`20 X`09CALLS`09#1,G`5ESYS$GETTIM`09`09; time for the current day. X`09BITB`09#0,R0 X`09BEQL`095$ X`09MOVAB`09TIM_ERR,OUTRAB+RAB$L_RBF X`09$PUT`09RAB=OUTRAB X`09$EXIT_S X5$:`09ADDQ2`09DAY,BEFORE_QUAD`09`09;BEFORE_QUAD is initialized to tommorrow X X`09PUSHAB`09DATE_DESC`09`09;Is the /DATE on the command line? X`09CALLS`09#1,G`5ECLI$PRESENT X`09CMPL`09R0,#CLI$_PRESENT X`09BNEQ`0910$`09`09`09;No, go check /SINCE X X`09PUSHAB`09RET_VALUE_DESC`09`09;Yes, get the date for /SINCE X`09PUSHAB`09DATE_DESC X`09CALLS`09#2,G`5ECLI$GET_VALUE X X`09BSBW`09SET_SINCE`09`09;/SINCE will equal /DATE X`09BSBW`09SET_BEFORE`09`09;/BEFORE will equal /SINCE + 24 Hours X`09BRB`0925$`09`09`09;Go process the file X`09 X10$: PUSHAB`09SINCE_DESC`09`09;Check if /SINCE is on the command line. X`09CALLS`09#1,G`5ECLI$PRESENT X`09CMPL`09R0,#CLI$_PRESENT`09;Was /SINCE there? X`09BNEQ`0920$`09`09`09;No, go check /BEFORE X X`09PUSHAB`09RET_VALUE_DESC X`09PUSHAB`09SINCE_DESC X`09CALLS`09#2,G`5ECLI$GET_VALUE X`09PUSHAB`09SINCE_QUAD X`09PUSHAB`09RET_VALUE_DESC X`09CALLS`09#2,G`5ESYS$BINTIM X X X20$:`09PUSHAB`09BEFORE_DESC`09`09;Is /BEFORE also on the command line? X`09CALLS`09#1,G`5ECLI$PRESENT X`09CMPL`09R0,#CLI$_PRESENT`09 X`09BNEQ`0925$`09`09`09;No, go process file. X X`09PUSHAB`09RET_VALUE_DESC`09`09;Yes, get the value. X`09PUSHAB`09BEFORE_DESC X`09CALLS`09#2,G`5ECLI$GET_VALUE X`09PUSHAB`09BEFORE_QUAD X`09PUSHAB`09RET_VALUE_DESC X`09CALLS`09#2,G`5ESYS$BINTIM X`09 X25$:`09RSB X X;/////////////////////////////////////////////////////////////////////////// V//// X;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ V\\\\ X;`09SET_SINCE X X;`09SET_SINCE will set the value of the /SINCE parameter to that of the X;`09/DATE parameter. That value is then converted to binary by SYS$BINTIM. X XSET_SINCE: X`09MOVW`09RET_VALUE_DESC,SINCE_DATE X`09MOVL`09RET_VALUE_DESC+4,SINCE_DATE+4 X`09PUSHAB`09SINCE_QUAD X`09PUSHAB`09SINCE_DATE X`09CALLS`09#2,G`5ESYS$BINTIM X X`09RSB X;/////////////////////////////////////////////////////////////////////////// V/// X;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ V\\\ X; X;`09SET_BEFORE X X;`09SET_BEFORE is used to initialize the value of the /BEFORE parameter X;`09Initially the value is set to the current day + 24 hours which is`20 X;`09represented by the label DAY. DAY is the hard coded binary value`20 X;`09for 24 hours. The before prarmeter is set to this value before it X;`09is determined if it is present on the command line. This way the`20 X;`09/SINCE parmeter is initialized to 0 and the /BEFORE is set to tomorrow X;`09so the entire file is valid if no parameters are found on the commmand X;`09line. No set up is required to call the subroutine and when it completes X;`09BEFORE_QUAD will have the binary value for tomorrow. X; X XSET_BEFORE: X`09PUSHAB`09BEFORE_QUAD X`09PUSHAB`09RET_VALUE_DESC X`09CALLS`09#2,G`5ESYS$BINTIM X`09ADDQ2`09DAY,BEFORE_QUAD X`09RSB X X;/////////////////////////////////////////////////////////////////////////// V/// X;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ V\\\ X; X;`09FIND_SOURCE X;`09 X;`09This subroutine is used to find the user name. The calling`20 X; convention is as follows: X; X;`09`09R5 => contains the address of the input buffer that is`20 X;`09`09 begin searched. X;`09`09R6 => contains the address of the with which to compare. X; X;`09The subroutine will return the following: X; X;`09 `09R4 => contains the length of the user name in bytes. X;`09`09R8 => contains the address of the user name. X; X;/////////////////////////////////////////////////////////////////////////// V//// X;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ V\\\\ X; XFIND_SOURCE: X XSEARCH1: X`09CMPC3`09#9,(R6),(R5)`09;Look for the pattern to match in the`20 X`09BEQL`095$`09`09; input buffer INBUF X`09INCL`09R5`09`09;Look at next nine characters for the match X`09BRB`09SEARCH1 X5$:`09 X`09ADDL2`09#9,R5`09`09;R5 now points to the 1st char. in user name X`09MOVL`09R5,START_ADDR`09;START_ADDR holds the address of the user name X`09CLRL`09R4`09`09;R4 will give length of user name X`09CMPB`09(R5),#`5EA'@' ;Is this the end of the user name? X`09BEQL`09NEW_SEARCH XQUOTE2:`09CMPB`09(R5),#`5EA'@' ;Is this the end of the user name? X`09BEQL`09DONE2 X`09CMPB`09(R5),#`5EA'>' X`09BEQL`09NULL X`09INCL`09R5`09`09;R5 now has the address of next character X`09INCL`09R4`09`09;R4 holds current length of user name X`09BRB`09QUOTE2`09`09;Go check next character XDONE2:`09MOVL`09START_ADDR,R8 X`09BRB`09OUT XNULL:`09MOVAB`09NULL_STRING,R8`09;The source was blank <> so the user name X`09MOVL`09#9,R4`09`09; NULL_USER is used. X`09BRB `09OUT X XNEW_SEARCH: X`09CMPB`09(R5),#`5EA':'`09 X`09BEQL`09HERE2 X`09INCL`09R5 X`09BRB`09NEW_SEARCH XHERE2:`09INCL`09R5 X`09MOVL`09R5,START_ADDR`09;START_ADDR holds the address of the user name X`09CLRL`09R4`09`09;R4 will give length of user name X5$:`09CMPB`09(R5),#`5EA'@' ;Is this the end of the user name? X`09BEQL`0910$ X`09INCL`09R5`09`09;R5 now has the address of next character X`09INCL`09R4`09`09;R4 holds current length of user name X`09BRB`095$`09`09;Go check next character X10$ : MOVL`09START_ADDR,R8 XOUT:`09RSB X; X;/////////////////////////////////////////////////////////////////////////// V/// X;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ V\\\ X; XFIND_USER: X XSEARC:`09CMPC3`09#5,(R6),(R5)`09;Start searching for the matching pattern X`09BEQL`095$`09`09; USER= When found branch to 5$. X`09INCL`09R5 X`09BRB`09SEARC X5$:`09ADDL2`09#5,R5`09`09;R5 now points to the 1st char. in user name X`09CMPB (R5),#`5EA/"/ ;Is this a quoted string? X`09BNEQ`098$`09`09;NO, Start getting the user name. X`09INCL`09R5`09`09;YES, Point R5 to begining of the user name. X`09MOVB #0,MX_231`09;Set new version of MX to FALSE X8$:`09MOVL`09R5,START_ADDR`09;START_ADDR holds the address of the user name X`09MOVL #1,R4`09`09;R4 will give length of user name X10$:`09CMPB`09(R5),#`5EA',' ;Is this the end of the user name? X`09BEQL`09DONE1 X`09INCL`09R5`09`09;R5 now has the address of next character X`09INCL`09R4`09`09;R4 holds current length of user name X`09BRB`0910$`09`09;Go check next character XDONE1:`09MOVL`09START_ADDR,R8 X`09CMPB`09MX_231,#1 X`09BEQL`095$ X`09DECL R4 X5$:`09DECL`09R4 X`09MOVB`09#1,MX_231`09;Reset new version to true X`09RSB X; X;/////////////////////////////////////////////////////////////////////////// V//// X;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ V\\\\ X; XCLEAR_NODE: X X`09MOVL`09CURRENT,HEAD`09`09;HEAD now points to the head of the list X`09MOVL`09CURRENT,R10`09`09;R10 points to the current node in list. X`09MOVL`09CURRENT,R9`09`09;R9 also points to the only node. X`09CLRL`09(R10)`09`09`09;FLINK is now NIL ( ZERO ). X`09CLRB`094(R10)`09`09`09;Clear the number of messages field. X`09CLRB`095(R10)`09`09`09;Clear the name_length field. X`09CLRL`0920(R10)`09`09`09;Clear the total bytes field in node. X`09MOVC3`09#14,BLANKS,6(R10) ;Put spaces in the name field. X`09RSB X; X;/////////////////////////////////////////////////////////////////////////// V//// X;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ V\\\\ X;`09NO_FILES X X;`09NO_FILES will print out a message saying that no files were found X;`09that met the parameters on the command line. X;`09Also if the file was empty this message will be printed out. X; XNO_FILES: X`09MOVAB`09ERROR1,OUTRAB+RAB$L_RBF X`09$PUT`09RAB=OUTRAB X`09RSB X`09.END`09MXSUM_V2 X $ CALL UNPACK MXSUM.MAR;1 51812853 $ create 'f' XSTART_SIZE:`09.LONG`090`09 X; X;`09TO BE GLOBAL X; XO_FILE::`20 X;`09MOVL`094(R2),FAB$L_FNA(R3) `09;Put file address in FAB X;`09MOVB (R2),FAB$B_FNS(R3) `09;Put file name size in FAB X`09$OPEN FAB=(R3) ;OPEN the file X`09$CONNECT RAB=(R4) X`09RSB X; X;/////////////////////////////////////////////////////////////////////////// V/// X;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ V\\\ X; X;`09TO BE GLOBAL X; XGET_REC::`09 X`09$GET`09RAB=(R3) ;GET the record X`09RSB X; X;/////////////////////////////////////////////////////////////////////////// V/// X;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ V\\\ X;`09`09TO BE GLOBAL X; XCLOSE_FILE:: X`09$DISCONNECT RAB=(R4) X`09$DISCONNECT RAB=(R5) X`09$CLOSE FAB=(R3) X`09$CLOSE FAB=(R6) X`09RSB X; X;/////////////////////////////////////////////////////////////////////////// V/// X;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ V\\\ X; X; X;`09This is find_size X; XFIND_SIZE:: X; XSEARCH1:`09 X`09CMPC3`09#5,(R6),(R5) X`09BEQL`09HERE X`09INCL`09R5 X`09BRB`09SEARCH1 XHERE:`09 X`09ADDL2`09#5,R5`09`09;R5 now points to the 1st char. in SIZE X`09MOVL`09R5,START_SIZE`09;START_SIZE holds the address of the SIZE X`09CLRL`09R4`09`09;R4 will give length of SIZE XBLANK:`09CMPB`09(R5),#`5EA'0' ;Is this the end of SIZE? X`09BLSS`09DONE1 X`09CMPB (R5),#`5EA'9' X`09BGTR DONE1 X`09INCL`09R5`09`09;R5 now has the address of next character X`09INCL`09R4`09`09;R4 holds current length of SIZE X`09BRB`09BLANK`09`09;Go check next character XDONE1:`09MOVL`09START_SIZE,R8 X`09RSB X`09.END $ CALL UNPACK MX_MOD.MAR;1 1214341873 $ v=f$verify(v) $ EXIT