Examples 1-10 and 1-11 illustrate the use of PMDF_dequeue_message_end to return a message to its originator. A message in the channel's queue is accessed and each of its envelope To: recipients are given a disposition of PMDF_DISP_RETURN which indicates that the message is undeliverable for that recipient. Then, when PMDF_dequeue_message_end is called, a bounce message is automatically generated and sent back to the original message's originator. The original message is then removed from the queue. Note that no notification message will be generated if the NOTARY flags for all of the recipients specify PMDF_RETURN_NEVER.
These two particular examples, through the use of PMDF_get_message, return each and every message in a message queue. A sample returned message is shown in Example 1-12 .
Note:
It is important to remember to define the PMDF_CHANNEL logical (OpenVMS) or environment variable (UNIX and NT) to be the name of the channel (in lower case) to be serviced by this program. Also, if experimenting from your own account, do not leave this logical or environment variable defined while not experimenting --- PMDF may see it when you send mail and submit that mail as though it was enqueued by the channel given by PMDF_CHANNEL. (This is a debugging feature.)
The following items of note are identified with callouts in each of the two programs:
Example 1-10 Dequeuing & returning messages (Pascal)
(* api_example7.pas -- Return channel which returns all mail queued to it *)
[inherit ('pmdf_exe:apidef')] program api_example7;
type
uword = [word] 0..65535;
string = packed array [1..ALFA_SIZE] of char;
var
from_adr, orig_adr, to_adr : string;
from_adr_len, orig_adr_len, to_adr_len : uword;
dq_context : PMDF_dq;
empty : varying [1] of char;
nflags : integer;
function SYS$EXIT (%immed status : integer := %immed 1) : integer; extern;
procedure check (stat : integer); (1)
var reason : varying [20] of char;
begin (* check *)
if not odd (stat) then begin
writev (reason, 'Error ', stat:0);
if dq_context <> nil then PMDF_defer_message (dq_context, true, reason);
end; (* if *)
end; (* check *)
function get_message : boolean; (2)
var msg_file : string; msg_file_len : uword; stat : integer;
begin (* get_message *)
stat := PMDF_get_message (dq_context, msg_file, msg_file_len,
from_adr, from_adr_len);
get_message := odd (stat);
if (not odd (stat)) and (stat <> PMDF__EOF) then check (stat);
end; (* get_message *)
begin (* api_example7 *)
dq_context := nil;
empty := '';
check (PMDF_initialize (true)); (3)
check (PMDF_dequeue_initialize (dq_context)); (4)
while get_message do begin (5)
while odd (PMDF_get_recipient (dq_context, to_adr, to_adr_len, (6)
orig_adr, orig_adr_len)) do begin
check (PMDF_get_recipient_flags (dq_context, nflags)); (7)
check (PMDF_recipient_disposition (dq_context, nflags, (8)
PMDF_DISP_RETURN, substr (to_adr, 1, to_adr_len),
substr (orig_adr, 1, orig_adr_len),
'Message undeliverable; returned by the postmaster'));
end; (* while *)
check (PMDF_dequeue_message_end (dq_context, false, empty)); (9)
end; (* while *)
check (PMDF_dequeue_end (dq_context)); (10)
check (PMDF_done);
end. (* api_example7 *)
Example 1-11 Dequeuing & returning messages (C)
/* api_example8.c -- Return channel which returns all mail queued to it */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef __VMS
#include "pmdf_com:apidef.h"
#else
#include "/pmdf/include/apidef.h"
#endif
typedef char string[ALFA_SIZE+1];
string from_adr;
int from_adr_len, item_index;
PMDF_dq *dq_context = 0;
void check (int stat) (1)
{
char reason[20];
if (!(1 & stat)) {
sprintf (reason, "Reason %d", stat);
if (dq_context) PMDFdeferMessage (&dq_context, 1, reason, strlen (reason));
if (!stat) exit (0);
else exit (stat);
}
}
int get_message (void) (2)
{
string msg_file;
int msg_file_len, stat;
msg_file_len = from_adr_len = ALFA_SIZE;
stat = PMDFgetMessage (&dq_context, msg_file, &msg_file_len,
from_adr, &from_adr_len);
if (!(1 & stat) && stat != PMDF__EOF) check (stat);
return (1 & stat);
}
main ()
{
string orig_adr, to_adr;
int i, nflags, orig_adr_len, to_adr_len;
channel_len = ALFA_SIZE;
check (PMDFinitialize (1)); (3)
check (PMDFdequeueInitialize (&dq_context)); (4)
while (get_message ()) { (5)
item_index = 0;
to_adr_len = orig_adr_len = ALFA_SIZE;
while (1 & PMDFgetRecipient (&dq_context, to_adr, &to_adr_len, (6)
orig_adr, &orig_adr_len)) {
check (PMDFgetRecipientFlags (&dq_context, &nflags)); (7)
check (PMDFrecipientDisposition (&dq_context, nflags, (8)
PMDF_DISP_RETURN, to_adr, to_adr_len,
orig_adr, orig_adr_len,
"Message undeliverable; returned by the postmaster", 49));
to_adr_len = orig_adr_len = ALFA_SIZE;
}
check (PMDFdequeueMessageEnd (&dq_context, 0, "", 0)); (9)
}
check (PMDFdequeueEnd (&dq_context)); (10)
check (PMDFdone ());
}
Example 1-12 shows a sample return message generated by PMDF_return_message. In that example, the following items are marked with callouts: the message header, (1) ; a MIME header line indicating that the message is a multi-part message, (2) ; the first body part which contains a human readable explanation as to why the message was returned, (3) ; the second body part which contains a machine readable explanation as to why the message was returned, (4) ; and the third body part containing the message being returned, (5) .
Example 1-12 Output of Examples1-10and1-11
Received: from acme.com (PMDF V6.0-21 #8790) (1) id <01IXGG2X55A88Y55Z3@acme.com>; Mon, 25 May 2000 16:12:09 PDT Date: Mon, 25 May 2000 16:12:09 PDT From: PMDF e-Mail Interconnect <postmaster@acme.com> Subject: Delivery Notification: Delivery has been manually aborted To: John.Doe@acme.com, postmaster@acme.com Message-id: <01IXGG2Y8J468Y55Z3@acme.com> MIME-version: 1.0 Content-type: MULTIPART/REPORT; REPORT-TYPE=DELIVERY-STATUS; (2) BOUNDARY="Boundary_(ID_78nMbcjsTsCboulbhJC84A)" --Boundary_(ID_78nMbcjsTsCboulbhJC84A) (3) Content-type: text/plain; charset=us-ascii Content-language: EN-US This report relates to a message you sent with the following header fields: Message-id: <01IXGGR0TSYS8Y55Z3@acme.com> Date: Mon, 25 May 2000 16:31:33 -0700 (PDT) From: John.Doe@acme.com To: Jane.Doe@acme.com Subject: Meeting next Wednesday Your message is being returned. It was forced to return by the postmaster. The recipient list for this message was: Recipient address: Jane.Doe@acme.com Reason: Message undeliverable; returned by the postmaster --Boundary_(ID_78nMbcjsTsCboulbhJC84A) (4) Content-type: message/DELIVERY-STATUS Original-envelope-id: 01IXGFBILT3M8Y55Z3@acme.com Reporting-MTA: dns;acme.com Action: failed Status: 5.0.0 (Message undeliverable; returned by the postmaster) Original-recipient: rfc822;Jane.Doe@acme.com Final-recipient: rfc822;Jane.Doe@acme.com --Boundary_(ID_78nMbcjsTsCboulbhJC84A) (5) Content-type: text/rfc822-headers Return-path: John.Doe@acme.com Received: from acme.com by acme.com (PMDF V6.0-21 #8790) id <01IXGG2X55A88Y55Z3@acme.com> (original mail from John.Doe@acme.com); Mon, 25 May 2000 16:12:09 PDT Received: from acme.com by acme.com (PMDF V6.0-21 #8790) id <01IXGFBIKQIO8Y55Z3@acme.com> for Jane.Doe@acme.com; Mon, 25 May 2000 15:50:52 PDT Date: Mon, 25 May 2000 15:50:50 -0700 (PDT) From: John.Doe@acme.com Subject: Meeting next Wednesday To: Jane.Doe@acme.com Message-id: <01IXGFBILT3M8Y55Z3@acme.com> MIME-version: 1.0 Content-type: TEXT/PLAIN; CHARSET=US-ASCII Can we reschedule the meeting to be at 14:30? --Boundary_(ID_78nMbcjsTsCboulbhJC84A)--