Skip to main content  
  Easy400   |       iSeries home   |   RSS feed
Freeware
 
Introduction
5250 utility
Windows utility
Other utilities
Service program
Sample code
Commands
CGI support
FAQ
WEBMail
Self maintenance
 
Download
 
 

 
Search   
iSeries MIME & Mail
Service program


If you want, to support your outgoing mail processes, you may write your own utilities or programs taking full advantage of our service program mmail/sendmail subprocedures.

If you do this, just remember to include some /copy statements in your ILE-RPG sources:
Before the file specifications:
/copy MMAIL/qrpglesrc,hspecs
/copy MMAIL/qrpglesrc,hspecsbnd

After the file specifications
/copy MMAIL/qrpglesrc,mailproto
/copy MMAIL/qrpglesrc,prototypeb
/copy MMAIL/qrpglesrc,variables3
/copy MMAIL/qrpglesrc,usec

Should you ever need to change something in the mmail/sendmail service program, read the following:

  • sources related to this service program are in file MMAIL/QRPGLESRC and begin by XXX .
  • new subprocedures should
    • document their prototypes in MMAIL/QRPGLESRC member MAILPROTO
    • document their names in source file MMAIL/QSRVSRC member SENDMAIL
  • to recreate both service programs and programs, run command MMAIL/COMPILE


For a quick walk-through service program subprocedures,
please check out page Message building procedures - Reference tables


1. Subprocedures to create the "body" of a MIME file

The following subprocedures help in the creation of the body of a MIME file. By "body" we here mean the MIME file (subject header, classification headers, and contents) without the "send headers" (Sender, Date, and distribution).
Such a partial MIME file allows to be reused for being sent from different persons to different receivers at different times.
Note 1.These subprocedures are the ones used by the mmail/crtmime command.
Note 2. They should be invoked in the same sequence as they are listed here.

MimeCrtF - Create an empty MIME file
MimeBldF - Create an empty MIME file
MimeSubj - Append the Subject header
MimeImpo - Append the Importance header
MimePrio - Append the Priority header
MimeSens - Append the Sensitivity header
MimeMultiP - Append the Content-Type: MULTIPART/MIXED; BOUNDARY:"..." header
MimeImbNul - Embed a null body
MimeNullBody - Embed a null body
MimeImbTxtF - Embed a text stream file
MimeStrBody - Start a body
MimeImbAtt - Embed or attach a part of the body
MimeImbDbf - Embed or attach a database file
MimeImbSrc - Embed or attach a source member
MimeImbSpl - Embed or attach a spool file
MimeSplPdf - Convert a spool file to PDF and attach it
MimeClose - Close a MIME file

  1.   MimeCrtF - Create an empty MIME file
    Use it to create an empty IFS file to become a MIME file.
    Note 1. If the file already exists, it is deleted before creating the new one.
    Note 2. The file is created with ASCII code page 819.
    Input: IFS file to be created
    Output: none
    Example:
    D MimeStmf        s            512a
    C                   eval      MimeStmf='/mmail/work/sample3.txt'
    C                   callp     MimeCrtF(MimeStmf)


  2.   MimeBldF - Create an empty MIME file
    Similar to MimeCRTF, but provides a return code.
    Note 1. If the file already exists, it is deleted before creating the new one.
    Note 2. The file is created with ASCII code page 819.
    Input: IFS file to be created
    Output:
    0 = successful
    1 = unsuccessful
    Example:
    D MimeStmf        s            512a
    D retCode         s             10i 0
    C                   eval      MimeStmf='/mmail/work/sample3.txt'
    C                   eval      retCode= MimeBldF(MimeStmf)


  3.   MimeSubj - Append the Subject header
    Use it to append a Subject header to the IFS MIME file.
    Inputs: IFS file name
    Subject of this message
    Output: none
    Example:
    D MimeStmf        s            512a
    D MimeFSubj       s             70a
    C                   eval      MimeStmf='/mmail/work/sample3.txt'
    C                   eval      MimeFSubj='Example 3: Attaching audio and images'
    C                   callp     MimeSubj(MimeStmf:MimeFSubj)
    Contents of the MIME file so far:
    Subject: Example 3: Attaching audio and images
    X-Mailer: IBM Internet Messaging Framework from eServer System


  4.   MimeImpo - Append the Importance header
    Use it to append a Importance header to the IFS MIME file.
    Inputs: IFS file name
    Importance of this message: 0=low, 1=medium, 2=high
    Output: none
    Example:
    D MimeStmf        s            512a
    D MimeFImpo       s             10i 0
    C                   eval      MimeStmf='/mmail/work/sample3.txt'
    C                   eval      MimeFImpo= 1
    C                   callp     MimeImpo(MimeStmf:MimeFImpo)
    Contents of the MIME file so far:
    Subject: Example 3: Attaching audio and images
    X-Mailer: IBM Internet Messaging Framework from eServer System
    Importance: medium


  5.   MimePrio - Append the Priority header
    Use it to append a Priority header to the IFS MIME file.
    Inputs: IFS file name
    Priority of this message: 0=non-urgent, 1=normal, 2=urgent
    Output: none
    Example:
    D MimeStmf        s            512a
    D MimeFPrio       s             10i 0
    C                   eval      MimeStmf='/mmail/work/sample3.txt'
    C                   eval      MimeFPrio= 1
    C                   callp     MimePrio(MimeStmf:MimeFPrio)
    Contents of the MIME file so far:
    Subject: Example 3: Attaching audio and images
    X-Mailer: IBM Internet Messaging Framework from eServer System
    Importance: medium
    Priority: normal


  6.   MimeSens - Append the Sensitivity header
    Use it to append a Sensitivity header to the IFS MIME file.
    Inputs: IFS file name
    Sensitivity of this message: 0=normal, 1=personal, 2=private, 3=Company-Confidential
    Note 1. A message with sensitivity 2=private cannot be printed neither forwarded
    Note 2. Sensitivity 3=Company-Confidential causes the subject be preceeded by a confidentiality statement. Use command MMAIL/SETCONFID to customize the confidentiality statement.
    Output: none
    Example:
    D MimeStmf        s            512a
    D MimeFSens       s             10i 0
    C                   eval      MimeStmf='/mmail/work/sample3.txt'
    C                   eval      MimeFSens= 2
    C                   callp     MimeSens(MimeStmf:MimeFSens)
    Contents of the MIME file so far:
    Subject: Example 3: Attaching audio and images
    X-Mailer: IBM Internet Messaging Framework from eServer System
    Importance: medium
    Priority: normal
    Sensitivity: private


  7.   MimeMultiP - Append the
    Content-Type: MULTIPART/MIXED; BOUNDARY:"..."
    header followed by the first boundary record.

    The above header instructs that the contents of the message would be several parts possibly with different types. Each of the parts must be preceeded and followed by a boundary line (as described in the "boundary" parameter of the header).

    Inputs: IFS file name
    Output: none

    Example:
    D MimeStmf        s            512a
    C                   eval      MimeStmf='/mmail/work/sample3.txt'
    C                   callp     MimeMultiP(MimeStmf)
    Contents of the MIME file so far:
    Subject: Example 3: Attaching audio and images
    X-Mailer: IBM Internet Messaging Framework from eServer System
    Importance: medium
    Priority: normal
    Sensitivity: private
    Content-Type: MULTIPART/MIXED; BOUNDARY="----=_NextPart_000_032_XXHUGGHU.VIHXOHG2"



  8.   MimeImbNul or MimeNullBody - Embed a null body.
    In some cases, the e-mail body will contain nothing. Just some attachments will be given.
    In order to have the MIME file understood from the receiving mailers, you must provide a message body anyhow.
    Procedures MimeImbNul or MimeNullBody provide a text/plain message body containing nothing.
    Input: • IFS MIME file name
    Output: • none
    Example:
    Embedding a null body
    D MimeStmf        s            512a
     * Embed a null body via subprocedure MimeImbNull
    C                   callp     MimeImbNul(MimeStmf)
     * Embed a null body via subprocedure MimeNullBody
    C                   callp     MimeImbNul(MimeStmf)
    Contents of the MIME file so far:
    Subject: Example 3: Attaching audio and images
    X-Mailer: IBM Internet Messaging Framework from eServer System
    Importance: medium
    Priority: normal
    Sensitivity: private
    Content-Type: MULTIPART/MIXED; BOUNDARY="----=_NextPart_000_032_XXHUGGHU.VIHXOHG2"

    ------=_NextPart_000_032_XXHUGGHU.VIHXOHG2
    Content-Type: text/html
    Content-Disposition: inline



  9.   MimeImbTxtF - Embed a text stream file.
    You may use this subprocedure to append (to the MIME file being built) the text of the main message (message body).
    This subprocedure does use the multipart/mixed technique (used for instance by Outlook). It appends the text stream file in two content-types: the first will be text/plain, the second will be text/html.
    This allows the receiving mailer to display the main message (message body) either as plain text ot html text, according to the user preferences.

    Inputs: • the name of the IFS MIME file that should be appended the message text
    • the name of the IFS stream file containing the message text to be appended
    • character set (optional); if missing character set "iso-8859-1" is assumed.
    • preformatted text (optional): whether the message text should be displayed as preformatted text.
    Output: • return code; a 0 value is returned if the operation was successful.


    Example:

    D  MIMEFile       s            512
    D  TextFile       s            512
    D  Charset        s             50    inz('iso-8859-1')
    D  Preformatted   s             50    inz('N')
    D  rcode          s             10i 0                          
    C                   eval      rc=MimeImbTxtF(MIMEFile:TextFile:
    C                             charset:preformatted)
    Note 1- Never use subprocedure MimeImbTxt after subprocedure MimeStrBody. Subprocedure MimeImbTxt must just follow subprocedure MimeMultiP.
    Note 2- The html version of the text stream file is displayed under the css style sheet defined in the stream file /mmaildata/css/mimeimbtxtf.css. This css style sheet can be modified as appropriate.

  10.   MimeStrBody - Start a body.
    If you plan to embed a part of the body via one of the following subprocedures
    • MimeCpyTxt
    • MimeUpdTxt
    you must make sure that the body starts with
    • the boundary delimiter
    • the Content-type and the Content-disposition headers
    This can be obtained through subprocedure MimeStrBody.
    Inputs: • IFS MIME file name
    • Content-type (optional)Allowed values
    T = text/plain (default value)
    H = text/html
    • Character set (optional) defaults to 'ISO-8859-1'
    Output: • none
    Examples:
    D MimeStmf        s            512a
    D  ContType       s              1a   inz('H')               
    D  Charset        s             50a   varying
     * Sample 1- Start a text/plain body                
    C                   callp     MimeStrBody(MimeFName)
     * Sample 2- Start a text/html body
    C                   callp     MimeStrBody(MimeFName:ContType)
     * Sample 3- Start a text/html body in Hebrew
    C                   eval      Charset='ISO-8859-8'
    C                   callp     MimeStrBody(MimeFName:ContType:
    C                             Charset)
    Contents of the MIME file so far (assuming the case of Sample 2):
    Subject: Example 3: Attaching audio and images
    X-Mailer: IBM Internet Messaging Framework from eServer System
    Importance: medium
    Priority: normal
    Sensitivity: private
    Content-Type: MULTIPART/MIXED; BOUNDARY="----=_NextPart_000_032_XXHUGGHU.VIHXOHG2"

    ------=_NextPart_000_032_XXHUGGHU.VIHXOHG2
    Content-Type: text/html; charset="ISO-8859-1"
    Content-Disposition: inline

    Note. You do not need subprocedure MimeStrBody when the body is created through one of the following subprocedures:
    • MimeImbDbf
    • MimeImbSrc
    • MimeImbSpl

     
  11.   MimeImbAtt - Embed or attach a part of the body.
    Repeat this subprocedure to embed or attach a part of the body, such as some text, an image, an audio, a movie, etc.

    Inputs: • IFS MIME file name
    • Name of the IFS file to embed or attach
    • Content-type of the IFS file to embed or attach
    • Binary data flag: Y=binary
        Note 1. If the IFS file to embed or attached is declared to be binary, it will be merged into the MIME file after being converted to BASE64 representation.
    • Embed/Attach parameter: 1=Embed, 2=Attach
        Note 2.Files to be embedded are assigned the requested Content-type;
    Files to be attached are assigned "Content-type: application/octect-stream"
    Content-ID number
    This is an optional parameter. If specified, must be an integer nnn from 1 to 999, and would generate the MIME header
        Content-ID: <nnn@mime.mail>
    This header may be generated to refer to this object in other parts of the MIME message. For instance, if the object is an image, you could refer to it with the following HTML syntax:
    <img src="cid:nnn@mime.mail">
    . You may use command mmail/sndmime and select Example07 to mail to you an example of using Content-ID headers.
    You may as wel run command dspf '/mmail/mime/example07.txt' to display the related MIME file.
    • New extension parameter.
    This is an optional parameter (char 3). It can be used to specify a new extension for the file attached. If this parameter is omitted or if it is blank, the extension is not changed.
    • Character set.
    This is an optional parameter for the embedded text.
    It applies only to Content-type text/plain and text/html.
    If omitted it defaults to ISO-8859-1.
    Use it to have your embedded text represented as due by the receiving mailer.
    For a list of available character sets, see this page.
    Output: • none


    Examples:

    1-Embedding some html text taken from "/mmail/text/Example03.txt"
    D MimeStmf        s            512a
    D FromFName       s            512a
    D ContType        s             21a
    D BinFlag         s              1a
    D ImbAtt          s             10i 0
    D ImbAttCid       s             10i 0
    D NewExt          s              3a
    D CharSet         s             50a   varying
     * Embed text from stream file /mmail/text/Example03.txt
    C                   eval      MimeStmf='/mmail/work/sample3.txt'
    C                   eval      FromFName='/mmail/text/Example03.txt'
    C                   eval      ContType='text/html'
    C                   eval      BinFlag=' '
    C                   eval      ImbAtt=1
    C                   callp     MimeImbAtt(MimeStmf:FromFName:
    C                             ContType:BinFlag:ImbAtt)
     *=============================
     * Embed hebrew text
    C                   eval      MimeStmf =...
    C                   eval      FromFName=...
    C                   eval      ContType='text/html'
    C                   eval      BinFlag=' '
    C                   eval      ImbAtt=1
    C                   eval      NewExt=' '
    C                   eval      CharSet='ISO-8859-8'
    C                   callp     MimeImbAtt(MimeStmf:FromFName:
    C                             ContType:BinFlag:ImbAtt:
    C                             NewExt:CharSet)
     *=============================
     *The following is to demonstrate the generation of a
     *Content-ID header (but it is not followed up in the rest
     *of this page):
     * -attach image from stream file /mmail/image/0002378.gif
     *  and assign to it "Content-ID: <001@mime.mail>"
    C                   eval      MimeStmf ='/mmail/work/sample3.txt'
    C                   eval      FromFName='/mmail/image/0002378.gif'
    C                   eval      ContType='image/gif'
    C                   eval      BinFlag='Y'
    C                   eval      ImbAtt=2
    C                   eval      ImbAttCid=001
    C                   callp     MimeImbAtt(MimeStmf:FromFName:
    C                             ContType:BinFlag:ImbAtt:ImbAttCid)
    Contents of the MIME file so far (assuming the first case of MimeImbAtt)
    Subject: Example 3: Attaching audio and images
    X-Mailer: IBM Internet Messaging Framework from eServer System
    Importance: medium
    Priority: normal
    Sensitivity: private
    Content-Type: MULTIPART/MIXED; BOUNDARY="----=_NextPart_000_032_XXHUGGHU.VIHXOHG2"

    --------=_NextPart_000_032_XXHUGGHU.VIHXOHG2
    Content-Type: text/html
    Content-Disposition: inline

    <font face=helv size=-2>
    Hello there!<br><br>
    This illustrates MIME headers for audio.<br>
    I am attaching a .wav file and a .gif file.<br><br>
    Giovanni </font><br><br>



    2-Attaching an audio taken from "/mmail/audio/rain.wav"
    C                   eval      FromFName='/mmail/audio/rain.wav'
    C                   eval      ContType='audio/basic'
    C                   eval      BinFlag='Y'
    C                   eval      ImbAtt=2
    C                   callp     MimeImbAtt(MimeStmf:FromFName:
    C                             ContType:BinFlag:ImbAtt)
    Contents of the MIME file so far:
    Subject: Example 3: Attaching audio and images
    X-Mailer: IBM Internet Messaging Framework from eServer System
    Importance: medium
    Priority: normal
    Sensitivity: private
    Content-Type: MULTIPART/MIXED; BOUNDARY="----=_NextPart_000_032_XXHUGGHU.VIHXOHG2"

    ------=_NextPart_000_032_XXHUGGHU.VIHXOHG2
    Content-Type: text/html
    Content-Disposition: inline

    <font face=helv size=-2>
    Hello there!<br><br>
    This illustrates MIME headers for audio.<br>
    I am attaching a .wav file and a .gif file.<br><br>
    Giovanni </font><br><br>

    ------=_NextPart_000_032_XXHUGGHU.VIHXOHG2
    Content-Type: application/octet-stream; name="rain.wav"
    Content-Disposition: attachment; filename="rain.wav"
    Content-Transfer-Encoding: base64
    Content-Description: rain.wav

    (here comes a copy of file "rain.wav" encoded to BASE64)


    3-Attaching an image taken from "/mmail/image/usaflag.gif"
    C                   eval      FromFName='/mmail/image/usaflg.gif'
    C                   eval      ContType='image/gif'
    C                   eval      BinFlag='Y'
    C                   eval      ImAtt=2
    C                   callp     MimeImbAtt(MimeStmf:FromFName:
    C                             ContType:BinFlag:ImbAtt)
    Contents of the MIME file so far:
    Subject: Example 3: Attaching audio and images
    X-Mailer: IBM Internet Messaging Framework from eServer System
    Importance: medium
    Priority: normal
    Sensitivity: private
    Content-Type: MULTIPART/MIXED; BOUNDARY="----=_NextPart_000_032_XXHUGGHU.VIHXOHG2"

    ------=_NextPart_000_032_XXHUGGHU.VIHXOHG2
    Content-Type: text/html
    Content-Disposition: inline

    <font face=helv size=-2>
    Hello there!<br><br>
    This illustrates MIME headers for audio.<br>
    I am attaching a .wav file and a .gif file.<br><br>
    Giovanni </font><br><br>

    ------=_NextPart_000_032_XXHUGGHU.VIHXOHG2
    Content-Type: application/octet-stream; name="rain.wav"
    Content-Disposition: attachment; filename="rain.wav"
    Content-Transfer-Encoding: base64
    Content-Description: rain.wav

    (here comes a copy of file "rain.wav" encoded to BASE64)
    ------=_NextPart_000_032_XXHUGGHU.VIHXOHG2
    Content-Type: application/octet-stream; name="usaflag.gif"
    Content-Disposition: attachment; filename="usaflag.gif"
    Content-Transfer-Encoding: base64
    Content-Description: usaflag.gif

    (here comes a copy of file "usaflag.gif" encoded to BASE64)


    4-Embedding some text taken from "/mmail/text/FootNote.txt"
    C                   eval      FromFName='/mmail/text/FootNote.txt'
    C                   eval      ContType='text/html'
    C                   eval      BinFlag=' '
    C                   eval      ImAtt=1
    C                   callp     MimeImbAtt(MimeStmf:FromFName:
    C                             ContType:BinFlag:ImbAtt)
    Contents of the MIME file so far:
    Subject: Example 3: Attaching audio and images
    X-Mailer: IBM Internet Messaging Framework from eServer System
    Importance: medium
    Priority: normal
    Sensitivity: private
    Content-Type: MULTIPART/MIXED; BOUNDARY="----=_NextPart_000_032_XXHUGGHU.VIHXOHG2"

    ------=_NextPart_000_032_XXHUGGHU.VIHXOHG2
    Content-Type: text/html

    Content-Disposition: inline

    <font face=helv size=-2>
    Hello there!<br><br>
    This illustrates MIME headers for audio.<br>
    I am attaching a .wav file and a .gif file.<br><br>
    Giovanni </font><br><br>

    ------=_NextPart_000_032_XXHUGGHU.VIHXOHG2
    Content-Type: application/octet-stream; name="rain.wav"
    Content-Disposition: attachment; filename="rain.wav"
    Content-Transfer-Encoding: base64
    Content-Description: rain.wav

    (here comes a copy of file "rain.wav" encoded to BASE64)
    ------=_NextPart_000_032_XXHUGGHU.VIHXOHG2
    Content-Type: application/octet-stream; name="usaflag.gif"
    Content-Disposition: attachment; filename="usaflag.gif"
    Content-Transfer-Encoding: base64
    Content-Description: usaflag.gif

    (here comes a copy of file "usaflag.gif" encoded to BASE64)
    ------=_NextPart_000_032_XXHUGGHU.VIHXOHG2
    Content-Type: text/html
    Content-Disposition: inline

    <font face=Garamond size=-2>
    <br><br>
    <b>Note.</b> This message was created through some simple RPG utility
    and distributed through the OS/400 QtmmSendMail API.<br>
    This utility is available at no charge, and includes all sources.<br>
    It has no SW prerequisites, runs from OS/400 release V4R5 on.<br>
    For information and download:<br><font face=Courier size=-2>
    http://www.easy400.net/mmail/start</font>
    </font><br><br>


  12.   MimeImbDbf - Embed or attach a database file.
    Inputs: • IFS MIME file name
    • Database file library name
    • Database file name
    • Database file member name
    • Embed/Attach parameter: 1=Embed, 2=Attach
    Content-ID number optional parameter
    Output: • return code: 0=successful, -1=cpytostmf failed


    Example:

    Attaching database file MMAIL/ADDR member *FIRST
    D rc              s             10i 0
    D MimeStmf        s            512a
    D DbfLib          s             10a
    D DbfFile         s             10a
    D DbfMbr          s             10a
    D ImbAtt          s             10i 0
    D ImbAttCid       s             10i 0
     *  Attach database file MMAIL/ADDR member *FIRST
    C                   eval      DbfLib  = 'MMAIL'
    C                   eval      DbfFile = 'ADDR'
    C                   eval      DbfMbr  = '*FIRST'
    C                   eval      ImbAtt=2
    C                   eval      rc = MimeImbDbf(MimeStmf:
    C                             DbfLib:DbfFile:DbfMbr:
    C                             ImbAtt)

    Note.Only the initial 2,000 bytes of each record are taken. Non-character data are taken "as is".

  13.   MimeImbSrc - Embed or attach a source member.
    Inputs: • IFS MIME file name
    • Source library name
    • Source file name
    • Source member name
    • Embed/Attach parameter: 1=Embed, 2=Attach
    Content-ID number optional parameter
    • Character set.
    This is an optional parameter for the embedded text. If omitted it defaults to ISO-8859-1. Use it to have your embedded text represented as due by the receiving mailer.
    For a list of available character sets, see this page.
    Output: • return code: 0=successful, -1=cpytostmf failed


    Example:

    Attaching source member MMAIL/QRPGLESRC CRTMIME
    D rc              s             10i 0
    D MimeStmf        s            512a
    D Srclib          s             10a
    D SrcFile         s             10a
    D SrcMbr          s             10a
    D ImbAtt          s             10i 0
    D ImbAttCid       s             10i 0
    D CharSet         s             50a   varying
     *  Attach source member MMAIL/QRPGLESRC CRTMIME
    C                   eval      SrcLib  = 'MMAIL'
    C                   eval      SrcFile = 'QRPGLESRC'
    C                   eval      SrcMbr  = 'CRTMIME'
    C                   eval      ImbAtt=2
    C                   eval      rc = MimeImbSrc(MimeStmf:
    C                             SrcLib:SrcFile:SrcMbr:
    C                             ImbAtt:CharSet)

  14.   MimeImbSpl - Embed or attach a spool file.
    Inputs: • IFS MIME file name
    • Spool file name
    • Spool file number
    • Name of the job generating the spool file
    • User profile of the job generating the spool file
    • Joblog number of the job generating the spool file
    • Embed/Attach parameter: 1=Embed, 2=Attach
    Content-ID number optional parameter
    Output: • return code: 0=successful, -1=cpysplf failed, -2=cpytostmf failed


    Example:

    Attaching last spool file QSYSPRT generated by job 045122/QPGMR/LIST
    D rc              s             10i 0
    D MimeStmf        s            512a
    D SplName         s             10a
    D SplNbr          s              6a
    D SplJobName      s             10a
    D SplJobUser      s             10a
    D SplJobNbr       s              6a
    D ImbAtt          s             10i 0
    D ImbAttCid       s             10i 0
     *  Attach last spool file QSYSPRT generated by job 045122/QPGMR/LIST
    C                   eval      SplName    = 'QSYSPRT'
    C                   eval      SplNbr     = '*LAST'
    C                   eval      SplJobName = 'LIST'
    C                   eval      SplJobUser = 'QPGMR'
    C                   eval      SplJobNbr  = '045122'
    C                   eval      ImbAtt=2
    C                   eval      rc = MimeImbSpl(MimeStmf:
    C                             SplName:SplNbr:
    C                             SplJobName:SplJobUser:SplJobNbr:
    C                             ImbAtt)

    As another example, we provide program mmail/testspl. This program generates a MIME file containing two spool files: /mmail/mime/testspl.txt.
    You can run this program and use command mmail/sndmime to send yourself that mime file.
    We also suggest you browse its source: member testspl in source file mmail/qrpglesrc.

  15.   MimeSplPdf - Convert a spool file to PDF and attach it.
    Inputs: • IFS MIME file name
    • Spool file name
    • Spool file number
    • Name of the job generating the spool file
    • User profile of the job generating the spool file
    • Joblog number of the job generating the spool file
    Content-ID number (optional parameter)
    • Save (archive) directory for the PDF (optional parameter)
    • PDF file name (optional parameter)
    Output: • return code: 0=successful, not-0=unsuccessful


    Example:

    Attaching the PDF generated from the last spool file QSYSPRT of job 045122/QPGMR/LIST
    D rc              s             10i 0
    D MimeStmf        s            512a
    D SplName         s             10a
    D SplNbr          s              6a
    D SplJobName      s             10a
    D SplJobUser      s             10a
    D SplJobNbr       s              6a
    D ImbAttCid       s             10i 0
    D PdfSaveDir      s            512a
    D PdfName         s            512a
     *  Convert to PDF and attach the last spool file QSYSPRT generated by job 045122/QPGMR/LIST.
     *  Save the spool file in the directory specified in variable PdfSaveDir .
     *  Assign to the PDF the name specified in variable PdfName .
    C                   eval      SplName    = 'QSYSPRT'
    C                   eval      SplNbr     = '*LAST'
    C                   eval      SplJobName = 'LIST'
    C                   eval      SplJobUser = 'QPGMR'
    C                   eval      SplJobNbr  = '045122'
    C                   eval      rc = MimeSplPdf(MimeStmf:
    C                             SplName:SplNbr:
    C                             SplJobName:SplJobUser:SplJobNbr:
    C                             ImbAttCid:PdfSaveDir:PdfName)

    This subprocedure does its job if the required prerequisites are fullfilled. In case they are not, procedure IbmAttSplf takes over.

    The spool_file_to_PDF conversion program used in this process is the utility selected through command MMAIL/CVTTOPDF.
    Note 1- For additional parameters of command CVTSPLSTMF when spool file conversion to PDF is requested, see Note on CVTSPLSTMF spool file conversion to PDF.
    Note 2- If the selected utility is CVTSPLSTMF (which handles only SCS spool files) and the spool file type is AFP, then utility CVTSPLFPDF (which handles both SCS and AFP spool files) is used instead.

      Of course, instead of using the one of the CVTTOPDF supported utilities to convert spool files to PDF, one may decide to use a different utility/product. In such a case, some statements in MMAIL/QRPGLESRC member XXXMIME must be changed for subprocedure MIMESPLDBF. This is a rather easy job for an ILE-RPG programmer. After performing the changes, use command MMAIL/COMPILE to regenerate all MMAIL service programs and programs.

  16.   MimeClose - Close a MIME file
    In order to propely close a MIME file, add the boundary tag
       ----=_NextPart_000_032_XXHUGGHU.VIHXOHG2
    followed by two hyphens ("--")
    Input: • IFS MIME file name
    Example:
    D rc              s             10i 0
    D MimeStmf        s            512a
     *  Close the MIME file by the part delimiter followed by "--"
    C                   callp     MimeClose(MimeStmf )
        

2. Subprocedures to complete and to send a MIME file
The following subprocedures allow to complete a MIME file (by adding on top sender and receivers headers), and to send it.
The process is as follow:
 
i. create a "temporary" IFS file  using subprocedure  TempCrtF
ii. add to it the  top headers 
iii. append the MIME file  using subprocedure  MimeCpyTxt
iv. send it  using subprocedure  SendMail
(This is, for instance, the process implemented by command mmail/sndmime)

 
1. TempCrtF - Create an empty "temporary" IFS file
2. MimeSender - Add the Sender header 
3. MimeRpyto - Add Reply-to headertop
4. MimeRtnPth - Add Return-path header 
5. MimeDistr - Add distribution headersheaders
6. MimeNotif - Add the Disposition Notification header  
7. MimeCpyTxt - Embed an IFS text file
8. SendMail - Mail the complete MIME file


  1.   TempCrtF - Create an empty "temporary" IFS file
    Create a "temporary" IFS file and return its name, complete of path and extension.
    Input: none
    Output: • Name of the temporary IFS file just created
    Example:
    D TempStmf        s            512a
    C                   eval      TempStmf=TempCrtF


  2.   MimeSender - Add the Sender header
    Inputs: • Name of the IFS "temporary" file
    • Sender's name
    • Sender's e-mail
    Output: none
    Example:
    D MimeStmf        s            512a
    D MimeSName       s            50a
    D MimeSEmail      s            50a
    C                   eval      MimeSName='Giovanni B. Perotti'
    C                   eval      MimeSEmail='gb_perotti@easy400.net'
    C                   callp     MimeSender(TempStmf:
    C                             MimeSName:MimeSEmail)
    Contents of the file so far:
    Sender: gb_perotti@easy400.net
    Date: Wed, 09 Oct 2002 13:21:13 +0100
    From: Giovanni B. Perotti <gb_perotti@easy400.net>
    MIME-Version: 1.0
    Note that a Date and a MIME-Version headers are also generated by this subprocedure.

  3.   MimeRpyTo - Add the Reply-to header
    Inputs: • Name of the IFS "temporary" file
    • Reply-to e-mail: e-mail destination of a reply, if other than the sender's one
    Output: none
    Example:
    D TempStmf        s            512a
    D ReplyTo         s            50a
    C                   eval      ReplyTo='otherAddr@easy400.net'
    C                   callp     MimeRpyTo(TempStmf:ReplyTo)
    Contents of the file so far:
    Sender: gb_perotti@easy400.net
    Date: Wed, 09 Oct 2002 13:21:13 +0100
    From: Giovanni B. Perotti <gb_perotti@easy400.net>
    MIME-Version: 1.0
    Reply-to: otherAddr@easy400.net
    Note- The "reply-to" address *FROMADDR identifies the sender as the one to receive a reply message.
    This is also the case when the "Reply-to" header is omitted.

  4.   MimeRtnPth - Add Return-path header
    In case of a message delivery error (for instance, the receiver's address was not found), a so called bounce message is returned to the originator (the sender's address or the Reply-to address).
    In some cases, it may be useful to have such error messages returned to a different address, specified in the Return-path header. In this way, the error message could, for instance, be processed by some program rather than some human being.
    For more information on this, see Bounce message, in Wikipedia.
    Inputs: • Name of the IFS "temporary" file
    • Return address
    Output: none
    Example:
    D TempStmf        s            512a
    D ReturnPth       s           256a
    C                   eval      ReturnPth='bouncemgr@easy400.net'
    C                   callp     MimeRtnPth(TempStmf:ReturnPth)
    Contents of the file so far:
    Sender: gb_perotti@easy400.net
    Date: Wed, 09 Oct 2002 13:21:13 +0100
    From: Giovanni B. Perotti <gb_perotti@easy400.net>
    MIME-Version: 1.0
    Return-path: <bouncemgr@easy400.net>


  5.   MimeDistr - Add distribution headers
    Inputs: • Name of the IFS "temporary" file
    • Array of receiver names
    • Array of receiver e-mail addresses
    • Array of distribution codes: 0=to, 1=cc, 2=bcc
    Output: none
    Note.The subprocedure stops generation at the first blank receiver name.
    Example:
    D TempStmf        s            512a
    D ToNameArr       s             50a   dim(1000)
    D ToAddrArr       s            256a   dim(1000)
    D ToDistArr       s             10i 0 dim(1000)
    C                   eval      ToNameArr(1)='tim fellow'
    C                   eval      ToAddrArr(1)='timfell@netmail.com'
    C                   eval      ToDistArr(1)=0
    C                   eval      ToNameArr(2)='helen grass'
    C                   eval      ToAddrArr(2)='grassh@nubi.com'
    C                   eval      ToDistArr(2)=0
    C                   eval      ToNameArr(3)='tom sailor'
    C                   eval      ToAddrArr(3)='tsailor@fanti.com'
    C                   eval      ToDistArr(3)=1
    C                   eval      ToNameArr(4)= ' '
    C                   callp     MimeDistr(TempStmf:ToNameArr:
    C                             ToAddrArr:ToDistArr)
    Contents of the file so far:
    Sender: gb_perotti@easy400.net
    Date: Wed, 09 Oct 2002 13:21:13 +0100
    From: Giovanni B. Perotti <gb_perotti@easy400.net>
    MIME-Version: 1.0
    To: tim fellow <timfell@netmail.com>,
    helen grass <grassh@nubi@com>
    cc: tom sailor <tsailor@fanti.com>


  6.   MimeNotif- Add the Disposition Notification header
    Use this optional subprocedure only if you want the sender be returned a receipt from each of the recipients when the message is opened.
    Inputs: • Name of the IFS "temporary" file
    • Sender's name
    • Sender's e-mail address
    Example:
    D MimeStmf        s            512a
    D MimeSName       s            50a
    D MimeSEmail      s            50a
    C                   callp     MimeNotif(TempStmf:
    C                             MimeSName:MimeSEmail)
    Contents of the file so far:
    Sender: gb_perotti@easy400.net
    Date: Wed, 09 Oct 2002 13:21:13 +0100
    From: Giovanni B. Perotti <gb_perotti@easy400.net>
    MIME-Version: 1.0
    To: tim fellow <timfell@netmail.com>,
    helen grass <grassh@nubi@com>
    cc: tom sailor <tsailor@fanti.com>
    Disposition-Notification-To: "Giovanni B. Perotti" <gb_perotti@easy400.net>


  7.   MimeCpyTxt - Embed an IFS text stream file
    Inputs: • Name of the target IFS stream file
    • Name of the text stream file to be copied into the target IFS stream file
    Output: none
    Note - This subprocedure is often used to attach a MIME file to the "temporary" IFS file.
    Example:
    D TempStmf        s            512a
    D MimeStmf        s            512a
    C                   eval      MimeFName='/mmail/work/sample3.txt'
    C                   callp     MimeCpyTxt(TempStmf:MimeStmf)
    Once this is done, the message is complete and can be sent.

  8.   SendMail - Mail the complete MIME file
    This subprocedure is used to call the QtmmSendMail API, which mails the MIME file.
    Inputs: • Name of the IFS "temporary" file
    • Sender's e-mail
    • Array of receiver e-mail addresses (the first blank entry ends the sending)
    • Array of distribution codes: 0=to, 1=cc, 2=bcc
    • Optional: email addresses validation option.
    Action to be taken if some email address is found to be non compliant with email address syntax rules
    • 1 (default): the email message is sent
    • 2 : the incorrect email addresses are removed before the email message is sent
    • Optional: IFS directory where sent messages should be copied
    Output: • CPF message ID (blank if no errors)
    Example:
    D TempStmf        s            512a
    D FromAddr        s            255a
    D ToAddrArr       s            256a   dim(1000)
    D ToDistArr       s             10i 0 dim(1000)
    D EmlVldOpt       s             10i 0 inz(2)
    D SaveDir         s            512a   inz('/mmail/history')
    D CpfID           s              7a
     *Send a MIME message, without saving it
    C                   eval      CpfID=SendMail(TempStmf: FromAddr:
    C                             ToAddrArr:ToDistArr)
     *Send a MIME message and save it
    C                   eval      CpfID=SendMail(TempStmf: FromAddr:
    C                             ToAddrArr:ToDistArr:EmlVldOpt:
    C                             SaveDir)
    If the returned CPF message is blank, the mailing was performed and the temporary file was deleted by the QtmSendMail API.
    Notes.
    1. Subprocedure SendMail cand send a message up to 1,000 receivers in a single shot (see arrays ToAddrArr and ToDistArr).
    2. Mandatory blank copies (blind copies). You may ask this subprocedure to send blank copies (blind copies) of any outgoing message to a given distribution list. A company auditing requirement could, for instance, need this to be done.
      In order to achieve this, you must
      1. make sure that data area MMAILDATA/MDTBC contains 'Y'
      2. add (please use a DFU for that) to file MMAILDATA/MDTBC a record for each receiver of a blank (blind) copy; the record contains two fields:
        • the e-mail address of a recipient
        • an active flag, that should be set to 'Y' in order to enable the recipient
    3. The email addresses of the sender and of the recipients are always inspected:
      • an incorrect sender email address results in the message not being sent
      • incorrect recipient email addresses may result either in the message being stopped or in the bad email addressed being removed before the message is sent, depending on the value (1 or 2) of the fifth parameter
      • if the final distribution has no email addresses, the message is not sent
      Program messages document the number of valid and invalid email addresses, and whether the message was sent or not. When the message is not sent because of errors in the email addresses, CPF9899 is returned.
    4. QtmSendMail API deletes the (temporary) MIME file if the sending had no major problems. Temporary MIME files are created by subprocedure TempCrtF in the IFS directory /mmail/temp. After sending a critical message, you may want to check whether the temporary MIME file is still in the directory /mmail/temp. In such a case, the message was not sent.


3. Miscellaneous subprocedures

  1. AddHyper - Add hyperlinks to a stream file
  2. ChkIfs - Check whether an IFS file exists
  3. CrtWrkF - Create an ASCII work stream file
  4. StgToIfs - Write a text string to an existing stream file
  5. MimeUpdTxt - Customize a MIME file
  6. RtvSplFA - Retrieve spooled file attributes
  7. RtvSplFTit - Retrieve spooled file title
  8. RtvObjLib - Retrieve object library
  9. RtvExeEnv - Retrieve execution environment
  10. RtvDftCsid - Retrieve default CCSID
  11. SetJobCsid - Set job CCSID
  12. VldEmail - Validate an e-mail address
  1.   AddHyper - Add hyperlinks to a stream file
    The stream file is supposed to be an HTML stream file. Texts containing URLs (http://...) or e-mail addresses are added hyperlinks that allow to connect to web pages or to the local mailer.
    Inputs: • Qualified name of the IFS file
    Outputs: • none
    Example:
    D stmf1000        s           1000    varying
    C                   callp     addHyper(stmf1000)


  2.   ChkIfs - Check whether an IFS file exists
    If the IFS file exists, the subprocedure returns its size and creation timestamp (GMT).
    Inputs: • Qualified name of the IFS file
    Outputs: • Return code: 0=found, -1=not found
    • File size
    • Creation/Last change timestamp (GMT)
    Example:
    D  IfsFileNam     s           1024a
    D  IfsFileSiz     s             10i 0
    D  IfsCrtStamp    s               z
    D  retCde         s             10i 0
    C                   eval      IfsFilename = '/mmail/text/Example03.txt'
    C                   eval      retCde = ChkIfs(IfsFileNam:IfsFileSiz:
    C                                  IfsCrtStamp)


  3.   CrtWrkF - Create an ASCII work stream file
    Use this subprocedure to create an ASCII (code page 819) temporary stream file in directory /mmail/work.
    This stream file could for instance host (via subprocedure StgToIfs, see next) a text string to become the message body of a MIME stream file (see subprocedure MimeImbTxt previously in this page).
    It is a program responsibility to delete this ASCII work stream file as soon as no longer needed.
    Input: • none
    Outputs: • Name of the ASCII work stream file just created
    Example:
    D  WorkFile       s            256             
    C                   eval      Workfile=CrtWrkF


  4.   StgToIfs - Write a text string to an IFS stream file
    Use this subprocedure to write a text string to an existing stream file (for instance created by subprocedure CrtWrkF).
    An example could be that of a CGI program receiving an input string from an HTML form. The string could then by copied with this subprocedure to a stream file used to make up a message body via subprocedure MimeImbTxtF
    Input: • the name of the variable containing the text string
    • the name of the IFS stream file to receive the text string
    Outputs: • Return code: 0=successful, -1=unsuccessful
    Example:
    D RetCode         s             10i 0                             
    D String          s           5000       (any length, up to 32767)
    D TgtIfs          s           1024       (any length, up to 1024) 
    C                   eval      retcode=StgToIfs(String:TgtIfs)     
    


  5.   MimeUpdTxt - Customize a MIME file
    If you have the need to distribute a MIME file, customized (that is, where some variables are replaced by given values) for each receiver, you have to go through the following steps:
    1. create a text IFS file containing the message to be customized. Represent your variables in the way that better fits your needs (e.g. &1 for the customer number, &2 for the customer name, etc.)
    2. build the "body" of your MIME file either using command mmail/crtmime, or through a program which implements the subprocedure described in "1.Subprocedures to create the "body" of a MIME file". Of course, do not forget to embed the text IFS file, as per the previous point.
    3. now, write your ILE-RPG program that scans your control file (e.g. customer file). It should customize and send the MIME file (see previous point) to each of the customers.
      To perform this, your program should use the following subprocedures (see "2.Subprocedures to complete and to send a MIME file")
      1. TempCrtF- Create a temporary file
      2. MimeSender- Add the Sender header
      3. MimeDistr- To add a single distribution header
      4. Instead of using subprocedure MimeCpyTxt, it should use subprocedure MimeUpdTxt (see next) to merge your MIME file into the temporary file while substituting the output variables with customer record values
      5. SendMail- To mail the temporary file
      As an example, you may take a look at member CUSTMAIL in mmail/qrpglesrc

    Subprocedure MimeUpdTxt:

    Inputs: • Name of the IFS "temporary" file
    • Name of the MIME file to be merged and customized into the IFS "temporary"file
    • Array of the output variables names:
    up to 500 substitution variables;
    the first blank entry ends substitution
    • Array of the corresponding substitution values
    Output: none

    Example:
    D MimeStmf        s            512a
    D MimeFName       s            512a
    D TxtVarArr       s             10a   dim(500)
    D TxtValArr       s            500a   dim(500)
     * Initialization
    C                   eval      MimeFName = '/mydir/ToBeCustomized.txt'
    C                   eval      TxtVarArr(1)='&1'
    C                   eval      TxtVarArr(2)='&2'
     * Read the customer file.
     * For each record,
     * -create a temporary IFS file ("MimeStmf ")
     * -add sender information
     * -add receiver information (taken from the customer record)
     * -give a values to each substitution varaiable: e.g.
    C                   eval      TxtValArr(1)=CustNbr
    C                   eval      TxtValArr(2)=CustName
     * -merge and customize the MIME file
    C                   callp     MimeUpdTxt(TempStmf:MimeFName:
    C                             TxtVarArr:TxtValArr)
     * -mail the temporary IFS file (subp. SendMail) to this customer


  6.   RtvSplFA - Retrieve spooled file attributes
    This subprocedure maybe of some help if you are going to develop programs for handling spooled files.
    It calls API QUSRSPLA and returns a 1512 byte string containing the attributes of the spooled file. This string, named SPLA, is mapped in MMAIL/QRPGLESRC member SPLA.
    Inputs:
    1. qualified job name (char 26): job_name + user_name + job_number
    2. spooled file name (char 10)
    3. spooled file number (bin 4); special values:
      • 0 = *ONLY
      • -1 = *LAST
    Output: 1512 byte string ("SPLA") containing the spooled file attributes.
    If the spooled file does not exist or cannot be accessed, this string contains all blanks.
    Example:
     /copy MMAIL/qrpglesrc,SPLA
    D  FJobname       s             26a
    D  SplfName       s             10a
    D  SplfNbr        s              9b 0
       ...   ...   ...
    C                   eval      SPLA=RtvSplFA(FJobname:SplFName:
    C                             SplfNbr)


  7.   RtvSplFTit - Retrieve spooled file title
    For *SCS spool files only, it retrieves the title of the spool file from the first non-blank print line.
    Inputs:
    1. spool file name (char 10)
    2. job creating the spool file
      job name (char 10)
      user name (char 10)
      job number (char 6)
    3. spool file number (char 6, six digits)
    Output: 70 char string containing the title of the SCS spooled file or blanks.
    Example:
    D splfname        s             10
    D splfname        s             10
    D jobnam          s             10
    D usrnam          s             10
    D jobnbr          s              6
    D splfnbr         s              6
    D splfTitle       s             70
    C                   eval      splfTitle=rtvSplfTit(splfname:
    C                             jobnam:usrnam:jobnbr:
    C                             splfnbr)


  8.   RtvObjLib - Retrieve object library
    It allows to retrieve the library of an object from *LIBL.
    Inputs:
    1. '*LIBL' or '*CURLIB' (char 10)
    2. object name (char 10)
    3. object type (char 8)
    Output: a 10 char string containing:
    • the library name for the object, if it could be retrieved
    • blanks, if it could not be retrieved
    Example:
    D  ObjLib         s             10a
    D  ObjName        s             10a
    D  ObjType        s              8a
    D  RtnLib         s             10a
       ...   ...   ...
    C                   eval      ObjLib  = '*LIBL'
    C                   eval      ObjName = 'XXX'
    C                   eval      ObjFile = '*FILE'
    C                   eval      RtnLib=RtvObjLib(ObjLib:ObjName:
    C                             ObjType)
     * OR
    C                   eval      RtnLib=RtvObjLib('*LIBL':'XXX':
    C                             '*FILE')


  9.   RtvExeEnv - Retrieve execution environment
    It allows to retrieve the execution environment (interactive or batch) of the current job.
    Inputs: none
    Output: a 1 char string containing:
    • '0', if the job is running in batch mode
    • '1', if the job is running in interactive mode
    Example:
    D  EnvType        s              1a
       ...   ...   ...
    C                   eval      EnvType=RtvExeEnv


  10.   RtvDftCsid - Retrieve default CCSID
    It allows to retrieve the CCSID the system should have depending on system value QLANGID. For instance, if system value QLANGID id ENU, then the CCSID value retrieved is 37.
    D  DftCCSID       s             10i 0
       ...   ...   ...
    C                   eval     DftCCSID=RtvDftCsid


  11.   SetJobCsid - Set job CCSID
    Performs the following if system value QCCSID is 65535:
    • retrieves system value QLANGID
    • establishes the appropriate CCSID for system value QLANGID (e.g. if QLANGID is ENU, then the correct CCSID is 37)
    • changes the job CCID to its appropriate value
    • changes the CCSID of all the QMSF jobs to this appropriate value
    Inputs: none(char 256)
    Output: a 10 char string containing:
    • system value QCCSID (char 1 to 5)
    • the appropriate job CCSID (char 6 to 10)
    Example:
    D  jobCCSIDs      s             10a
       ...   ...   ...
    C                   eval      jobCCSIDs=SetJobCSID


  12.   VldEmail - Validate e-mail address
    Validates an e-mail address.
    Inputs: e-mail address (char 256)
    Output: return code containing:
    • 0, if the e-mail address was validated
    • -1', if the e-mail failed to be validated
    Example:
    D  email          s            256a
    D  rc             s             10i 0
       ...   ...   ...
    C                   eval      rc=VldEmail(email)


For a quick walk-through service program subprocedures,
please check out page Message building procedures - Reference tables





    Contact