Skip to content
Snippets Groups Projects
Select Git revision
  • 4c18bf803900d6073355ce26943fe9f61b7b2758
  • release default protected
  • more-testing
  • attempt-vax90b1
  • attempt-1
  • conversion protected
  • linux
  • v0.9.1 protected
  • v0.9.0 protected
9 results

pmdf.com

Blame
  • user avatar
    Kevin Lyda authored
    1a9e6c25
    History
    pmdf.com 25.26 KiB
    $set nover
    $copy sys$input BULLETIN_MASTER.PAS
    $deck
    %INCLUDE '[-]ATTRIB.INC'
    PROGRAM bulletin_master (output, outbound,
                             %INCLUDE '[-]APFILES.INC',
                             %INCLUDE '[-]MMFILES.INC',
                             %INCLUDE '[-]QUFILES.INC');
    
    (*******************************************************************)
    (*                                                                 *)
    (*      Authors:   Ned Freed (ned@ymir.bitnet)                     *)
    (*                 Mark London (mrl%mit.mfenet@nmfecc.arpa)        *)
    (*                 8/18/88                                         *)
    (*                                                                 *)
    (*******************************************************************)
    
      CONST
           %INCLUDE '[-]UTILCONST.INC'
           %INCLUDE '[-]OSCONST.INC'
           %INCLUDE '[-]APCONST.INC'
           %INCLUDE '[-]MMCONST.INC'
           %INCLUDE '[-]HECONST.INC'
           %INCLUDE '[-]LOGCONST.INC'
           %INCLUDE '[-]SYCONST.INC'
    
      TYPE
           %INCLUDE '[-]UTILTYPE.INC'
           %INCLUDE '[-]OSTYPE.INC'
           %INCLUDE '[-]APTYPE.INC'
           %INCLUDE '[-]SYTYPE.INC'
           %INCLUDE '[-]MMTYPE.INC'
           %INCLUDE '[-]HETYPE.INC'
           %INCLUDE '[-]LOGTYPE.INC'
    
      string = varying [alfa_size] of char;
    
      VAR
           %INCLUDE '[-]UTILVAR.INC'
           %INCLUDE '[-]OSVAR.INC'
           %INCLUDE '[-]APVAR.INC'
           %INCLUDE '[-]QUVAR.INC'
           %INCLUDE '[-]MMVAR.INC'
           %INCLUDE '[-]HEVAR.INC'
           %INCLUDE '[-]LOGVAR.INC'
    
           outbound : text;
    
      (* Place to store the channel we are servicing *)
       mail_channel : mm_channel_ptr := nil;
    
      (* MM status control flag *)
    
      mm_status          : (uninitialized, initialized, sending) := uninitialized;
    
      filename       : vstring;
    
      %INCLUDE '[-]UTILDEF.INC'
      %INCLUDE '[-]OSDEF.INC'
      %INCLUDE '[-]APDEF.INC'
      %INCLUDE '[-]HEDEF.INC'
      %INCLUDE '[-]LOGDEF.INC'
      %INCLUDE '[-]MMDEF.INC'
      %INCLUDE '[-]QUDEF.INC'
    
      (* Declare interface routines to BULLETIN *)
    
      procedure INIT_MESSAGE_ADD (
        in_folder : [class_s] packed array [l1..u1 : integer] of char;
        in_from : [class_s] packed array [l2..u2 : integer] of char;
        in_descrip : [class_s] packed array [l3..u3 : integer] of char;
        var ier : boolean); extern;
    
      procedure WRITE_MESSAGE_LINE (
        in_line : [class_s] packed array [l1..u1 : integer] of char); extern;
    
      procedure FINISH_MESSAGE_ADD; extern;
    
      PROCEDURE warn_master (message : varying [len1] of char);
    
        BEGIN (* warn_master *)
          writeln;
          os_write_datetime (output);
          writeln (message);
          END; (* warn_master *)
    
      (* abort program. *)
    
      PROCEDURE abort_master (message : varying [len1] of char);
    
        BEGIN (* abort_master *)
          warn_master (message);
          halt;
          END; (* abort_master *)
    
    (* activate_mm fires up the MM package and performs related startup chores. *)
    
    function activate_mm (is_master : boolean) : rp_replyval;
    
    var
      mm_init_reply : rp_replyval; found : boolean; mail_chan_text : ch_chancode;
      stat : integer;
    
      (* Place to store the protocol that we are providing/servicing *)
      protocol_name : varying [10] of char;
    
    begin (* activate_mm *)
      (* Set up the name of the protocol we are servicing/providing *)
      stat := $TRNLOG (lognam := 'PMDF_PROTOCOL',
                       rslbuf := protocol_name.body,
                       rsllen := protocol_name.length);
      if (not odd (stat)) or (stat = SS$_NOTRAN) then protocol_name := 'IN%';
      mm_status := initialized;
      mm_init_reply := mm_init;
      mail_chan_text := '            ';
      stat := $TRNLOG (lognam := 'PMDF_CHANNEL', rslbuf := mail_chan_text);
      if (not odd (stat)) or (stat = SS$_NOTRAN) then
        mail_chan_text := 'l           ';
      if rp_isgood (mm_init_reply) then begin
        mail_channel := mm_lookup_channel (mail_chan_text);
        if mail_channel = nil then mail_channel := mm_local_channel;
      end else mail_channel := mm_local_channel;
      activate_mm := mm_init_reply;
    end; (* activate_mm *)
    
      (* initialize outbound, mm_ and qu_ *)
    
      PROCEDURE init;
    
        VAR fnam : vstring;
            i : integer;
    
        BEGIN (* init *)
          os_jacket_access := true;
          (* Initialize subroutine packages *)
          IF rp_isbad (activate_mm (false)) THEN
            abort_master ('Can''t initialize MM_ routines');
          IF rp_isbad (qu_init) THEN
            abort_master ('Can''t initialize QU_ routines');
          fnam.length := 0;
          IF NOT os_open_file (outbound, fnam, exclusive_read) THEN
            abort_master ('Can''t open outbound file');
          END; (* init *)
    
    
    procedure return_bad_messages (var bad_address : vstring);
    
    label
      100;
    
    var
      line : vstring;
      bigline : bigvstring; result : rp_bufstruct;
      pmdfenvelopefrom : vstring;
      temp_line : vstringlptr;
    
      procedure try_something (rp_error : integer; routine : string);
    
      begin (* try_something *)
        if rp_isbad (rp_error) then begin
          mm_wkill; mm_status := initialized; goto 100;
        end;
      end; (* try_something *)
    
    begin (* return_bad_messages *)
      if mm_status = uninitialized then
        try_something (activate_mm (false), 'mm_init');
      mm_status := sending;
      try_something (mm_sbinit, 'mm_sbinit');
      initstring (line, 'postmaster@                             ', 11);
      catvstring (line, mm_local_channel^.official_hostname);
      try_something (mm_winit (mail_channel^.chancode, line), 'mm_winit');
      initstring (line,
                  'postmaster                              ', 10);
      try_something (mm_wadr (mail_channel^.official_hostname,
                                line), 'mm_wadr');
      try_something (mm_rrply (result), 'mm_rrply');
      try_something (result.rp_val, 'mm_rrply structure return');
      try_something (mm_waend, 'mm_waend');
      initstring (line, 'From: PMDF Mail Server <Postmaster@     ', 35);
      catvstring (line, mm_local_channel^.official_hostname);
      catchar (line, '>');
      catchar (line, chr (chr_lf));
      try_something (mm_wtxt (line), 'mm_wtxt');
      initstring (line, 'To: Postmaster                          ', 14);
      catchar (line, chr (chr_lf));
      try_something (mm_wtxt (line), 'mm_wtxt');
      initstring (line, 'Subject: Undeliverable mail             ', 27);
      catchar (line, chr (chr_lf));
      try_something (mm_wtxt (line), 'mm_wtxt');
      initstring (line, 'Date:                                   ', 6);
      os_cnvtdate (line);
      catchar (line, chr (chr_lf));
      try_something (mm_wtxt (line), 'mm_wtxt');
      line.length := 1; line.body[1] := chr (chr_lf);
      try_something (mm_wtxt (line), 'mm_wtxt');
      initstring (line, 'The message could not be delivered to:  ', 38);
      catchar (line, chr (chr_lf));
      try_something (mm_wtxt (line), 'mm_wtxt');
      line.length := 1; line.body[1] := chr (chr_lf);
      try_something (mm_wtxt (line), 'mm_wtxt');
      initstring (line, 'Addressee:                              ', 11);
      catvstring (line, bad_address);
      catchar (line, chr (chr_lf));
      try_something (mm_wtxt (line), 'mm_wtxt');
      initstring (line, 'Reason: No such bulletin folder.        ', 32);
      catchar (line, chr (chr_lf));
      try_something (mm_wtxt (line), 'mm_wtxt');
      line.length := 1; line.body[1] := chr (chr_lf);
      try_something (mm_wtxt (line), 'mm_wtxt');
      initstring (line, '----------------------------------------', 40);
      catchar (line, chr (chr_lf));
      catchar (line, chr (chr_lf));
      try_something (mm_wtxt (line), 'mm_wtxt');
      try_something (qu_rkill, 'qu_rkill');
      try_something (qu_rinit (filename, pmdfenvelopefrom), 'qu_rinit');
      while rp_isgood (qu_radr (line)) do begin end;
      while rp_isgood (qu_rtxt (bigline)) do
        try_something (mm_bigwtxt (bigline), 'mm_wtxt');
      mm_status := initialized;
      try_something (mm_wtend, 'mm_wtend');
      try_something (mm_rrply (result), 'mm_rrply');
      try_something (result.rp_val, 'mm_rrply structure return');
    100:
    end; (* return_bad_messages *)
    
      (* submit messages to BULLETIN *)
    
      PROCEDURE dosubmit;
    
        VAR fromaddr, toaddr, tombox, name : vstring;
            retval : rp_replyval;
            line : bigvstring;
            ier, done : boolean;
            i : integer;
    
        BEGIN (* dosubmit *)
          WHILE NOT eof (outbound) DO BEGIN
            readvstring (outbound, filename, 0);
            IF rp_isgood (qu_rinit (filename, fromaddr)) THEN BEGIN
              done := false;
              FOR i := 1 TO fromaddr.length DO
                fromaddr.body[i] := upper_case (fromaddr.body[i]);
              IF rp_isgood (qu_radr (toaddr)) THEN BEGIN
                REPEAT
                  retval := qu_radr (name);
                  UNTIL rp_isbad (retval);
                mm_parse_address (toaddr, name, tombox, TRUE, FALSE, 0);
                FOR i := 1 TO tombox.length DO
                  tombox.body[i] := upper_case (tombox.body[i]);
                INIT_MESSAGE_ADD (substr (tombox.body, 1, tombox.length),
                                  'IN%',' ', ier);
    (* The parameter with 'IN%', causes bulletin to search for the From line: *)
    (*                            substr (fromaddr.body, 1, fromaddr.length), *)
                IF ier THEN BEGIN
                  WHILE rp_isgood (qu_rtxt (line)) DO BEGIN
                    IF line.length > 0 THEN line.length := pred (line.length);
                    WRITE_MESSAGE_LINE (substr (line.body, 1, line.length));
                    END; (* while *)
                  FINISH_MESSAGE_ADD;
                  done := true;
                END ELSE BEGIN
    	      warn_master ('Error opening folder ' +
                                  substr (tombox.body, 1, tombox.length));
    	      return_bad_messages(tombox);
                  done := true;
                END;
    	  END
              ELSE warn_master ('Can''t read To: address in file ' +
                                substr (filename.body, 1, filename.length));
              if done then qu_rend else qu_rkill;
              END
            ELSE warn_master ('Can''t open queue file ' +
                              substr (filename.body, 1, filename.length));
            END; (* while *)
          END; (* dosubmit *)
    
      BEGIN (* bulletin_master *)
        init;
        dosubmit;
        mm_end (true);
        qu_end;
        END. (* bulletin_master *)
    $eod 
    $copy sys$input MASTER.COM
    $deck
    $ ! MASTER.COM - Initiate delivery of messages queued on a channel
    $ !
    $ ! Modification history and parameter definitions are at the end of this file.
    $ !
    $ set noon
    $ !
    $ ! Clean up and set up channel name, if on hold just exit
    $ !
    $ channel_name = f$edit(p1, "COLLAPSE,LOWERCASE")
    $ hold_list = "," + f$edit(f$logical("PMDF_HOLD"), "COLLAPSE,LOWERCASE") + ","
    $ if f$locate("," + channel_name + ",", hold_list) .lt. -
         f$length(hold_list) then exit
    $ define/process pmdf_channel "''channel_name'"
    $ !
    $ ! Save state information, set up environment properly
    $ !
    $ save_directory = f$environment("DEFAULT")
    $ set default pmdf_root:[queue]
    $ save_protection = f$environment("PROTECTION")
    $ set protection=(s:rwed,o:rwed,g,w)/default
    $ save_privileges = f$setprv("NOSHARE")
    $ !
    $ if f$logical("PMDF_DEBUG") .eqs. "" then on control_y then goto out
    $ !
    $ ! Create listing of messages queued on this channel.
    $ !
    $ if p3 .eqs. "" then p3 = "1-JAN-1970"
    $ dirlst_file = "pmdf_root:[log]" + channel_name + "_master_dirlst_" + -
      F$GETJPI ("", "PID") + ".tmp"
    $ define/process outbound 'dirlst_file'
    $ directory/noheader/notrailer/column=1/since="''p3'"/output='dirlst_file' -
      pmdf_root:[queue]'channel_name'_*.%%;*
    $ !
    $ ! Determine whether or not connection should really be made
    $ !
    $ if p2 .nes. "POLL" .and. -
         f$file_attributes(dirlst_file, "ALQ") .eq. 0 then goto out1
    $ !
    $ ! Handle various channels specially
    $ !
    $ if channel_name .eqs. "l" then goto local_channel
    $ if channel_name .eqs. "d" then goto DECnet_compatibility_channel
    $ if channel_name .eqs. "directory" then goto dir_channel
    $ if f$extract(0,5,channel_name) .eqs. "anje_"  then goto BITNET_channel
    $ if f$extract(0,4,channel_name) .eqs. "bit_"   then goto BITNET_channel
    $ if f$extract(0,5,channel_name) .eqs. "bull_"  then goto BULLETIN_channel
    $ if f$extract(0,3,channel_name) .eqs. "cn_"    then goto CN_channel
    $ if f$extract(0,5,channel_name) .eqs. "ctcp_"  then goto CTCP_channel
    $ if f$extract(0,3,channel_name) .eqs. "dn_"    then goto DECnet_channel
    $ if f$extract(0,6,channel_name) .eqs. "dsmtp_" then goto DSMTP_channel
    $ if f$extract(0,5,channel_name) .eqs. "etcp_"  then goto ETCP_channel
    $ if f$extract(0,5,channel_name) .eqs. "ftcp_"  then goto FTCP_channel
    $ if f$extract(0,4,channel_name) .eqs. "ker_"   then goto KER_channel
    $ if f$extract(0,5,channel_name) .eqs. "mail_"  then goto MAIL_channel
    $ if f$extract(0,5,channel_name) .eqs. "mtcp_"  then goto MTCP_channel
    $ if f$extract(0,5,channel_name) .eqs. "px25_"  then goto PX25_channel
    $ if f$extract(0,4,channel_name) .eqs. "tcp_"   then goto TCP_channel
    $ if f$extract(0,5,channel_name) .eqs. "test_"  then goto TEST_channel
    $ if f$extract(0,5,channel_name) .eqs. "uucp_"  then goto UUCP_channel
    $ if f$extract(0,5,channel_name) .eqs. "wtcp_"  then goto WTCP_channel
    $ if f$extract(0,6,channel_name) .eqs. "xsmtp_" then goto XSMTP_channel
    $ !
    $ ! This must be a PhoneNet channel (the default); set up and use MASTER
    $ !  Read the list of valid connection types for each channel.
    $ !
    $ cnt = f$integer("0")
    $ open/read/error=regular_master pmdf_data pmdf_root:[table]phone_list.dat
    $       list_loop:
    $               read/end=eof_list pmdf_data line
    $ !  Ignore comment lines.
    $               if (f$extract (0, 1, line) .eqs. "!") then -
                            goto list_loop
    $               line = f$edit (line, "COMPRESS,LOWERCASE")
    $ !  Get the channel name from the line read.
    $               chan = f$extract (0, f$locate(" ", line), line)
    $               if (chan .nes. channel_name) then -
    $                       goto list_loop
    $ !  Get the connection name
    $               name = f$edit(f$extract(f$locate(" ",line),255,line),"COLLAPSE")
    $ !  If none, then ignore the line
    $               if name .eqs. "" then -
                            goto list_loop
    $ !  Found at least one to try.
    $               cnt = cnt + 1
    $               @pmdf_root:[exe]all_master.com 'name'
    $               define PMDF_DEVICE TT
    $ !
    $ ! Define other logical names
    $ !
    $ define/user script             pmdf_root:[table.'channel_name']'name'_script.
    $ define/user ph_current_message pmdf_root:[log]'channel_name'_master_curmsg.tmp
    $ define/user option_file        pmdf_root:[table]'channel_name'_option.
    $ define/user di_transcript      pmdf_root:[log]di_'channel_name'_master.trn
    $ define/user ph_logfile         pmdf_root:[log]ph_'channel_name'_master.log
    $ define/user di_errfile         pmdf_root:[log]di_'channel_name'_master.log
    $ !
    $ !   This check attempts to verify that we are in fact the owner process of
    $ !   the device, TT.  If the device is sharable, then we ignore the
    $ !   owner.
    $ !
    $ if (f$getdvi("TT","pid") .nes. f$getjpi(0,"pid")) .and. -
         (f$getdvi("TT","shr") .eqs. "FALSE") then -
            goto list_loop
    $ !
    $ !  Run master to deliver the mail
    $ !
    $ run pmdf_root:[exe]master
    $ exit_stat = $status
    $ !
    $ ! Activate optional cleanup script to reset terminal/modem
    $ !
    $ if f$search("pmdf_root:[exe]''name'_cleanup.com") .nes. "" then -
         @pmdf_root:[exe]'name'_cleanup.com 'exit_stat'
    $ deallocate TT
    $ deassign TT
    $ deassign PMDF_DEVICE
    $ !
    $ !  If master does not exit normally, then try a different connection.
    $ !
    $ if exit_stat .ne. 1 then goto list_loop
    $ eof_list:
    $ close pmdf_data
    $ !
    $ !  If we found at least one connection type for this channel, then skip
    $ !  the attempt to use the conventional mechanism.
    $ !
    $ if cnt .gt. 0 then goto out_phonenet
    $ !
    $ regular_master:
    $ @pmdf_root:[exe]'channel_name'_master.com
    $ define PMDF_DEVICE TT
    $ !
    $ !  Define logical names
    $ !
    $ define/user script             pmdf_root:[table]'channel_name'_script.
    $ define/user ph_current_message pmdf_root:[log]'channel_name'_master_curmsg.tmp
    $ define/user option_file        pmdf_root:[table]'channel_name'_option.
    $ define/user di_transcript      pmdf_root:[log]di_'channel_name'_master.trn
    $ define/user ph_logfile         pmdf_root:[log]ph_'channel_name'_master.log
    $ define/user di_errfile         pmdf_root:[log]di_'channel_name'_master.log
    $ !
    $ run pmdf_root:[exe]master
    $ exit_stat = $status
    $ !
    $ !  Activate optional cleanup script to reset terminal/modem
    $ !
    $ if f$search("''channel_name'_cleanup.com") .nes. "" then -
         @pmdf_root:[exe]'channel_name'_cleanup.com 'exit_stat'
    $ deallocate TT
    $ deassign TT
    $ deassign PMDF_DEVICE
    $ !
    $ out_phonenet:
    $ if P4 .eqs. "POST" then wait 00:00:30
    $ goto out1
    $ !
    $ ! Directory channel
    $ !
    $ dir_channel:
    $ !
    $ run pmdf_root:[exe]dir_master
    $ goto out1
    $ !
    $ ! This is a DECnet channel; set up and use DN_MASTER
    $ !
    $ DECnet_channel:
    $ !
    $ ! Define other logical names
    $ !
    $ node_name = f$edit(channel_name - "dn_", "UPCASE")
    $ define/user ph_current_message pmdf_root:[log]'channel_name'_master_curmsg.tmp
    $ define/user option_file        pmdf_root:[table]'channel_name'_option.
    $ define/user di_transcript      pmdf_root:[log]di_'channel_name'_master.trn
    $ define/user ph_logfile         pmdf_root:[log]ph_'channel_name'_master.log
    $ define/user di_errfile         pmdf_root:[log]di_'channel_name'_master.log
    $ define/user pmdf_node          "''node_name'::""PMDF="""
    $ !
    $ run pmdf_root:[exe]dn_master
    $ goto out1
    $ !
    $ ! This is a BITNET channel; use BN_MASTER
    $ !
    $ BITNET_channel:
    $ !
    $ if channel_name .eqs. "bit_gateway" then goto BITNET_gateway
    $ run pmdf_root:[exe]bn_master
    $ goto out1
    $ !
    $ ! This is the BITNET gateway channel; use BN_GATEWAY
    $ !
    $ BITNET_gateway:
    $ !
    $ run pmdf_root:[exe]bn_gateway
    $ goto out1
    $ !
    $ ! This is a BULLETIN channel; use BULLETIN_MASTER
    $ !
    $ BULLETIN_channel:
    $ !
    $ run pmdf_root:[exe]bulletin_master
    $ goto out1
    $ !
    $ ! This is a Tektronix TCP channel; use TCP_MASTER
    $ !
    $ TCP_channel:
    $ !
    $ run pmdf_root:[exe]tcp_master
    $ goto out1
    $ !
    $ ! This is a CMU/Tektronix TCP channel; use CTCP_MASTER
    $ !
    $ CTCP_channel:
    $ !
    $ run pmdf_root:[exe]ctcp_master
    $ goto out1
    $ !
    $ ! This is a Wollongong TCP channel; use WTCP_MASTER
    $ !
    $ WTCP_channel:
    $ !
    $ ! Define other logical names
    $ !
    $ run pmdf_root:[exe]wtcp_master
    $ goto out1
    $ !
    $ ! This is a MultiNet TCP channel; use MTCP_MASTER
    $ !
    $ MTCP_channel:
    $ !
    $ run pmdf_root:[exe]mtcp_master
    $ goto out1
    $ !
    $ ! This is a Excelan TCP channel; use ETCP_MASTER
    $ !
    $ ETCP_channel:
    $ !
    $ run pmdf_root:[exe]etcp_master
    $ goto out1
    $ !
    $ ! This is an NRC Fusion TCP channel; use FTCP_MASTER
    $ !
    $ FTCP_channel:
    $ !
    $ run pmdf_root:[exe]ftcp_master
    $ goto out1
    $ !
    $ CN_channel:
    $ !
    $ ! Define other logical names
    $ !
    $ define/user script             pmdf_root:[table]'channel_name'_script.
    $ ! following may vary: should point to cnio's group
    $ define/table=lnm$process_directory lnm$temporary_mailbox lnm$group_000277
    $ !
    $ run/nodeb'p5' pmdf_root:[exe]cn_smtp_master
    $ goto out1
    $ !
    $ KER_channel:
    $ !
    $ ! kermit protocol is slave only. If we get here there has been a mistake.
    $ ! however we will just exit and no harm done.
    $ goto out1
    $ !
    $ ! This is a PhoneNet X25 channel; set up and use PX25_MASTER
    $ !
    $ PX25_channel:
    $ !
    $ ! Define other logical names
    $ !
    $ define/user ph_current_message pmdf_root:[log]'channel_name'_master_curmsg.tmp
    $ define/user option_file        pmdf_root:[table]'channel_name'_option.
    $ define/user di_transcript      pmdf_root:[log]'channel_name'_di_master.trn
    $ define/user ph_logfile         pmdf_root:[log]'channel_name'_ph_master.log
    $ define/user di_errfile         pmdf_root:[log]'channel_name'_di_master.log
    $ !
    $ run pmdf_root:[exe]PX25_master
    $ goto out1
    $ !
    $ ! This is a DEC/Shell channel; set up and use UUCP_MASTER
    $ !
    $ UUCP_channel:
    $ !
    $ ! Define other logical names
    $ !
    $ uucp_to_host = channel_name - "uucp_"
    $ define/user uucp_to_host       "''uucp_to_host'"
    $ define/user uucp_current_message -
      pmdf_root:[log]'channel_name'_master_curmsg.tmp
    $ define/user uucp_logfile       pmdf_root:[log]'channel_name'_master.logfile
    $ !
    $ run pmdf_root:[exe]UUCP_master
    $ uupoll = "$shell$:[usr.lib.uucp]uupoll"
    $ uupoll 'uucp_to_host'
    $ goto out1
    $ !
    $ ! This is a X.25 SMTP channel; set up and use XSMTP_MASTER
    $ !
    $ XSMTP_channel:
    $ !
    $ run pmdf_root:[exe]xsmtp_master
    $ goto out1
    $ !
    $ ! This is a DECNET SMTP channel; set up and use DSMTP_MASTER
    $ !
    $ DSMTP_channel:
    $ !
    $ run pmdf_root:[exe]dsmtp_master
    $ goto out1
    $ !
    $ ! Handle delivery on the local channel, MAIL_ channels, and
    $ ! the DECnet compatibility channel
    $ !
    $ MAIL_channel:
    $ local_channel:
    $ DECnet_compatibility_channel:
    $ open/read queue_file 'dirlst_file'
    $ local_loop:
    $   read/end=exit_local_loop/error=exit_local_loop  queue_file file_to_process
    $   priv_list = f$setprv("SYSPRV, DETACH")
    $   mail/protocol=pmdf_mailshr 'file_to_process'
    $   priv_list = f$setprv(priv_list)
    $ goto local_loop
    $ !
    $ exit_local_loop:
    $ close queue_file
    $ goto out1
    $ !
    $ ! This is a SMTP test channel, use TEST_SMTP_MASTER
    $ !
    $ TEST_channel:
    $ !
    $ ! Typically some form of redirection is needed here...
    $ deassign sys$input
    $ run pmdf_root:[exe]test_smtp_master
    $ goto out1
    $ !
    $ out1:
    $ delete 'dirlst_file';*
    $ !
    $ ! Common exit point - clean up things first
    $ !
    $ out:
    $ if f$logical("OUTBOUND") .nes. "" then deassign/process outbound
    $ if f$logical("PMDF_CHANNEL") .nes. "" then deassign/process pmdf_channel
    $ if f$logical("PMDF_DATA") .nes. "" then close pmdf_data
    $ if f$logical("PMDF_DEVICE") .eqs. "" then goto restore
    $ deallocate TT
    $ deassign TT
    $ deassign PMDF_DEVICE
    $ restore:
    $ !
    $ ! Restore saved stuff
    $ !
    $ set protection=('save_protection')/default
    $ set default 'save_directory'
    $ set process/priv=('save_privileges')
    $ !
    $ exit
    $ !
    $ ! Modification history:
    $ !
    $ ! This version by Ned Freed, 20-Jul-1986
    $ !
    $ ! Modified by Gregg Wonderly to allow multiple connections for each channel
    $ !   10-Oct-1986.
    $ ! Some additions by Ned Freed 30-Oct-86.
    $ ! Added CMU/Tektronix TCP channel (CTCP) /Kevin Carosso 6-Mar-1987
    $ ! Added Multinet TCP channel (MTCP) /Ned Freed 10-Mar-1987
    $ ! Added directory save/restore /Ned Freed 1-Jun-1987
    $ ! Added Excelan TCP channel (ETCP) /Ned Freed 9-Jul-1987
    $ ! Added MAIL, CNIO, KERMIT channel /Bob Smart 4-Jul-1987
    $ ! Added Warwick Jackson's PhoneNet X25 support /Ned Freed 5-Sep-87
    $ ! Added X25 SMTP channel SX25_ /Goeran Bengtsson, Mats Sundvall 24-Jul-87
    $ ! Added NRC Fusion TCP channel (FTCP) /Kevin Carosso 12-Jan-1988
    $ ! Added a variant of Randy McGee's code to put a list of channels on hold
    $ !   /Ned Freed 9-Feb-1988
    $ ! Made this procedure save and restore a little more state information
    $ !   than it used to, including default protection and privileges. Also
    $ !   moved a bunch of the logical name assignments around to eliminate
    $ !   redundant code all over the place. /Ned Freed 10-Feb-1988
    $ ! Modified to allow P3 date/time paramter. /Ned Freed 23-Feb-1988
    $ ! Added support for Dennis Boylan's UUCP channel. /Ned Freed 28-Mar-1988
    $ ! Added Robert Smart's directory channel. /Ned Freed 21-Apr-1988
    $ ! Added support for Warwick Jackson's SMTP over X.25 and SMTP over
    $ !   DECnet channels. /Ned Freed 26-May-1988
    $ ! Added P4 and P5 parameters. /Ned Freed 10-Jun-1988
    $ ! Added code to call the TEST_SMTP_MASTER for testing. /Ned Freed 1-Jul-1988
    $ ! Added preliminary support for ANJE. /Ned Freed 7-Jul-1988
    $ ! Removed extra dispatch for WTCP_ channel. /Ned Freed 3-Sep-1988
    $ ! Added dispatch for BULL_ channel. /Ned Freed 28-Nov-1988
    $ ! Cleaned up error recovered and emergency exit -- close PHONE_LIST.DAT
    $ !   file when aborting. /Ned Freed 13-Dec-1988
    $ ! Additional error recovery cleanup -- use PMDF_DEVICE instead of TT to
    $ !   allow deallocation on an abort. /Ned Freed 14-Dec-1988
    $ !
    $ ! Parameters:
    $ !
    $ !   P1 - Name of the channel whose messages are to be delivered.
    $ !   P2 - Activity type. If P2 .eqs. "POLL", establish the connection
    $ !        unconditionally, otherwise only establish the connection if
    $ !        messages are waiting in the queue.
    $ !   P3 - Earliest possible date/time for message(s). Messages older than
    $ !        this time are not processed.
    $ !   P4 - Environment. P4 .eqs. "POST" if MASTER is being called from the
    $ !        POST.COM procedure or some other procedure that invokes MASTER
    $ !        more than once. This parameter is used to insert delays before
    $ !        returning if hardware needs time to reset.
    $ !   P5 - Parameter reserved for channel-specific uses.
    $eod 
    $copy sys$input PMDF.TXT
    $deck
    BULLETIN_MASTER.PAS and MASTER.COM are the files you need to run a BULLETIN
    channel. Put BULLETIN_MASTER.PAS in a subdirectory of PMDF_ROOT:[SRC] (I use
    the directory PMDF_ROOT:[SRC.BULLETIN]). Compile it there and then link it as
    follows: 
    
        LINK BULLETIN_MASTER,[EXE]PMDFLIB/LIB,BULL_SOURCE:BULL/LIB,
    
    and put the .EXE in PMDF_ROOT:[EXE]. Put the new MASTER.COM in PMDF_ROOT:[EXE].
    NOTE: Check your MASTER.COM, as the latest version of PMDF contains the code
    necessary to check for bulletin mail.  However, it will not necessary have the
    latest copy of BULLETIN_MASTER.PAS.
    
    You then need a channel definition like the following in your configuration
    file PMDF.CNF:
    
        bull_local single master logging
        BULLETIN-DAEMON
    
    And a rewrite rule of the form:
    
        BULLETIN                          $U%BULLETIN@BULLETIN-DAEMON
    
    Then you put an alias in your ALIASES. file for each mailing list you want to
    process this way. I have the following:
    
        info-vax: info-vax@bulletin
        tex-hax: tex-hax@bulletin
        xmailer-list: xmailer@bulletin
        mail-l: mail-l@bulletin
        jnet-l: jnet-l@bulletin
        policy-l: policy-l@bulletin
        future-l: future-l@bulletin
        mon-l: mon-l@bulletin
        ug-l: ug-l@bulletin
    
    Then mail sent to info-vax@localhost will be routed to a folder called
    info-vax. In general, an alias of the form
    
        a : b@bulletin
    
    will route mail sent to a@localhost to folder b in BULLETIN.
    
    NOTE: If you have BBOARD set for a folder that you convert to be delivered
    directly to PMDF, remember to do a SET NOBBOARD for that folders.  After
    doing so, restart BULLCP using BULLETIN/START.
    $eod