The programs shown in Examples 1-8 and 1-9 will loop through all messages in a message queue, converting the body of each message and re-enqueuing the converted message back to PMDF. The conversion process involves applying the "rot13" encoding used by many news readers to encode potentially offensive message content.
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:
hdr, and
display any header lines stored in the structure. This routine does not
serve any real purpose here other than to illustrate how to walk a
header structure.
hdr. This is merely done as an
example of walking through a header structure; displaying the structure
serves no other useful purpose in this example.
Example 1-8 Message dequeuing & re-enqueuing (Pascal)
(* api_example5.pas -- Dequeue a message, rot13 the message body,
and then requeue the message *)
[inherit ('pmdf_exe:apidef')] program api_example5 (output);
type
uword = [word] 0..65535;
string = packed array [1..ALFA_SIZE] of char;
bigstring = packed array [1..BIGALFA_SIZE] of char;
var
channel, env_id, from_adr, orig_adr, to_adr : string;
channel_len, env_id_len, from_adr_len,
orig_adr_len, to_adr_len, txt_len : uword;
dq_context : PMDF_dq;
empty : varying [1] of char;
hdr : PMDF_hdr;
i, nflags, stat : integer;
nq_context : PMDF_nq;
outfile : text;
txt : bigstring;
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, 'Reason ', stat:0);
if dq_context <> nil then PMDF_defer_message (dq_context, true, reason);
if nq_context <> nil then PMDF_abort_message (nq_context);
if stat = 0 then SYS$EXIT (1) else SYS$EXIT (stat);
end; (* if *)
end; (* check *)
function get_message : boolean; (2)
var msg_file : string; msg_file_len : uword;
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 *)
function read_line : boolean; (3)
begin (* read_line *)
stat := PMDF_read_line (dq_context, txt, txt_len);
read_line := odd (stat);
if (not odd (stat)) and (stat <> PMDF__EOF) then check (stat);
end; (* read_line *)
procedure display_header_lines (hdr : PMDF_hdr); (4)
var i : integer; hdr_line : PMDF_hdr_line_ptr;
begin (* display_header_lines *)
for i := HL_FIRST_HEADER to HL_LAST_HEADER do begin
if hdr^[i] <> nil then begin
hdr_line := hdr^[i];
while hdr_line <> nil do begin
writeln (substr (hdr_line^.line^, 1, hdr_line^.line_length));
hdr_line := hdr_line^.next_line;
end; (* while *)
end; (* if *)
end; (* for *)
end; (* display_header_lines *)
function rot13 (c : char) : char; (5)
begin (* rot13 *)
if c in ['A'..'Z'] then
rot13 := chr (((ord (c) - ord ('A') + 13) mod 26) + ord ('A'))
else if c in ['a'..'z'] then
rot13 := chr (((ord (c) - ord ('a') + 13) mod 26) + ord ('a'))
else rot13 := c;
end; (* rot13 *)
begin (* api_example5 *)
empty := '';
hdr := nil;
dq_context := nil;
nq_context := nil;
check (PMDF_initialize (true)); (6)
check (PMDF_get_channel_name (channel, channel_len)); (7)
check (PMDF_dequeue_initialize (dq_context)); (8)
check (PMDF_enqueue_initialize);
while get_message do begin (9)
check (PMDF_get_envelope_id (dq_context, env_id, env_id_len)); (10)
check (PMDF_start_message_envelope (nq_context, (11)
substr (channel, 1, channel_len),
substr (from_adr, 1, from_adr_len)));
check (PMDF_set_envelope_id (nq_context, substr (env_id, 1, env_id_len))); (12)
while odd (PMDF_get_recipient (dq_context, to_adr, to_adr_len, (13)
orig_adr, orig_adr_len)) do begin
check (PMDF_get_recipient_flags (dq_context, nflags)); (14)
check (PMDF_set_recipient_flags (nq_context, nflags));
check (PMDF_add_recipient (nq_context, substr (to_adr, 1, to_adr_len),
substr (orig_adr, 1, orig_adr_len)));
check (PMDF_recipient_disposition (dq_context, nflags, (15)
PMDF_DISP_DELIVERED,
substr (to_adr, 1, to_adr_len),
substr (orig_adr, 1, orig_adr_len), empty));
end; (* while *)
check (PMDF_start_message_header (nq_context)); (16)
check (PMDF_read_header (dq_context, hdr)); (17)
display_header_lines (hdr); (18)
check (PMDF_write_header (nq_context, hdr));
check (PMDF_dispose_header (hdr));
check (PMDF_start_message_body (nq_context));
while read_line do begin (19)
for i := 1 to txt_len do txt[i] := rot13 (txt[i]);
check (PMDF_write_line (nq_context, substr (txt, 1, txt_len)));
end; (* while *)
check (PMDF_enqueue_message (nq_context)); (20)
check (PMDF_dequeue_message_end (dq_context, false, empty)); (21)
end; (* while *)
check (PMDF_dequeue_end (dq_context)); (22)
check (PMDF_done);
end. (* api_example5 *)
Example 1-9 Message dequeuing & re-enqueuing (C)
/* api_example6.c -- Dequeue a message, rot13 the message body,
and then requeue the message */
#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, txt;
int from_adr_len, txt_len;
PMDF_nq *nq_context = 0;
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 (nq_context) PMDFabortMessage (&nq_context);
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);
}
int read_line (void) (3)
{
int stat;
txt_len = BIGALFA_SIZE;
stat = PMDFreadLine (&dq_context, txt, &txt_len);
if ( !(1 & stat) && stat != PMDF__EOF) check (stat);
return (1 & stat);
}
void display_header_lines (PMDF_hdr *hdr) (4)
{
int i;
PMDF_hdr_line *hdr_line;
for (i = HL_FIRST_HEADER; i <= HL_LAST_HEADER; i++) {
if ((*hdr)[i]) {
hdr_line = (*hdr)[i];
while (hdr_line) {
printf ("%s\n", hdr_line->line);
hdr_line = hdr_line->next_line;
}
}
}
}
char rot13 (char c) (5)
{
if ('A' <= c && c <= 'Z') return (((c - 'A' + 13) % 26) + 'A');
else if ('a' <= c && c <= 'z') return (((c - 'a' + 13) % 26) + 'a');
else return (c);
}
main ()
{
string channel, env_id, orig_adr, to_adr;
int channel_len, env_id_len, nflags, i, orig_adr_len, to_adr_len;
PMDF_hdr *hdr;
unsigned int key;
check (PMDFinitialize (1)); (6)
channel_len = ALFA_SIZE;
check (PMDFgetChannelName (channel, &channel_len, &key, &key)); (7)
check (PMDFdequeueInitialize (&dq_context)); (8)
check (PMDFenqueueInitialize ());
while (get_message ()) { (9)
env_id_len = ALFA_SIZE;
check (PMDFgetEnvelopeId (&dq_context, env_id, &env_id_len)); (10)
check (PMDFstartMessageEnvelope (&nq_context, channel, channel_len, (11)
from_adr, from_adr_len));
check (PMDFsetEnvelopeId (&nq_context, env_id, env_id_len)); (12)
to_adr_len = orig_adr_len = ALFA_SIZE;
while (1 & PMDFgetRecipient (&dq_context, to_adr, &to_adr_len, (13)
orig_adr, &orig_adr_len))
{
check (PMDFgetRecipientFlags (&dq_context, &nflags)); (14)
check (PMDFsetRecipientFlags (&nq_context, nflags));
check (PMDFaddRecipient (&nq_context, to_adr, to_adr_len,
orig_adr, orig_adr_len));
check (PMDFrecipientDisposition (&dq_context, nflags, (15)
PMDF_DISP_DELIVERED, to_adr,
to_adr_len, orig_adr, orig_adr_len,
NULL, 0));
to_adr_len = orig_adr_len = ALFA_SIZE;
}
check (PMDFstartMessageHeader (&nq_context)); (16)
check (PMDFreadHeader (&dq_context, &hdr)); (17)
display_header_lines (hdr); (18)
check (PMDFwriteHeader (&nq_context, hdr));
check (PMDFdisposeHeader (&hdr));
check (PMDFstartMessageBody (&nq_context));
while (read_line ()) { (19)
for (i = 0; i < txt_len - 1; i++) txt[i] = rot13 (txt[i]);
check (PMDFwriteLine (&nq_context, txt, txt_len));
}
check (PMDFenqueueMessage (&nq_context)); (20)
check (PMDFdequeueMessageEnd (&dq_context, 0, NULL, 0)); (21)
}
check (PMDFdequeueEnd (&dq_context)); (22)
check (PMDFdone ());
}