{This program was written by Alta M. Paul, January, 1988.  This program 
will execute after the ARPA3 program during the 3a.m. run that adds messages 
to the bulletin board data base.

The purpose of this program is to speed up the initial screen painting of 
the bulletin board utility.  This program will use the specified data base file
and count the messages for each topic by date.  These records will be stored in 
a sequential file.  The intent is to have the bulletin board utility read 
this sequential file and make the lines for the first screen instead of 
touching every record in the data base file each time the utility 
is invoked.

The lines will be totaled by date for each topic (the lines are in order by 
topic and in order by date under each topic).  Then the BB$USERFILE3.DAT
file will be used to get the totals for the NEW column on the first screen. 
The procedure where the BB$category_COUNT.DAT will be used is called 
MESSAGE_STATE in the bulletin board program.
          
This program resides in each of the category areas.  Edit this program 
carefully to reflect the current locations of the count file and data base 
file being used.}



{*************************************************************************
**************************************************************************

Changes were made to this program 24-MAR-1988 to accomodate splitting the 
data base files into categories.  

The data base files will be known as:
			BB$BITNET_BOARDS.DAT
                        BB$LOCAL_BOARDS.DAT
                        BB$RESEARCH_BOARDS.DAT
The count files have also been split for the 3 categories and are known as:
			BB$BITNET_COUNT.DAT
                        BB$LOCAL_COUNT.DAT
                        BB$RESEARCH_COUNT.DAT
The file names are set in the main module.  The only changes needed if the
topics are further split will be to add more logic in the main module to
run the count program for each separate data base file.

AMP

*************************************************************************
*************************************************************************}


[inherit('sys$library:starlet')]
program Counter(input,output,bbfile,count_file);

const null_date = chr(0)+chr(0)+chr(0)+chr(0)+chr(0)+chr(0)+chr(0)+chr(0);
      data_logical = 'SYSTEM3:[BB$PROGRAM.DATA]';  {location of data base files}
      block_size = 512 * 3;
      date_length = 8;
      topic_length = 16;
      username_length = 48;
      subject_length = 30;
      data_length = block_size-date_length-topic_length-
                    username_length-subject_length-3;

      
type nametype = packed array [1..username_length] of char;
     timetype = packed array [1..date_length] of char;
     topictype = packed array [1..topic_length] of char;
     bbrec = record
               date: timetype;
               topic : topictype;
               poster : nametype;
               subject : packed array [1..subject_length] of char;
               data : varying [data_length] of char;
               continuation : boolean;
               date_posted : timetype;
             end;
     dir_ptr = ^dirrec;
     dirrec = record
                previous : dir_ptr;
                next : dir_ptr;
                number : integer;
                date : timetype;
                topic : topictype;
                poster : packed array [1..username_length] of char;
                subject : packed array [1..subject_length] of char;
                class : integer;
                message_counters : record
                                     total_message : integer;
                                     new_message : integer;
                                     read_message : integer;
                                     skipped_message : integer;
                                  end;
                last_date_accessed : timetype;
               end;
    string = varying [data_length] of char;

var bbfile : file of bbrec;
    count_file : text;
    chosen_file : string;
    count_location : string;
    current_record : bbrec;
    topic_root : dir_ptr;
    topic_curr : dir_ptr;
    topic_prev : dir_ptr;
    topic_list : dir_ptr;
    current_topic : topictype;
    total_msgs : integer;    


procedure create_the_list;  

{Construct list of topics from chosen_file.}

begin
  new(topic_root);
  topic_root^.next := nil;
  topic_root^.previous := nil;
  topic_root^.message_counters.total_message := 0;

  topic_curr := topic_root;
  open(bbfile,data_logical+chosen_file,history:=readonly,
       access_method:=keyed,organization:=indexed,sharing:=readwrite,
       error:=continue);
  resetk(bbfile,0);

  repeat
    read(bbfile,current_record,error:=continue);
    with current_record do
    begin
      if (date = null_date) and (status(bbfile) <= 0) then
      begin
        topic_prev := topic_curr;
        new(topic_curr);
        topic_prev^.next := topic_curr;
        topic_curr^.previous := topic_prev;
        topic_curr^.topic := topic;
        topic_curr^.message_counters.total_message := 0;
      end;
    end;
  until (current_record.date <> null_date) or
         eof(bbfile) or (status(bbfile) > 0);
  topic_curr^.next := nil;
end;


function invert (time:timetype):timetype;  

{Needed to convert vax time to ascii.}

var temp : timetype;
    i : integer;
begin
  for i := 1 to 8 do
    temp[i] := time[9-i];
  invert := temp;
end;


procedure do_the_counts;  

{Count the messages by topic and date.}

var date_mark : packed array [1..11] of char;
    test_date : timetype;
    write_date : timetype;
    date_string : packed array [1..20] of char;
    date_count : integer;

begin
  $setprv(1,prv$m_sysprv);
  open(count_file,count_location,history:=old);
  rewrite(count_file);
  topic_list := topic_root;

  while (topic_list^.next <> nil) do
    begin
      date_count := 0;
      topic_list := topic_list^.next;
      current_topic := topic_list^.topic;
      findk(bbfile,1,current_topic+null_date,gtr,error:=continue);
      if not ufb(bbfile) then
        begin
          read(bbfile,current_record,error:=continue);

          repeat
            date_count := 0;
            write_date := current_record.date;
            $asctim(timbuf:=date_string,timadr:=invert(current_record.date));
            date_mark := substr(date_string,1,11);

            repeat
              date_count := date_count + 1;
              findk(bbfile,1,current_record.topic+current_record.date,
                    gtr,error:=continue);
              if (not(ufb(bbfile))) then
                begin
                  read(bbfile,current_record,error:=continue);
                  $asctim(timbuf:=date_string,
                      timadr:=invert(current_record.date));
                  if (eof(bbfile)) then
                    date_count := date_count + 1;
                end;
            until (date_mark <> substr(date_string,1,11))
                   or (ufb(bbfile));

            if (date_count > 0) 
                and (write_date <> null_date) then
              writeln(count_file,current_topic:16,write_date:8,
                      date_count,'    ',date_mark:11);
          until (current_record.topic <> current_topic)
                 or (eof(bbfile));

        end;
    end;

  close(count_file);
  $setprv(0,prv$m_sysprv);
end;


begin   {*****EDIT TO CHOOSE ONE GROUP BELOW FOR EACH CATEGORY AREA*****}

  chosen_file := 'bb$local_boards.dat';
  count_location := 'bb$local_count.dat';
  create_the_list;          
  do_the_counts;
  close(bbfile,error:=continue);
  writeln('End of local board count.');
  writeln;
  writeln;
{
  chosen_file := 'bb$research_boards.dat';
  count_location := 'bb$research_count.dat';
  create_the_list;          
  do_the_counts;
  close(bbfile,error:=continue);
  writeln('End of research board count.');
  writeln;
  writeln;

  chosen_file := 'bb$bitnet_boards.dat';
  count_location := 'bb$bitnet_count.dat';
  create_the_list;          
  do_the_counts;
  close(bbfile,error:=continue);
  writeln('End of bitnet board count.');
  writeln;
  writeln;
}
end.
