Figure 8: Program IFS3MAIL1 |
* This program demonstrates creating/sending an e-mail message
* for each order in the "shipped orders" files.
*
* If compiling this for the first time, create a binding
* directory for e-mail by typing:
* CRTBNDDIR BNDDIR(mylib/EMAIL)
* ADDBNDDIRE BNDDIR(mylib/EMAIL) OBJ((QTCP/QTMMSNDM *SRVPGM))
*
* To Compile:
* CRTBNDRPG IFS3MAIL1 SRCFILE(mylib/QRPGLESRC) DBGVIEW(*LIST)
*
H DFTACTGRP(*NO) OPTION(*SRCSTMT: *NODEBUGIO: *NOSHOWCPY)
H BNDDIR('QC2LE': 'EMAIL')
FSHPORDERS IF E DISK BLOCK(*YES)
FSHPDETAIL IF E K DISK
/copy ifsio_h
/copy iconv_h
/copy sendmail_h
/copy errno_h
D CreateMsg PR
D NameTo 256A varying const
D AddrTo 256A varying const
D NameFrom 256A varying const
D AddrFrom 256A varying const
D FirstName 50A varying const
D OrderNo 10A const
D OrderDate D const
D MsgFile 256A varying
D SendMsg PR
D FileName 256A varying const
D AddrTo 256A varying const
D AddrFrom 256A varying const
D do_iconv PR 256A varying
D Trans likeds(iconv_t) const
D Text 256A varying value
D MailDate PR 31A
D ReportError PR
D SENDER_EMAIL C 'custserv@example.com'
D filename s 256A varying
/free
// ************************************
// Read through the "Shipped Orders"
// file. For each shipped order, do
// the following:
//
// a) Create a text file containing
// an e-mail message.
//
// b) Send that e-mail.
// ************************************
|
read SHPORDERS;
dow not %eof(SHPORDERS);
CreateMsg( %trimr(FirstName) + ' ' + %trimr(LastName)
: %trimr(EmailAddr)
: 'Acme Customer Service'
: SENDER_EMAIL
: %trimr(FirstName)
: OrderNo
: OrderDate
: FileName );
SendMsg( FileName
: %trimr(EmailAddr)
: SENDER_EMAIL );
read SHPORDERS;
enddo;
|
A |
*inlr = *on;
/end-free
*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
* CreateMsg(): Create a text file that's formatted as
* an e-mail message.
*
* NameTo = (input) Recipient's name
* AddrTo = (input) Recipient's e-mail address
* NameFrom = (input) Sender's name
* AddrFrom = (input) Sender's e-mail address
* FirstName = (input) Recipient's first name
* OrderNo = (input) Order number that has shipped
* OrderDate = (input) Date that order was placed
* MsgFile = (output) Filename in the IFS where the
* message was saved.
*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
P CreateMsg B
D CreateMsg PI
D NameTo 256A varying const
D AddrTo 256A varying const
D NameFrom 256A varying const
D AddrFrom 256A varying const
D FirstName 50A varying const
D OrderNo 10A const
D OrderDate D const
D MsgFile 256A varying
D get_errno PR * ExtProc('__errno')
D ptrToErrno s *
D errno s 10I 0 based(ptrToErrno)
D CRLF C x'0d25'
D fd s 10I 0
D hdr s 2048A varying
D msg s 2048A varying
D FileNo s 10I 0 inz(0)
/free
// When the O_EXCL flag is passed, open() will fail
// and set errno to EEXIST if the file already exists.
//
// Here, we use that to create a unique filename.
|
dou (fd <> -1);
FileNo += 1;
MsgFile = '/tmp/ship_notify_'+ %editc(FileNo:'X') +'.txt';
fd = open( MsgFile
: O_CREAT + O_EXCL + O_WRONLY + O_CCSID
+ O_TEXTDATA + O_TEXT_CREAT
: M_RDWR
: 367
: 0 );
if (fd = -1);
ptrToErrno = get_errno();
if (errno <> EEXIST);
ReportError();
endif;
endif;
enddo;
|
B |
//
// *** Write e-mail header to the text file ***
//
hdr = 'To: ' + NameTo + ' <' + AddrTo + '>' + CRLF
+ 'From: ' + NameFrom + ' <' + AddrFrom + '>' + CRLF
+ 'Date: ' + MailDate() + CRLF
+ 'Subject: Order ' + %trimr(OrderNo) + ' shipped!' + CRLF
+ CRLF;
callp write(fd: %addr(hdr)+2: %len(hdr));
//
// *** Write top of e-mail message to the text file ***
//
msg = 'Dear ' + FirstName +',' + CRLF
+ CRLF
+ 'The following order that you placed on '
+ %char(OrderDate:*ISO) + ' has been shipped!' + CRLF
+ CRLF
+ 'A summary of order #' + %trimr(OrderNo) + ' follows:'
+ CRLF
+ CRLF
+ 'ItemNo Description Quantity Price'
+ CRLF
+ '------ ------------------------- -------- --------'
+ CRLF;
callp write(fd: %addr(msg)+2: %len(msg));
//
// *** Add order details to the e-mail message ***
//
setll OrderNo SHPDETAIL;
reade OrderNo SHPDETAIL;
dow not %eof(SHPDETAIL);
msg = ItemNo + ' '
+ ItemDesc + ' '
+ %editc(QtyShp:'L') + ' '
+ %editc(Price:'L')
+ CRLF;
callp write(fd: %addr(msg)+2: %len(msg));
reade OrderNo SHPDETAIL;
enddo;
callp close(fd);
/end-free
P E
*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
* SendMsg(): Send E-mail Message
*
* Filename = (input) name of file containing the message
* that is to be sent.
* AddrTo = (input) E-mail address of recipient
* AddrFrom = (input) E-mail address of sender
*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
P SendMsg B
D SendMsg PI
D FileName 256A varying const
D AddrTo 256A varying const
D AddrFrom 256A varying const
D NullError DS
D BytesProv 10I 0 inz(0)
D BytesAvail 10I 0 inz(0)
D ascii_from s like(AddrFrom)
D ascii_to s like(AddrTo)
D conv ds likeds(iconv_t)
D conv_from ds likeds(QtqCode_t)
D inz(*likeds)
D conv_to ds likeds(QtqCode_t)
D inz(*likeds)
D recip ds likeds(ADDTO0100)
D dim(1)
/free
//
// The QtmmSendMail API requires that the From and To
// addresses be in CCSID 500.
//
// The iconv() API can be used to convert from one
// CCSID to another. (0 = Current Job's CCSID)
//
conv_from.CCSID = 0;
conv_to.CCSID = 500;
conv = QtqIconvOpen( conv_to : conv_from );
if (conv.return_value = -1);
ReportError();
endif;
ascii_from = do_iconv(conv: AddrFrom);
ascii_to = do_iconv(conv: AddrTo);
iconv_close(conv);
// Recipients are specified as a data structure. Note
// that this is an array, because you can have more than
// one recipient if you like.
//
// DistType can be ADDR_NORMAL, ADDR_CC or ADDR_BCC
recip(1).NextOffset = %size(ADDTO0100);
recip(1).AddrFormat = 'ADDR0100';
recip(1).DistType = ADDR_NORMAL;
recip(1).Reserved = 0;
recip(1).SmtpAddr = ascii_to;
recip(1).AddrLen = %len(ascii_to);
//
// The QtmmSendMail API deletes the text file
// when it is done sending it.
//
QtmmSendMail( FileName
: %len(FileName)
: ascii_from
: %len(ascii_from)
: recip
: %elem(recip)
: NullError );
/end-free
P E
*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
* do_iconv(): Shortcut wrapper for the iconv() API.
*
* Trans = (input) Translator returned by iconv()
* Text = (input) Text to translate
*
* Returns the translated text
*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
P do_iconv B
D do_iconv PI 256A varying
D Trans likeds(iconv_t) const
D Text 256A varying value
D p_input s *
D p_output s *
D Output s 1024A varying
D InLeft s 10U 0
D OutLeft s 10U 0
/free
InLeft = %len(Text);
OutLeft = InLeft;
%len(Output) = OutLeft;
p_input = %addr(text) + 2;
p_output = %addr(output) + 2;
if (iconv(Trans: p_input: InLeft: p_output: OutLeft) = -1);
ReportError();
endif;
return Output;
/end-free
P E
*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
* MailDate(): Returns the current date, formatted for use
* in an e-mail message.
*
* For example: 'Sat, 23 Oct 2004 14:42:06 -0500'
*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
P MailDate B
D MailDate PI 31A
D CEELOCT PR opdesc
D Lilian 10I 0
D Seconds 8F
D Gregorian 23A
D fc 12A options(*omit)
D CEEUTCO PR opdesc
D Hours 10I 0
D Minutes 10I 0
D Seconds 8F
D CEEDATM PR opdesc
D input_secs 8F const
D date_format 80A const options(*varsize)
D char_date 80A options(*varsize)
D feedback 12A options(*omit)
D rfc2822 c 'Www, DD Mmm YYYY HH:MI:SS'
D junk1 s 8F
D junk2 s 10I 0
D junk3 s 23A
D hours s 10I 0
D mins s 10I 0
D tz_hours s 2P 0
D tz_mins s 2P 0
D tz s 5A varying
D CurTime s 8F
D Temp s 25A
/free
//
// Calculate the Timezone in format '+0000', for example,
// CST should show up as '-0600'
//
CEEUTCO(hours: mins: junk1);
tz_hours = %abs(hours);
tz_mins = mins;
if (hours < 0);
tz = '-';
else;
tz = '+';
endif;
tz += %editc(tz_hours:'X') + %editc(tz_mins:'X');
//
// Get the current time and convert it to the format
// specified for e-mail in RFC 2822
//
CEELOCT(junk2: CurTime: junk3: *omit);
CEEDATM(CurTime: rfc2822: Temp: *omit);
return Temp + ' ' + tz;
/end-free
P E
|