Since V3R7, IBM has been steadily furnishing the AS/400 with a comprehensive set of e- mail functions, such as the ability to act as a Post Office Protocol Version 3 (POP3) mail server and a set of OS/400 AnyMail Framework "snap-in" modules that let the AS/400 process mail for POP3 and OV/400 clients in a common way. V4R2 further strengthens the AS/400 as an e-mail server by providing the QtmmSendMail API, which makes it easier than ever to send e-mail from an Integrated Language Environment (ILE) RPG, C, or Cobol program to PC mail clients over a TCP/IP network.
Why would you want to send e-mail from an AS/400 program? You could use this capability in an AS/400 application that monitors an event and sends you an e-mail message when that event occurs or sends an Internet e-mail message to an operator at home when the system needs attention. Another possible use is a business application that sends e-mail messages to customers informing them of the status of their orders.
Let's take an in-depth look at how the QtmmSendMail API works, its parameters, and the structure of a Multipurpose Internet Mail Extensions (MIME) e-mail message. "RPG Utility Puts QtmmSendMail API to Work," provides an ILE RPG utility that uses the QtmmSendMail API, and a C utility that performs a similar function is available online.
A Better Way
Before V4R2, the AS/400 supported sending mail from an Original Program Model (OPM) or ILE program via the SNDDST (Send Distribution) command. Pre-V4R1 versions of the SNDDST command were difficult to use with Internet addressing. The V4R1 version of SNDDST supports Internet addressing but doesn't handle multiple attachments, as QtmmSendMail does. As of V4R1, OS/400 also includes QzmfCrtMailMsg, which is more complex than QtmmSendMail and is a general mail API, while QtmmSendMail is specifically for Simple Mail Transport Protocol (SMTP)/MIME mail (i.e., Internet mail).
The QtmmSendMail API lets you write programs that send mail messages and attachments without SNDDST. The API enables ILE programs written on the AS/400 to send messages to the AnyMail Framework, which then processes the messages, determines the recipient type (OfficeVision/400 (OV/400) or POP3) and sends them on to the appropriate mail transport for delivery (i.e., SNADS for OV/400 mail, SMTP for Internet mail). The messages must be properly formatted using the SMTP/MIME protocol. You can find descriptions of SMTP/MIME in the Internet Network Information Center (InterNIC) Request For Comment (RFC) documents 822, 1521, and 1522, available from http://www.internic.net.
Because it's a command, SNDDST is easier to use than QtmmSendMail, but the API is more flexible because it handles any type of attachment that can be defined using MIME, as well as multiple attachments. QtmmSendMail lets you use an AS/400 program to send any SMTP/MIME formatted mail, whereas SNDDST is restricted to limited conversions from SNADS to SMTP formats.
Although QtmmSendMail is part of V4R2, if you have TCP/IP Connectivity Utilities (5769-TC1), you need to apply PTF SF49318 to use the API with RPG. Pre-V4R2 AS/400s require the following PTFs to use the QtmmSendMail API:
SF36758 (for 5716-SS1)
V4R1: SF49437, SF49318 (for 5769-TC1)
SF45139 (for 5769-SS1)
Note: Although these PTFs were current when this article was written, be sure to check IBM's AS/400 Web site (http://www.as400.ibm.com) for the latest PTFs.
What's in a MIME Message?
Before we take a look at how an RPG program can send a fixed e-mail message, such as a status message, to a fixed set of one or more recipients, let's look at the e-mail message itself. A MIME file, or note, consists of two logical parts: envelope and body. The envelope contains header information, such as addresses and subject. Note that the MIME envelope can contain text such as the addressee's name as well as the actual address - for example, Sue Hall
A MIME note can contain different originator and recipient addresses from those in the QtmmSendMail API parameters. Also, a note can't contain blind copy addresses, although the parameters can. Although a MIME note can contain all addresses for recipients, the corresponding QtmmSendMail API parameter list will include only those addresses handled by the AnyMail Framework (i.e., some mail systems might handle local mail and give the framework only mail destined for POP or SMTP forwarding or OfficeVision or SNADS forwarding).
Figure 1 shows a sample MIME text note. You create a MIME note that you want to use as input to the QtmmSendMail API as an IFS file in ASCII code page 819 (US-ASCII) for it to be processed properly for Internet mail. You also must create the file in a directory that gives the QMSF profile *ALL object authority and *RWX data authority. (QMSF is the AnyMail Framework's AS/400 profile; AS/400 mail server jobs run as QMSF jobs in the QSYSWRK subsystem.) To view the permissions associated with the file and directory, use the WRKLNK (Work with Object Links) command on the path name and then select option 9, or use the DSPAUT (Display Authority) command. Make sure you end the MIME headers in the file (the general headers as well as the headers for each part) with a blank line (two carriage return/line feed characters, X'0D0A0D0A' in ASCII), the standard end-of-header indicator for SMTP mail.
In Figure 1, the Date:, From:, To:, and Subject: fields contain SMTP header information. The other header tags are MIME additions. The first header, MIME-Version: 1.0, indicates what MIME tags will be included in the note (many tags are defined in the MIME RFCs; this example uses only a basic set of tags).
The Content-Type: header precedes a keyword that describes either the contents of the entire note or the type of attachment. The first Content-Type value refers to the entire note, and subsequent Content-Type value(s) refer to the type of attachment. Examples of content types are text, image, audio, multipart. There are also subtypes that follow the content type, for example, in Figure 1, multipart/mixed and text/plain are type/subtype combinations. (For definitions of these keywords, see the MIME RFCs.)
The "boundary" part of a MIME message uses the format boundary="thisisanystring" (substitute your own character string) and indicates what characters to look for as boundaries of parts of the message. Each part starts with two dashes (--) followed by the string, such as --PART.BOUNDARY.xyz in Figure 1. A boundary marker indicates the end of the message with two dashes followed by the same string and ending with two dashes - for example, --PART.BOUNDARY.xyz-- in Figure 1.
This is an example of a simple MIME note. If you want to send a nontext attached file (e.g., graphics files, Microsoft Word documents), you must send it as a binary attachment. To transmit binary attachments in a MIME note, binary data must be encoded so that no character in the data exceeds X'7F'. Most e-mail packages use an encoding scheme called Base 64; the MIME header information describes the type of encoding used in a message so that e-mail client software knows how to decode the data. MIME RFC 2045 contains a description of Base 64 encoding. Many examples of routines that perform this encoding are available on the Web. To find these, just search for the string "base 64" from your favorite Web browser.
Using the QtmmSendMail API
Once you've created a MIME message, your program can call the QtmmSendMail API to send it. In an ILE RPG program, you use the format in Figure 2 to call the QtmmSendMail API. (The calling format for C is in QSYSINC/H member QTMMSNDM.) The QtmmSendMail API requires the following parameters for an ILE RPG program:
- Filename: the name of an integrated file system (IFS) root file in EBCDIC (code page 37 or 500) containing a complete MIME note in US-ASCII (code page 819), including headers
- FilenameLength: an integer containing the length of the file name in bytes
- Originator: the originator's address in EBCDIC (code page 37 or 500), for example, firstname.lastname@example.org. (Addresses use the format email@example.com.)
- OriginatorLength: an integer containing the length of the originator address in bytes
- FirstRecipient: a data structure containing the first recipient's address as a variable and information that indicates the recipient type: 0 for normal "to" mail, 1 for carbon copy, or 2 for blind carbon copy (a blind copy means the message will be sent to an address that doesn't appear in the MIME note). The rest of the FirstRecipient structure is overhead. The OffSet is 0 when the message will be sent to only one recipient, otherwise it's the length of the next recipient structure (at least the length of the fixed part and the address itself). Currently, you can use either ADDR0100 or ADDT0100 as the Format value; this value will probably change in the future. You should set the Reserved field value to 0.
- TotalNumberRec: an integer containing the total number of recipients
- ErrorMessage: a data structure that will hold a value indicating whether or not the e- mail message was created and put into the AnyMail Framework. (See the AS/400 System API Reference V4R2 (SC41-5801-01) for a description of this structure.) If you specify a length of 0 for the first field of the ErrorMessage structure, errors will be displayed on screen or entered in the job log. As with other OS/400 APIs, specifying a length of at least 8 returns the error message number to the caller instead of sending the error message to the job.
The QtmmSendMail API is in service program QTCP/QTMMSNDM. To use the API with your own custom program, you must compile your program so it becomes a *MODULE object using a language-specific CRTxxxMOD command, such as CRTRPGMOD (Create RPG Module), as follows:
SRCFILE(your lib/source file)
Then, you must bind the *MODULE object with the service program using the CRTPGM (Create Program) command:
A Custom Mail Tool
The QtmmSendMail API gives AS/400 programmers a powerful tool for customizing applications to send Internet e-mail messages and attached files containing text, audio, video, fax, or images. For more information about the QtmmSendMail API, see AS/400 System API Reference, the Redbook AS/400 Electronic Mail Capabilities (SG24- 4703), and TCP/IP Configuration and Reference (SC41-3420).
John Hall is a senior software engineer for the AS/400 Division. He was the lead designer and architect for the AS/400 POP3 server and is currently working on developing additional AS/400 TCP/IP applications. You can reach him at firstname.lastname@example.org.
Susan Hall is a staff software engineer for the AS/400 Division. She wrote the QtmmSendMail API and other AS/400 mail functions. She is currently working on developing additional TCP/IP functions for the AS/400. You can reach her at email@example.com.