From:	CRDGW2::CRDGW2::MRGATE::"SMTP::CUNYVM.CUNY.EDU::POSTMAST%YMIR.BITNET"  1-JUL-1989 04:28
To:	MRGATE::"ARISIA::EVERHART"
Subj:	pmdf_summary.2_of_2

Resent-From: @CUNYVM.CUNY.EDU:postmast@YMIR.BITNET
Received: from YMIR.BITNET by CUNYVM.CUNY.EDU (IBM VM SMTP R1.1) with BSMTP id 9361; Sat, 01 Jul 89 04:08:32 EDT
Resent-Message-Id: <8F078ADFCF3FE03017@YMIR.BITNET>
Message-Id: <8F0B97E038BFE03106@YMIR.BITNET>
Received: from CUNYVM.BITNET by YMIR.BITNET; Fri, 30 Jun 89 19:15 PDT
Received: from CUNYVM by CUNYVM.BITNET (Mailer R2.03B) with BSMTP id 4707; Fri,
 30 Jun 89 18:19:04 EDT
Received: from RELAY.CS.NET by CUNYVM.CUNY.EDU (IBM VM SMTP R1.1) with TCP;
 Fri, 30 Jun 89 18:18:55 EDT
Received: from relay2.cs.net by RELAY.CS.NET id ac06880; 30 Jun 89 15:32 EDT
Received: from merrimack.edu by RELAY.CS.NET id ab14730; 30 Jun 89 15:27 EDT
Resent-Date: Fri, 30 Jun 89 19:24 PDT
Date: Fri, 30 Jun 89 11:11 EST
From: "Rand P. Hall" <RAND%merrimack.edu%RELAY.CS.NET@CUNYVM.CUNY.EDU>
Subject: pmdf_summary.2_of_2
Resent-To: INFO-PMDF-LIST2@YMIR.BITNET
To: info-pmdf%ymir.bitnet@RELAY.CS.NET
Errors-To: postmast@YMIR.BITNET
X-Vms-To: IN%"info-pmdf@ymir.BITNET"

+-+-+-+ Beginning of part 2 +-+-+-+
$ CHECKSUM_IS = 520967861
$ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY
X$ ! Logicals used to be passsed (sort of) to the program
X$ ! In parentheses is the default
X$ ! pmdf$sum_input  -  The datafile that is to be summed (Mail.log)
V$ ! PMDF$sum_output - The datafile that the results will be dumped to (Mail.t
Xot)
X$ ! Month - The three letter month code (Tot), Total or All
X$ ! Month_extended - The full name of the month (Total)
X$ ! Sort - the key upon which the the string is sorted (Name)
X$
X$ Month := 'P1
X$ The_sort_key := 'P2
X$ Infile := 'P3
X$ Outfile := 'P4
X$`032
X$ ! setup for the defaults
X$ If month .eqs. ""
X$   THEN
X$     month := "TOT"
X$ ENDIF
X$
X$ If The_sort_key .eqs. ""
X$   THEN
X$     The_sort_key := "Name"
X$ ENDIF
X$
X$ If Infile  .eqs. ""
X$   THEN
X$     Infile := "MAIL.LOG"
X$ ENDIF
X$
X$ If Outfile .eqs. ""
X$   THEN
X$     Outfile := "Mail.TOT"
X$ ENDIF
X$ `032
X$ !the input and output files have these logicals
X$     ASSIGN 'infile PMDF$SUM_INPUT/nolog
X$
X$     ASSIGN 'outfile PMDF$SUM_OUTPUT/nolog
X$`032
X$`032
X$ MONTH_LIST = "JAN/FEB/MAR/APR/MAY/JUN/JUL/AUG/SEP/OCT/NOV/DEC/ALL/TOT"
X$ POSITION = F$LOCATE(MONTH,MONTH_LIST)
X$ IF POSITION .EQS. 55 THEN GOTO BADMONTH
X$ assign pmdf$sum_output sys$output
X$`032
X$
X$!crude, but effective
X$ IF MONTH .EQS. "JAN" THEN GOTO JAN
X$ IF MONTH .EQS. "FEB" THEN GOTO FEB
X$ IF MONTH .EQS. "MAR" THEN GOTO MAR
X$ IF MONTH .EQS. "APR" THEN GOTO APR
X$ IF MONTH .EQS. "MAY" THEN GOTO MAY
X$ IF MONTH .EQS. "JUN" THEN GOTO JUN
X$ IF MONTH .EQS. "JUL" THEN GOTO JUL
X$ IF MONTH .EQS. "AUG" THEN GOTO AUG
X$ IF MONTH .EQS. "SEP" THEN GOTO SEP
X$ IF MONTH .EQS. "OCT" THEN GOTO OCT
X$ IF MONTH .EQS. "NOV" THEN GOTO NOV
X$ IF MONTH .EQS. "DEC" THEN GOTO DEC
X$!ALL really does not work - it cannot separate the months
X$ IF MONTH .EQS. "ALL" THEN GOTO ALL
X$ IF MONTH .EQS. "TOT" THEN GOTO TOT
X$ GOTO FINISH
X$ JAN:
X$ RUN PMDF_SUM
XJAN
XJanuary
X$ GOTO FINISH
X$ FEB:
X$ RUN PMDF_SUM
XFEB
XFebruary
X$ GOTO FINISH
X$ MAR:
X$ RUN PMDF_SUM
XMAR
XMarch
X$ GOTO FINISH
X$ APR:
X$ RUN PMDF_SUM
XAPR
XApril
X$ GOTO FINISH
X$ MAY:
X$ RUN PMDF_SUM
XMAY
XMay
X$ GOTO FINISH
X$ JUN:
X$ RUN PMDF_SUM
XJUN
XJune
X$ GOTO FINISH
X$ JUL:
X$ RUN PMDF_SUM
XJUL
XJuly
X$ GOTO FINISH
X$ AUG:
X$ RUN PMDF_SUM
XAUG
XAugust
X$ GOTO FINISH
X$ SEP:
X$ RUN PMDF_SUM
XSEP
XSeptember
X$ GOTO FINISH
X$ OCT:
X$ RUN PMDF_SUM
XOCT
XOctober
X$ GOTO FINISH
X$ NOV:
X$ RUN PMDF_SUM
XNOV
XNovember
X$ GOTO FINISH
X$ DEC:
X$ RUN PMDF_SUM
XDEC
XDecember
X$ GOTO FINISH
X$ TOT:
X$ RUN PMDF_SUM
XTOT
XTotal
X$ GOTO FINISH
X$ ALL:
X$ RUN PMDF_SUM
XJAN
XJanuary
X$ RUN PMDF_SUM
XFEB
XFebruary
X$ RUN PMDF_SUM
XMAR
XMarch
X$ RUN PMDF_SUM
XAPR
XApril
X$ RUN PMDF_SUM
XMAY
XMay
X$ RUN PMDF_SUM
XJUN
XJune
X$ RUN PMDF_SUM
XJUL
XJuly
X$ RUN PMDF_SUM
XAUG
XAugust
X$ RUN PMDF_SUM
XSEP
XSeptember
X$ RUN PMDF_SUM
XOCT
XOctober
X$ RUN PMDF_SUM
XNOV
XNovember
X$ RUN PMDF_SUM
XDEC
XDecember
X$ Goto finish
X$
X$
X$
X$
X$
X$ BADSORT:
X$ TYPE SYS$INPUT
X
XSorry, but that is not a valid choice. The valid choices are
X`009
X`009`009IN_C         INSIZE      INAVG       NAME
X`009`009OUT_C        OUTSIZE     OUTAVG     `032
X
X$ EXIT
X
X$
X$
X$
X$ BADMONTH:
X$ TYPE SYS$INPUT
X
XSorry, but that is not a valid choice. The valid choices are
X`009
X`009`009JAN         MAY         SEP         TOT
X`009`009FEB         JUN         OCT         ALL
X        `009MAR         JUL         NOV
X        `009APR         AUG         DEC
X
X$ EXIT
X$
X$
X$
X$
X$
X$ Finish:
X$ deass sys$output
V$! this sorts the program, also outputs it. PMDF_SUM does not output by itsel
Xf
X$ @pmdf_sort 'the_sort_key
X$ EXIT
$ GOSUB UNPACK_FILE

$ FILE_IS = "PMDF_SUM.PAS"
$ CHECKSUM_IS = 2116993597
$ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY
XPROGRAM parsemail(input , output) ;
X
XCONST
X    INSTITUTION = '@merrimack.edu'; `123The name of the institution`125
X
XTYPE
X  `032
X   string = packed array [1..200] OF char ;
X   string4 = PACKED array [1..4] OF char ;
X   log_record = RECORD
X      day : PACKED array [1..2] OF char ;  `123Day message was recorded`125
X      month : PACKED array [1..3] OF char ; `123month of same`125
X      year : string4 ;                      `123year`125
X      time : PACKED array [1..8] OF char ;  `123time`125
X      source : char ;                       `123source ((L)ocal or (P))`125
X      destination : char ;                  `123(L)ocal or (P)`125
X      kind : char ; `123type of entry, (E)nqueue or (D)equeue`125
X      inbound : boolean ;      `123Is it and inbound or outbound message?`125
X      size : integer ;         `123size of the message`125
V      insize : integer ;       `123To count the total size of inbound message
Xs`125
V      incount : integer ;      `123to count the number of inbound messages`12
X5
V      inavg : real ;           `123the average size of the inbound messages`1
X25
X      outsize : integer ;      `123same as insize,count and ave`125
X      outcount : integer;
X      outavg : real ;
X      local_name : string;     `123the local address`125
V      tto : string ;           `123who the message is TTO ("TO" is reserved i
Xn PAS`125
X      from : string ;          `123who the message is FROM`125
X      END ;
V   messagebank = array [0..1000] OF log_record ;  `123the array that the reco
Xrds
Xare added in`125
X  `032
XVAR
X  `032
V   infile,outfile : text ; `123both input and output are simple text files`12
X5
X   one_line : log_record ; `123Read the log file one line at a time`125
X   total : messagebank ;   `123the name of the total array`125
V   top_of_total , i : integer ;`123a global variable - the top of messagebank
X`125
V   filter_month : packed array[1..3] of char ;  `123the month you are summing
X for`125
V   fullname_month : packed array[1..9] of char ;`123The full name of the mont
Xh`125
X
X
XFUNCTION UPPERCASE(VAR temp : string):string;
X`123I can't believe that PASCAL doesn't have an uppercase command!`125
X
XVAR
X      i : integer;
XBEGIN
X   i := 1;
X   while (i-1 < length(temp)) DO BEGIN
X      if ((temp[i] >= 'a') AND (temp[i] <= 'z')) THEN
X         temp[i] := chr(ord(temp [i]) - 32);
X      i := i + 1
X     END;
X     uppercase := temp;
XEND;
X
X
X
XFUNCTION convert_to_dec(VAR fourchars : string4) : integer ;
X
X`123Short and simple, converts a four character number to an integer`125
XVAR
X   one , two , three , four : char ;
X
XBEGIN
X   one := fourchars[1] ;
X   two := fourchars[2] ;
X   three := fourchars[3] ;
X   four := fourchars[4] ;
X   convert_to_dec := (ord(one) - 48) * 1000 + (ord(two) - 48) * 100 +`032
X                  (ord(three) - 48) * 10 + (ord(four) - 48) ;
XEND ;
X
X
X
XFUNCTION extract_name(var log : log_record; var inbound : boolean):string;
X
X`123Gets the name of the person, puts it into the table`125
V`123it searches the the TO feild for the name of the institution. If it finds
X it,
Xthen the local name is everything to the left of that. If not, then the local
Xname is just the from feild. For example:
X
XJohn@merrimack.edu Hatem@bcvax3.edu
X    \____________/
V           `124________the name of the institution is here, therefore the loc
Xal
X                    name is JOHN.
X
X@relay.cs.net:whiting%akov12.dec@decwrl.dec.com ain14924
X\_____________________________________________/
V                  `124____________________________no institution name, theref
Xore
X`009`009`009`009`009       the local name must be AIN14924
X
X`125
XVAR
X   name : string;
X   final_position:integer;
X
XBEGIN
X   final_position := index(log.tto,institution);
X   IF  final_position = 0 THEN BEGIN
X      inbound := true;
X      extract_name := log.from;
X      END ELSE BEGIN
X         extract_name := substr(log.tto,1,final_position-1);
X         inbound := false;
X         END;
XEND;
X
X
X
X
XFUNCTION getrecord : log_record ;
X`032
V`123This function reads one_line from the text(data) file, and extracts all o
Xf the
Xinformation. date,time,channels, who to, who from, size (it must convert the
Xsize as a four character string i.e. "0224" = 224), to and from fields (which
Xvary in size) ad nauseum.`125
X
X
XVAR
X   line : PACKED array [1..240] OF char ;
X   tempsize:string4 ;
X   tempsizeint : integer ;
X   temprecord : log_record ;
X   nextspace , finalspace : integer ;
X   inbound : boolean;
X
X   `032
XBEGIN
X   readln(infile , line) ;
X   temprecord.day := substr(line , 1 , 2) ;
X   temprecord.month := substr(line , 4 , 3) ;
X   temprecord.year := substr(line , 8 , 4) ;
X   temprecord.time := substr(line , 13 , 8) ;
X   temprecord.source := line[22] ;
X   temprecord.destination := line[35] ;
X   temprecord.kind := line[48] ;
X   tempsize := substr(line , 50 , 4) ;
X   temprecord.size := convert_to_dec(tempsize) ;
X   line := substr(line , 55 , length(line) - 55) ;
X   nextspace := index(line , ' ' ) ;
X   temprecord.tto := substr(line , 1 , nextspace - 1) ;
X   line := substr(line , nextspace + 1 , length(line) - nextspace - 1) ;
X   nextspace := index(line , ' ' ) ;
X   temprecord.from := substr(line , 1 , nextspace - 1) ;
X   temprecord.local_name := extract_name(temprecord,inbound);
X   temprecord.local_name := Uppercase(temprecord.local_name);
X   temprecord.inbound := inbound;   `032
X   IF inbound THEN BEGIN
X      temprecord.insize := temprecord.size ;
X      temprecord.incount := 1 ;
X      temprecord.outsize := 0 ;
X      temprecord.outcount := 0 ;
X      temprecord.inavg := temprecord.insize/temprecord.incount;
X      temprecord.outavg := 0;
X      END
X   ELSE BEGIN
X      temprecord.insize := 0 ;
X      temprecord.incount := 0 ;
X      temprecord.outsize := temprecord.size ;
X      temprecord.outcount := 1 ;
X      temprecord.outavg := temprecord.outsize/temprecord.outcount;
X      temprecord.inavg := 0;
X      END;
X   getrecord := temprecord ;
XEND ;
X
XPROCEDURE add_to_table(VAR log : log_record) ;
X
V`123takes the record (which is found in GETRECORD) and puts it into an array
X of
Xrecords (1..1000 right now, it can be increased).`125
X
XVAR
X   done : boolean ;
X   i : integer ;
X
XBEGIN
X   i := 1 ;
X   done := false ;
X   WHILE(i <= top_of_total) AND (NOT done) AND`032
X        ((log.month = filter_Month) OR (filter_month = 'TOT')) DO BEGIN
X      IF total [i].local_name = log.local_name THEN BEGIN
X
X         IF log.inbound THEN BEGIN
X            total [i].insize := total [i].insize + log.size ;
X            total [i].incount := total [i].incount + 1 ;
X            total [i].inavg := total [i].insize/total[i].incount
X            END
X         ELSE BEGIN
X            total [i].outsize := total [i].outsize + log.size ;
X            total [i].outcount := total [i].outcount + 1 ;
X            total [i].outavg := total [i].outsize/total[i].outcount
X            END;
X         done := true ;
X         END
X      ELSE
X         IF i = top_of_total THEN BEGIN
X            total [i]:= log ;
X            top_of_total := top_of_total + 1 ;
X            done := true ;
X            END
X         ELSE
X            i := i + 1 ;
X      END ;
XEND ;
X
X
XBEGIN
X   top_of_total := 1 ;
X   open(infile , 'pmdf$sum_input' , history := old) ;
X   reset(infile) ;
X   readln(filter_month);
X   readln(fullname_month);`032
X
X`123this is the whole program, it reads in one line at a time.`125
X   WHILE NOT eof(infile) DO BEGIN
X      one_line := getrecord ;   `032
X      add_to_table(one_line) ;
X      END ;
X
X`123this prints it out. It prints it out to the screen, but sys$output is
Xredirected at this point, so you don't really see it`125
X   FOR i := 1 TO top_of_total - 1 DO BEGIN
X      write(total[i].local_name:15,
X`009total [i].incount:10, total[i].insize:10, total[i].inavg:10:1) ;
V        writeln(total[i].outcount:10,total[i].outsize:10,total[i].outavg:10:1
X);
X      END;
X   close(infile) ;
XEND .
$ GOSUB UNPACK_FILE
$ EXIT
-+-+-+-+-+ End of part 2 +-+-+-+-+-
