$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 '); 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