From:	CSBVAX::CSBVAX::MRGATE::"SMTP::CUNYVM.CUNY.EDU::MAILSERV-REPLY%UNCG.BITNET" 14-MAR-1989 01:06
To:	MRGATE::"ARISIA::EVERHART"
Subj:	Re: SEND [MAILSERV_SOURCE]V101.*  ([MAILSERV_SOURCE]V101.3_OF_4)


Received: from uncg.bitnet by CUNYVM.CUNY.EDU (IBM VM SMTP R1.1) with BSMTP id 7217; Tue, 14 Mar 89 00:41:37 EST
Date: Mon, 13 Mar 89 16:28 EST
From: "PMDF Mailserv V1.02" <MAILSERV-REPLY%UNCG.BITNET@CUNYVM.CUNY.EDU>
Subject: Re: SEND [MAILSERV_SOURCE]V101.*  ([MAILSERV_SOURCE]V101.3_OF_4)
To: EVERHART%ARISIA.decnet@GE-CRD.ARPA

+-+-+-+ Beginning of part 3 +-+-+-+
X      copy_file (MAILSERV_FILES_DIR , returned_filename);
X      end_reply;
X    END
X    ELSE BEGIN
X      error_in_command := TRUE;  (*  we've hit an error  *)
X      start_reply;
X      write_varalfa ('>' + local_filename);
X      write_varalfa ('');
X      write_varalfa`032
X('This is an improper filespec.  Please make sure you have specified a ');
X      write_varalfa`032
X('file name and file type.  For more information, use the HELP command ');
X      write_varalfa
X('to receive help on the format of the SEND command.');
X      end_reply;
X    END
X  END
X  ELSE BEGIN  (*  error getting filename  *)
X    WRITELN ('Error getting file, status = ', ret_status);
X    abort_it ('error calling cli$get_value in send_routine');
X  END;
X
X  send_routine := ret_status;
XEND; (*  send_routine  *)
X
X(***********************************************************************)
X(*                                                                     *)
X(*  SEND_LIST_ROUTINE - handles the SEND/LIST verb.                    *)
X(*                                                                     *)
X(***********************************************************************)
X[global] FUNCTION send_list_routine : UNSIGNED;
X
XVAR
X  list_file : TEXT;
X  listfilename : varalfa;
X  listname : var80;
X  ret_buffer : PACKED ARRAY [1..255] OF CHAR;
X  ret_buffer_len : UNSIGNED;
XBEGIN
X
X  IF DEBUG THEN WRITELN ('Entering routine SEND_LIST_ROUTINE');
X
X  (*  assume the command is in error  *)
X  error_in_command := TRUE;
X
X  (*  if mailing lists not enabled (the logical name isn't defined) tell
X       them so.  *)
X `032
X  ret_status := $TRNLOG (lognam := MAILSERV_MAIL_DIR, rslbuf := ret_buffer);
X  IF DEBUG THEN WRITELN`032
X    ('  return status of $TRNLOG on pmdf_maillist_dir', ret_status);
X
X  IF (NOT ODD (ret_status)) OR
X     (ret_status = SS$_NOTRAN) THEN BEGIN  (*  i.e. no logical name  *)
X    IF DEBUG THEN WRITELN ('  Writing ''lists not enabled'' message');
X    start_reply;
X    write_varalfa ('Mailing lists are not currently enabled at this site.');
X    end_reply;
X  END
X  ELSE BEGIN
X    (*  get the list name  *)
X    IF DEBUG THEN WRITELN ('  Getting list name.');
X    ret_buffer_len := 0;
X    ret_status := CLI$GET_VALUE ('SEND_LIST_P1', ret_buffer, ret_buffer_len);
X    IF DEBUG THEN WRITELN ('  return stat of cli$get_value = ', ret_status);
X    IF DEBUG THEN WRITELN ('  Length of list name = ', ret_buffer_len);
X    IF NOT ODD (ret_status) THEN`032
X      abort_it ('error getting p1 in SEND_LIST_ROUTINE');
X    listname := SUBSTR (ret_buffer, 1, MIN (ret_buffer_len, UINT(80)));
X    listfilename := MAILSERV_MAIL_DIR + ':' + listname + '.DIS';
X    IF DEBUG THEN BEGIN
X      WRITELN ('  listname is ', listname);
X      WRITELN ('  listfilename is ', listfilename);
X    END;
X
X    (*  check to find file... *)
X    OPEN (FILE_VARIABLE := list_file,
X`009  FILE_NAME := listfilename,
X`009  HISTORY := OLD,
X`009  SHARING := READWRITE,
X`009  ERROR := CONTINUE);
X    IF (STATUS (list_file) <> 0) THEN BEGIN  (*  couldn't find the file  *)
X      IF DEBUG THEN WRITELN ('  Couldn''t find ', listfilename);
X      start_reply;
X      write_varalfa`032
V        ('List ' + listname + ' does not exist or is not currently available.
X');
X      write_varalfa ('');
X      write_varalfa`032
V        ('Use the LISTS command to get a list of mailing lists for this site.
X');
X      end_reply;
X    END
X    ELSE BEGIN
X      CLOSE (FILE_VARIABLE := list_file, DISPOSITION := SAVE);
X      (*  SEND THEM THE FILE  *)
X      error_in_command := FALSE;
X      start_reply;
X      copy_file (MAILSERV_MAIL_DIR + ':', listname + '.DIS');
X      end_reply;
X    END;
X  END;
X  send_list_routine := SS$_NORMAL;
XEND;  (*  send_list_routine  *)
X
X(***********************************************************************)
X(*                                                                     *)
X(*  SUBSCRIBE_ROUTINE - handles the SUBSCRIBE verb.                    *)
X(*                                                                     *)
X(***********************************************************************)
X[global] FUNCTION subscribe_routine : UNSIGNED;
X
XVAR
X  list_file : text;
X  listfilename : varalfa;
X  listname, listmember, user_address : var80;
X  ret_buffer : PACKED ARRAY [1..255] OF CHAR;
X  ret_buffer_len : UNSIGNED;
X  found_a_match : boolean;
XBEGIN
X
X  IF DEBUG THEN WRITELN ('Entering routine SUBSCRIBE_ROUTINE');
X
X  (*  assume error in command  *)
X  error_in_command := TRUE;
X
X  (*  if mailing lists not enabled (the logical name isn't defined) tell
X       them so.  *)
X `032
X  ret_status := $TRNLOG (lognam := MAILSERV_MAIL_DIR, rslbuf := ret_buffer);
X  IF DEBUG THEN WRITELN`032
X    ('  return status of $TRNLOG on pmdf_maillist_dir', ret_status);
X
X  IF (NOT ODD (ret_status)) OR
X     (ret_status = SS$_NOTRAN) THEN BEGIN  (*  i.e. no logical name  *)
X    IF DEBUG THEN WRITELN ('  Writing ''lists not enabled'' message');
X    start_reply;
X    write_varalfa ('Mailing lists are not currently enabled at this site.');
X    end_reply;
X  END
X  ELSE BEGIN
X    (*  get the list name  *)
X    IF DEBUG THEN WRITELN ('  Getting list name.');
X    ret_buffer_len := 0;
X    ret_status := CLI$GET_VALUE ('SUBS_P1', ret_buffer, ret_buffer_len);
X    IF DEBUG THEN WRITELN ('  return stat of cli$get_value = ', ret_status);
X    IF DEBUG THEN WRITELN ('  Length of list name = ', ret_buffer_len);
X    IF NOT ODD (ret_status) THEN`032
X      abort_it ('error getting p1 in SUBSCRIBE_ROUTINE');
X    listname := SUBSTR (ret_buffer, 1, MIN (ret_buffer_len, UINT(80)));
X    listfilename := MAILSERV_MAIL_DIR + ':' + listname + '.DIS';
X    IF DEBUG THEN BEGIN
X      WRITELN ('  listname is ', listname);
X      WRITELN ('  listfilename is ', listfilename);
X    END;
X
X    OPEN (FILE_VARIABLE := list_file,
X`009  FILE_NAME := listfilename,
X`009  HISTORY := OLD,
X`009  SHARING := READONLY,
X`009  ERROR := CONTINUE);
X    IF (STATUS (list_file) <> 0) THEN BEGIN  (*  couldn't find the file  *)
X      IF DEBUG THEN WRITELN ('  Couldn''t find ', listfilename);
X      start_reply;
X      write_varalfa`032
V        ('List ' + listname + ' does not exist or is not currently available.
X');
X      write_varalfa ('');
X      write_varalfa`032
V        ('Use the LISTS command to get a list of mailing lists for this site.
X');
X      end_reply;
X    END
X    ELSE BEGIN
X      (*  look for their return address in the mailing list  *)
X      RESET (list_file);
X
X      (*  make return address easier to handle  *)
X      user_address :=`032
X        SUBSTR(return_address.body,1,MIN (return_address.length,80));
X      IF DEBUG THEN WRITELN ('  user address is ', user_address);
X      found_a_match := FALSE;
X      WHILE (NOT EOF (list_file)) and (NOT found_a_match) DO BEGIN
X        READLN (list_file, listmember);
X        IF (upcase_var80 (listmember) = upcase_var80 (user_address)) THEN
X          found_a_match := TRUE;
X      END;
X      CLOSE (FILE_VARIABLE := list_file, DISPOSITION := SAVE);
X
X      IF found_a_match THEN BEGIN  (*  already in this list  *)
X        IF DEBUG THEN WRITELN ('  address already found in the list');
X        start_reply;
X        write_varalfa ('The address:');`032
X        write_varalfa ('');
X        write_varalfa (user_address);
X        write_varalfa ('');
X        write_varalfa ( 'is already in the ' + listname + ' mailing list.');
X        end_reply;
X      END
X      ELSE BEGIN   (*  need to add them to the list  *)
X        OPEN (FILE_VARIABLE := list_file,
X              FILE_NAME := listfilename,
X`009      HISTORY := OLD,
X`009      SHARING := READWRITE,
X`009      ERROR := CONTINUE);
X        EXTEND (list_file);
X        WRITELN (list_file, user_address);
X        CLOSE (FILE_VARIABLE := list_file, DISPOSITION := SAVE);
X
X        (*  tell them about it  *)
X        IF DEBUG THEN WRITELN ('  address was appended to list');
X        error_in_command := FALSE;
X        start_reply;
X        write_varalfa ('The address:');
X`009write_varalfa ('');
X        write_varalfa (user_address);
X        write_varalfa ('');
V        write_varalfa ('has been added to the ' + listname + ' mailing list.'
X);
X        end_reply;
X      END;
X    END;
X  END;
X  subscribe_routine := SS$_NORMAL;
XEND;  (*  subscribe_routine  *)
X
X(***********************************************************************)
X(*                                                                     *)
X(*  UNSUBSCRIBE_ROUTINE - handles the UNSUBSCRIBE verb.                *)
X(*                                                                     *)
X(***********************************************************************)
X[GLOBAL] FUNCTION unsubscribe_routine : UNSIGNED;
X
XVAR
X  list_file, new_file : TEXT;
X  listfilename : varalfa;
X  listname, listmember, user_address : var80;
X  ret_buffer : PACKED ARRAY [1..255] OF CHAR;
X  ret_buffer_len : UNSIGNED;
X  found_a_match : BOOLEAN;
X  rename_status : INTEGER;
XBEGIN
X
X  IF DEBUG THEN WRITELN ('Entering routine UNSUBSCRIBE_ROUTINE');
X
X  (*  assume error in command  *)
X  error_in_command := TRUE;
X
X  (*  if mailing lists not enabled (the logical name isn't defined) tell
X       them so.  *)
X `032
X  ret_status := $TRNLOG (lognam := MAILSERV_MAIL_DIR, rslbuf := ret_buffer);
X  IF DEBUG THEN WRITELN`032
X    ('  return status of $TRNLOG on pmdf_maillist_dir', ret_status);
X
X  IF (NOT ODD (ret_status)) OR
X     (ret_status = SS$_NOTRAN) THEN BEGIN  (*  i.e. no logical name  *)
X    IF DEBUG THEN WRITELN ('  Writing ''lists not enabled'' message');
X    start_reply;
X    write_varalfa ('Mailing lists are not currently enabled at this site.');
X    end_reply;
X  END
X  ELSE BEGIN
X    (*  get the list name  *)
X    IF DEBUG THEN WRITELN ('  Getting list name.');
X    ret_buffer_len := 0;
X    ret_status := CLI$GET_VALUE ('UNSU_P1', ret_buffer, ret_buffer_len);
X    IF DEBUG THEN WRITELN ('  return stat of cli$get_value = ', ret_status);
X    IF DEBUG THEN WRITELN ('  Length of list name = ', ret_buffer_len);
X    IF NOT ODD (ret_status) THEN`032
X      abort_it ('error getting p1 in UNSUBSCRIBE_ROUTINE');
X    listname := SUBSTR (ret_buffer, 1, MIN (ret_buffer_len, UINT(80)));
X    listfilename := MAILSERV_MAIL_DIR + ':' + listname + '.DIS';
X    IF DEBUG THEN BEGIN
X      WRITELN ('  listname is ', listname);
X      WRITELN ('  listfilename is ', listfilename);
X    END;
X
X    OPEN (FILE_VARIABLE := list_file,
X`009  FILE_NAME := listfilename,
X`009  HISTORY := OLD,
X`009  SHARING := READONLY,
X`009  ERROR := CONTINUE);
X    IF (STATUS (list_file) <> 0) THEN BEGIN  (*  couldn't find the file  *)
X      IF DEBUG THEN WRITELN ('  Couldn''t find ', listfilename);
X      start_reply;
X      write_varalfa`032
V        ('List ' + listname + ' does not exist or is not currently available.
X');
X      write_varalfa ('');
X      write_varalfa`032
V        ('Use the LISTS command to get a list of mailing lists for this site.
X');
X      end_reply;
X    END
X    ELSE BEGIN
X      (*  for now, assume that most requests will be accurate, so we'll`032
X          rewrite the mailing list each time for a UNSUB command, meaning
X          that we do an unnecessary rewrite when the unsub isn't accurate
X      *)
X
X      OPEN (FILE_VARIABLE := new_file,
X   `009    FILE_NAME := listfilename,
X`009    HISTORY := NEW,
X`009    SHARING := READWRITE,
X`009    ERROR := CONTINUE);
X      IF (STATUS (new_file) <> 0) THEN`032
X        abort_it ('Unable to create new mailing list in UNSUBSCRIBE.');
X
X      (*  copy over file, looking to skip the current user's address  *)
X
X      RESET (list_file);
X      REWRITE (new_file);
X
X      (*  make return address easier to handle  *)
X      user_address :=`032
X        SUBSTR(return_address.body,1,MIN (return_address.length,80));
X      IF DEBUG THEN WRITELN ('  user address is ', user_address);
X
X      found_a_match := FALSE;
X      WHILE (NOT EOF (list_file)) DO BEGIN
X        READLN (list_file, listmember);
X        IF (upcase_var80 (listmember) = upcase_var80 (user_address)) THEN
X          found_a_match := TRUE
X        ELSE`032
X          WRITELN (new_file, listmember);
X      END;
X
X      CLOSE (FILE_VARIABLE := list_file, DISPOSITION := DELETE);
X      CLOSE (FILE_VARIABLE := new_file, DISPOSITION := SAVE);
X      RENAME_FILE (listfilename, ';1', rename_status);
X      IF NOT ODD (rename_status) THEN BEGIN
X        WRITELN ('Cannot rename new mailing list to ;1');
X        WRITELN ('  Please check for multiple versions.');
X      END;
X
X      IF found_a_match THEN BEGIN  (*  already in this list  *)
X        IF DEBUG THEN WRITELN ('  address removed from list');
X        error_in_command := FALSE;
X        start_reply;
X        write_varalfa ('The address:');
X        write_varalfa ('');
X        write_varalfa (user_address);
X        write_varalfa ('');
X        write_varalfa`032
X          ('has been removed from the ' + listname + ' mailing list.');
X        end_reply;
X       `032
X      END
X      ELSE BEGIN   (*  need to add them to the list  *)
X        IF DEBUG THEN WRITELN ('  address not found in list');
X        start_reply;
X        write_varalfa ('The address:');
X        write_varalfa ('');
X        write_varalfa (user_address);
X        write_varalfa ('');
X        write_varalfa ('was not found in the '+ listname + ' mailing list.');
X        write_varalfa ('');
X        write_varalfa`032
X('Please send a note to the Postmaster of this site if you have questions.');
X        end_reply;
X      END;
X    END;
X  END;
X  unsubscribe_routine := SS$_NORMAL;
XEND;  (*  unsubscribe_routine  *)
X
X(************************************************************************)
X(*                                                                      *)
X(*  HELP_ROUTINE - process the HELP command                             *)
X(*                                                                      *)
X(************************************************************************)
X[global] FUNCTION help_routine : UNSIGNED;
X
XVAR
X  filename : vstring;
XBEGIN
X  IF DEBUG THEN WRITELN ('Entering routine HELP_ROUTINE');
X  start_reply;
X  copy_file (MAILSERV_FILES_DIR , '[000000]help.txt');
X  end_reply;
X  help_routine := SS$_NORMAL;
XEND;  (*  help_routine  *)
X
X(************************************************************************)
X(*                                                                      *)
X(*  LISTS_ROUTINE - handle the LISTS command                            *)
X(*                                                                      *)
X(************************************************************************)
X[global] FUNCTION lists_routine : UNSIGNED;
X
XVAR
X  ret_buffer : PACKED ARRAY [1..255] OF CHAR;
X  ret_status : UNSIGNED;
XBEGIN
X  IF DEBUG THEN WRITELN ('Entering routine LISTS_ROUTINE');
X
X  (*  if mailing lists not enabled (the logical name isn't defined) tell
X       them so.  *)
X `032
X  ret_status := $TRNLOG (lognam := MAILSERV_MAIL_DIR, rslbuf := ret_buffer);
X  IF DEBUG THEN WRITELN`032
X    ('  return status of $TRNLOG on pmdf_maillist_dir', ret_status);
X
X  IF (NOT ODD (ret_status)) OR
X     (ret_status = SS$_NOTRAN) THEN BEGIN  (*  i.e. no logical name  *)
X    start_reply;
X    write_varalfa`032
X      ('Sorry, mailing lists are not currently enabled on this server.');
X    end_reply;
X  END
X  ELSE BEGIN
X    start_reply;
X    copy_file (MAILSERV_MAIL_DIR + ':' , 'LISTS.TXT');
X    end_reply;
X  END;
X  lists_routine := SS$_NORMAL;
XEND; (*  lists_routine  *)
X
X(************************************************************************)
X(*                                                                      *)
X(*  INDEX_ROUTINE - handle the INDEX command                            *)
X(*                                                                      *)
X(************************************************************************)
X[global] FUNCTION index_routine : UNSIGNED;
X
XBEGIN
X  IF DEBUG THEN WRITELN ('Entering routine INDEX_ROUTINE');
X  start_reply;
X  copy_file (MAILSERV_FILES_DIR , '[000000]index.txt');
X  end_reply;
X  index_routine := SS$_NORMAL;
XEND; (*  index_routine  *)
X
X(***************************************************************************)
X(*                                                                         *)
X(*  GET_RETURN_ADDRESS - get the return address from the incoming message  *)
X(*  and work through the message down to the text.                         *)
X(*                                                                         *)
X(***************************************************************************)
XPROCEDURE get_return_address;
X
XBEGIN
X  (* tell QU_ to read it *)
X  IF DEBUG THEN BEGIN`032
X    writeln ('Entering routine GET_RETURN_ADDRESS');
X    write ('  Accessing message file "');
X    writevstring (output, filename);
X    writeln ('".');
X  END;
X  IF rp_isbad (qu_rinit (filename, return_address)) THEN
X    abort_it (' error in qu_rinit in get_return_address');
X  IF DEBUG THEN BEGIN
X    write ('  Message is from: "');
X    writevstring (output, return_address);
X    writeln ('".');
X  END;
X
X  (*  read any and all addresses, we don't care about them  *)
X  WHILE qu_radr (to_address) = RP_AOK DO BEGIN END;
X
X  (*  read header from input message  *)
X  IF rp_isbad (he_read_header (header_stuff, qu_rtxt)) THEN
X    abort_it (' error reading message header');
X
X  (*  get the from_to_use  *)
X  IF (header_stuff[he_from] <> nil) THEN
X    from_to_use := header_stuff[he_from]`094.ltext
X  ELSE BEGIN
X    from_to_use.length := return_address.length;
X    FOR i := 1 to return_address.length DO
X      from_to_use.body[i] := return_address.body[i];
X  END;
XEND;  (*  get return address  *)
X
X(**************************************************************************)
X(*                                                                        *)
X(*  WRITE_PARSE_ERROR_MSG - write a message explaining the parse error in *)
X(*  the command.                                                          *)
X(*                                                                        *)
X(**************************************************************************)
XPROCEDURE write_parse_error_msg;
X
XVAR
X  curr_ptr : text_line_ptr;
X  i : INTEGER;
X
XBEGIN
X  IF DEBUG THEN WRITELN ('Entering routine WRITE_PARSE_ERROR_MSG');
X  write_varalfa ('>' +`032
X    substr(current_command.body,1,MIN(current_command.length,ALFA_SIZE-1)));
X  write_varalfa ('');
X  write_varalfa ('This command produced the following error:');
X  write_varalfa ('');
X
X  curr_ptr := error_line_head;
X  WHILE (curr_ptr <> nil) DO BEGIN
X    write_varalfa ('> ' +
V      substr(curr_ptr`094.line.body,1,min(curr_ptr`094.line.length,ALFA_SIZE)
X));
X    curr_ptr := curr_ptr`094.next;
X  END;  (*  while  *)
X
X  dispose_text_list (error_line_head);
X  error_line_tail := nil;
X
XEND;  (*  write_parse_error_msg  *)
X
X(*************************************************************************)
X(*                                                                       *)
X(*  DO_A_COMMAND - process one command from the input message            *)
X(*                                                                       *)
X(*************************************************************************)
XPROCEDURE do_a_command;
X
XVAR
X  ret_status : UNSIGNED;
X
XBEGIN
X
X  IF DEBUG THEN WRITELN ('Entering routine DO_A_COMMAND');
X
X  (*  establish error handler to trap CLI errors  *)
X  ESTABLISH (my_handler);
X
X  ret_status := CLI$DCL_PARSE(
V    SUBSTR(current_command.body,1,current_command.length),mailserv_tables,,,)
X;
X
X  (*  revert the handler first thing  *)
X  REVERT;
X
X  IF DEBUG THEN WRITELN ('  DCL_PARSE returned status of ', ret_status);
X  IF ODD (ret_status) THEN BEGIN`009(*  if the parse was okay  *)
X    ret_status := CLI$DISPATCH();
X  END
X  ELSE BEGIN`009(*  error in parse  *)
X    error_in_command := true;
X    start_reply;
X
X    (*  if dcl_parse didn't signal an error, but did return an error status,
V        call $putmsg with the process error routine to fill in an error line
X *)
X    IF (error_line_head = NIL) THEN BEGIN
X      new (error_line_head);
X      IF NOT ODD ($GETMSG (ret_status, error_line_head`094.line.length,`032
X        error_line_head`094.line.body,1,)) THEN`032
X        abort_it ('Error calling $GETMSG in DO_A_COMMAND');
V      IF DEBUG THEN WRITELN ('  Text from $GETMSG: ', error_line_head`094.lin
Xe);
X    END;
X    write_parse_error_msg;
X    end_reply;
X  END;
X
X  log_it;
X
XEND;  (*  do_a_command  *)
X
X(*************************************************************************)
X(*                                                                       *)
X(*  DO_THE_MESSAGE - process the current message                         *)
X(*                                                                       *)
X(*************************************************************************)
XPROCEDURE do_the_message;
X
XVAR
X  cmd_read_status : rp_replyval;`009(*  status of reading input line  *)
X  command_limit_text : var80;`009(*  textual form of command_limit  *)
X
XBEGIN
X
X  get_return_address;
X
X  IF (return_address.length > 0) THEN BEGIN
X    commands_processed := 0;  (*  reset number of commands processed  *)
X    error_in_command := FALSE;  (*  reset error status  *)
X
X    cmd_read_status := qu_rtxt (current_command);
X
X    (*  while we have commands and while there haven't been any errors. *)
X    WHILE ((cmd_read_status = RP_OK) AND
X           (commands_processed < command_limit) AND
X           (not error_in_command)) DO BEGIN
X
X      IF DEBUG THEN BEGIN
X        WRITE (' command = ');
X        writebigvstring (output,current_command);
X      END;
X
X      (*  take off the LF that qu_rtxt put on  *)
X      current_command.length := current_command.length - 1;
X
X      trim_command;
X
X      IF (current_command.length > 0) THEN BEGIN;  (*  if not a blank  *)
X        do_a_command;
X        commands_processed := commands_processed + 1;
V        IF DEBUG THEN WRITELN ('  Commands processed = ', commands_processed)
X;
X      END;
X
X      (*  read next line from the message  *)
X      cmd_read_status := qu_rtxt (current_command);
X    END;  (*  while  *)
X
X    (*  check whether end of file, parse error, or too many commands and send
X        a message if necessary  *)
X    if (cmd_read_status <> RP_OK) THEN BEGIN
V      IF DEBUG THEN WRITELN ('  QU_RTXT returned a status of ', cmd_read_stat
Xus);
X    END;
X    if (commands_processed = command_limit) THEN BEGIN
V      IF DEBUG THEN WRITELN ('  Command limit of ',command_limit,' was reache
Xd.');
X    END;
X    if error_in_command THEN BEGIN
X      if DEBUG THEN WRITELN ('  Error in last command processed.');
X    END;
X
X    (*  check for command over limit with more commands to do  *)
X    IF (NOT (error_in_command)) AND`032
X       (commands_processed >= command_limit) AND
X       (cmd_read_status = RP_OK) THEN BEGIN
X      `032
X      (*  okay, no errors, hit command limit, and have a new command  *)
X
X      (*  start_reply uses current command for subject  *)
X      current_command.body := 'Exceeded command limit';
X      current_command.length := 22;
X
X      IF DEBUG THEN WRITELN ('  Sending "exceeded command limit" message');
X      start_reply;
X      writev (command_limit_text, command_limit:1);
X      write_varalfa ('You have reached the command limit of ' +
X        command_limit_text + '.  Any further');
X      write_varalfa ('lines have been ignored.');
X      end_reply;
X    END;
X
X  END;  (*  if  *)
X
X
X  (*  done with input message  *)
X  rp := qu_rend;
X  IF DEBUG THEN writeln ('  Finished with this message.');
X
XEND;  (*  do_the_message  *)
X
X(**************************************************************************)
X(*                                                                        *)
X(*  INIT_PUPPY - init stuff                                               *)
X(*                                                                        *)
X(**************************************************************************)
XPROCEDURE init_puppy;
X
XVAR
X  ret_buf : packed array [1..20] of char;
X  ret_len : $UWORD;
X  ret_stat : unsigned;
X
XBEGIN
-+-+-+-+-+ End of part 3 +-+-+-+-+-
