AnyMail/400 Mail Server Framework Developer Guide January 1995

440
International Technical Support Organization AnyMail/400 Mail Server Framework Developer Guide January 1995 GG24-4449-00

Transcript of AnyMail/400 Mail Server Framework Developer Guide January 1995

Page 1: AnyMail/400 Mail Server Framework Developer Guide January 1995

International Technical Support Organization

AnyMail/400 Mail Server FrameworkDeveloper Guide

January 1995

GG24-4449-00

Page 2: AnyMail/400 Mail Server Framework Developer Guide January 1995
Page 3: AnyMail/400 Mail Server Framework Developer Guide January 1995

International Technical Support Organization

AnyMail/400 Mail Server FrameworkDeveloper Guide

January 1995

GG24-4449-00

IBML

Page 4: AnyMail/400 Mail Server Framework Developer Guide January 1995

Take Note!

Before using this information and the product it supports, be sure to read the general information under“Special Notices” on page xiv.

First Edition (January 1995)

This edition applies to Version 3, Release 1.0 of the AS/400 Operating System/400.

Order publications through your IBM representative or the IBM branch office serving your locality. Publicationsare not stocked at the address given below.

An ITSO Technical Bulletin Evaluation Form for reader′s feedback appears facing Chapter 1. If the form has beenremoved, comments may be addressed to:

IBM Corporation, International Technical Support OrganizationDept. 44C Building 015-23605 Highway 52NRochester, Minnesota 55901-7829

When you send information to IBM, you grant IBM a non-exclusive right to use or distribute the information in anyway it believes appropriate without incurring any obligation to you.

Copyright International Business Machines Corporation 1995. All rights reserved.Note to U.S. Government Users — Documentation related to restricted rights — Use, duplication or disclosure issubject to restrictions set forth in GSA ADP Schedule Contract with IBM Corp.

Page 5: AnyMail/400 Mail Server Framework Developer Guide January 1995

Abstract

This document is unique in its detailed coverage of the AnyMail/400 Mail ServerFramework (MSF). It focuses on the technical details needed to understand howthe mail server framework works. It provides information about how to writeprograms that will create MSF messages or act on MSF messages as MSF exitpoint programs.

This document is written to assist AS/400 programmers write mail messagingapplications using MSF. The reader′s knowledge of basic electronic messagingconcepts is assumed. Its scope includes a description of MSF, designing MSFapplications, configuring MSF, MSF operation, and MSF problem determination.

(398 pages)

Copyright IBM Corp. 1995 iii

Page 6: AnyMail/400 Mail Server Framework Developer Guide January 1995

iv AnyMail/400 MSF

Page 7: AnyMail/400 Mail Server Framework Developer Guide January 1995

Contents

Abstract . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . i i i

Special Notices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xiv

Preface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xviHow This Document is Organized . . . . . . . . . . . . . . . . . . . . . . . . . xviRelated Publications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xviiiInternational Technical Support Organization Publications . . . . . . . . . . xviiiAcknowledgments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxi

Chapter 1. Introduction to AnyMail/400 Mail Server Framework . . . . . . . . 1Benefits of the Mail Server Framework . . . . . . . . . . . . . . . . . . . . . . . 2

Chapter 2. Mail Server Framework Concepts . . . . . . . . . . . . . . . . . . . 3MSF Exit Points . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3Typing of MSF Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5Addressing Group Exit Points . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6

List Expansion (QIBM_QZMFMSF_LST_EXP) . . . . . . . . . . . . . . . . . . . 7Address Resolution (QIBM_QZMFMSF_ADR_RSL) . . . . . . . . . . . . . . . 7

Pre-delivery Processing Group Exit Points . . . . . . . . . . . . . . . . . . . . . 8Envelope Processing (QIBM_QZMFMSF_ENV_PSS) . . . . . . . . . . . . . . 9Attachment Conversion (QIBM_QZMFMSF_ATT_CNV) . . . . . . . . . . . . . 9Security and Authority (QIBM_QZMFMSF_SEC_AUT) . . . . . . . . . . . . . 10

Delivery Group Exit Points . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10Local Delivery (QIBM_QZMFMSF_LCL_DEL) . . . . . . . . . . . . . . . . . . . 11Message Forwarding (QIBM_QZMFMSF_MSG_FWD) . . . . . . . . . . . . . . 11

Management Group Exit Points . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11Non-Delivery (QIBM_QZMFMSF_NON_DEL) . . . . . . . . . . . . . . . . . . . 12Attachment Management (QIBM_QZMFMSF_ATT_MGT) . . . . . . . . . . . 12Accounting (QIBM_QZMFMSF_ACT) . . . . . . . . . . . . . . . . . . . . . . . 13

Creating MSF Messages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13MSF Message Flow . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15Determining the Exit Point Program to Call . . . . . . . . . . . . . . . . . . . . . 16

Chapter 3. Mail Server Framework Configuration . . . . . . . . . . . . . . . . . 18MSF Data Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18

Rules for MSF Data Type Definitions . . . . . . . . . . . . . . . . . . . . . . . 19List of IBM-Supplied Data Types . . . . . . . . . . . . . . . . . . . . . . . . . . 19

MSF Configuration APIs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21OS/400 User Registration Facility . . . . . . . . . . . . . . . . . . . . . . . . . . . 22

IBM-Supplied Exit Points for the MSF . . . . . . . . . . . . . . . . . . . . . . . 22IBM-Supplied Exit Point Programs for the MSF . . . . . . . . . . . . . . . . . 22Registering Exit Point Programs . . . . . . . . . . . . . . . . . . . . . . . . . . 23Rules for MSF Exit Point Program Data . . . . . . . . . . . . . . . . . . . . . . 27

Registration Facility APIs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28

Chapter 4. Mail Server Framework Operation . . . . . . . . . . . . . . . . . . . 29Starting MSF . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29

Start Mail Server Framework Command . . . . . . . . . . . . . . . . . . . . . 29Copying the MSF Configuration . . . . . . . . . . . . . . . . . . . . . . . . . . 30Preparation of Existing MSF Messages . . . . . . . . . . . . . . . . . . . . . . 31

Copyright IBM Corp. 1995 v

Page 8: AnyMail/400 Mail Server Framework Developer Guide January 1995

QMSF Job Submission . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36Ending MSF . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37

End Mail Server Framework Command . . . . . . . . . . . . . . . . . . . . . . 37Immediate or Controlled Ending . . . . . . . . . . . . . . . . . . . . . . . . . . 38

QMSF Job Structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39MSF Scalability . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40Automatic Starting of MSF . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41

MSF Queue . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43

Chapter 5. Mail Server Framework Message . . . . . . . . . . . . . . . . . . . . 44MSF Message Content . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44

MSF Message Identifiers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46How an MSF Message Gets Created . . . . . . . . . . . . . . . . . . . . . . . . . 46MSF Message Information Data Types . . . . . . . . . . . . . . . . . . . . . . . . 48MSF Message Lists — Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . 48

Overall Rules for MSF Message Lists . . . . . . . . . . . . . . . . . . . . . . . 49MSF Message Lists Common Header . . . . . . . . . . . . . . . . . . . . . . . . 50Common List Entry Format . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52

List Entry IDs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52List Entry Reference IDs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53

Originator List . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53Originator List Entry . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54

Envelope List . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56Envelope List Entry . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57

Recipient List . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58Recipient List Entry . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59

Attachment Reference List . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62Attachment Reference List Entry . . . . . . . . . . . . . . . . . . . . . . . . . . 63

Original Recipient List . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64Original Recipient List Entry . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65

Reply-to List . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67Reply-to List Entry . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67

Report-to List . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69Report-to List Entry . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69

Report-on List . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71Report-on List Entry . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71

Exit Point Call History List . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74Exit Point Call History List Entry . . . . . . . . . . . . . . . . . . . . . . . . . . 75

Recipient History List . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76Recipient History List Entry . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76

System Considerations for MSF Messages . . . . . . . . . . . . . . . . . . . . . 78

Chapter 6. Mail Server Framework Exit Points . . . . . . . . . . . . . . . . . . . 80MSF Exit Points Versus Snap-in Exit Points . . . . . . . . . . . . . . . . . . . . . 80

Considerations for MSF Exit Point Program Designers . . . . . . . . . . . . 82MSF Message Information and Exit Point Programs . . . . . . . . . . . . . . . . 85Basic Design of Exit Point Programs . . . . . . . . . . . . . . . . . . . . . . . . . 86Multiple Exit Point Programs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87

Determining Which Exit Point Program to Call . . . . . . . . . . . . . . . . . 87Data Type Evaluation and Call Cycle . . . . . . . . . . . . . . . . . . . . . . . . . 90Why Exit Point Program Order Is Important . . . . . . . . . . . . . . . . . . . . . 93Using QzmfChgMailMsg to Put Back Recipients . . . . . . . . . . . . . . . . . . 95How MSF Uses Recipient List Address and Message Types . . . . . . . . . . . 98Special Properties of the Addressing Group Exit Points . . . . . . . . . . . . 101

List Expansion Exit Point Reevaluation . . . . . . . . . . . . . . . . . . . . . 102

vi AnyMail/400 MSF

Page 9: AnyMail/400 Mail Server Framework Developer Guide January 1995

Address Resolution Exit Point Reevaluation . . . . . . . . . . . . . . . . . . 104How MSF Uses Recipient List Status . . . . . . . . . . . . . . . . . . . . . . . . 110

Special Status Field Values . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112How an Exit Point Program Changes a Message . . . . . . . . . . . . . . . . 114Exit Point Program Rules Tables . . . . . . . . . . . . . . . . . . . . . . . . . . 118Exit Point Programs Shipped in V3R1 . . . . . . . . . . . . . . . . . . . . . . . 122Special Exit Points . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123

Track Changes Exit Point (QIBM_QZMFMSF_TRK_CHG) . . . . . . . . . . 123Validate Data Field Exit Point (QIBM_QZMFMSF_VLD_TYP) . . . . . . . . 125

Chapter 7. Summary of the Mail Server Framework APIs . . . . . . . . . . . 133Configurations APIs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134Message APIs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134

Chapter 8. Mail Server Framework Configuration APIs . . . . . . . . . . . . . 137Add Mail Server Framework Configuration (QzmfAddMailCfg) API . . . . . . 137

Required Parameter Group . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137ADDC0100 Format . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137Add MSF Configuration API Field Descriptions . . . . . . . . . . . . . . . . 138Examples for Add Mail Configuration API . . . . . . . . . . . . . . . . . . . 138

Remove Mail Server Framework Configuration (QzmfRmvMailCfg) API . . . 140Required Parameter Group . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140DLTC0100 Format . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140Remove MSF Configuration Field Descriptions . . . . . . . . . . . . . . . . 140Examples for Remove Mail Configuration API . . . . . . . . . . . . . . . . . 141

List Mail Server Framework Configuration (QzmfLstMailCfg) API . . . . . . . 142Required Parameter Group . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142LSTL0100 Format . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143LSTC0100 Format . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143List MSF Field Descriptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143Examples for List Mail Configuration API . . . . . . . . . . . . . . . . . . . . 144

Chapter 9. Working with Mail Message Lists . . . . . . . . . . . . . . . . . . . 146MSF Message List − Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 146Defining MSF Message Lists in ILE C/400 . . . . . . . . . . . . . . . . . . . . . 148

Handling Variable Length Fields . . . . . . . . . . . . . . . . . . . . . . . . . 151Building MSF Message Descriptor Arrays in ILE C/400 . . . . . . . . . . . . . 152Using MSF Message Lists to Create a Message . . . . . . . . . . . . . . . . . 153Working with MSF Message Lists Passed to Exit Point Programs . . . . . . 155Using Message Descriptors to Retrieve Information . . . . . . . . . . . . . . . 159Using MSF Message Lists to Change a Message . . . . . . . . . . . . . . . . 161

Chapter 10. Creating a Mail Message . . . . . . . . . . . . . . . . . . . . . . . 163Create Mail Message (QzmfCrtMailMsg) API . . . . . . . . . . . . . . . . . . . 163

Chapter 11. Retrieving Mail Message Information . . . . . . . . . . . . . . . . 168Information Returned by the Retrieve Mail Message API . . . . . . . . . . . . 168Retrieve Mail Message (QzmfRtvMailMsg) API . . . . . . . . . . . . . . . . . . 168

Chapter 12. Changing a Mail Message . . . . . . . . . . . . . . . . . . . . . . 172Change Mail Message (QzmfChgMailMsg) API . . . . . . . . . . . . . . . . . . 172

Chapter 13. Other Message APIs . . . . . . . . . . . . . . . . . . . . . . . . . . 178How to Use These MSF APIs . . . . . . . . . . . . . . . . . . . . . . . . . . . . 178Reserve Mail Message Identifier (QzmfRsvMailMsgId) API . . . . . . . . . . 179

Contents vii

Page 10: AnyMail/400 Mail Server Framework Developer Guide January 1995

Remove Reserved Mail Message Identifier (QzmfRmvRsvMailMsgId) API . 182Complete Creation Sequence (QzmfCrtCmpMailMsg) API . . . . . . . . . . . 184Query Mail Message Identifier (QzmfQryMailMsgId) API . . . . . . . . . . . . 187

Chapter 14. Additional Exit Point Interfaces . . . . . . . . . . . . . . . . . . . 192Validate Data Field Exit Point . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192Track Mail Message Changes Exit Point . . . . . . . . . . . . . . . . . . . . . . 194

Chapter 15. Snap-In Call Exit Point Interface . . . . . . . . . . . . . . . . . . . 197Snap-In Call Exit Point . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 197

Chapter 16. Creating an MSF Program in ILE C/400 . . . . . . . . . . . . . . 199MSF Application Programs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199

Creating a Module and Program in ILE C/400 — Example . . . . . . . . . . 199Special Considerations for MSF Exit Point Programs . . . . . . . . . . . . 199

Specific ILE C/400 Features and MSF Application Programs . . . . . . . . . . 201Interactive Testing and Debugging of an MSF Application . . . . . . . . . . . 202Packaging an MSF Mail Application . . . . . . . . . . . . . . . . . . . . . . . . 203

Chapter 17. Security and Authority . . . . . . . . . . . . . . . . . . . . . . . . . 205AS/400 Program Authority . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205

Object Authority . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205MSF Program Authority . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 206

MSF Command Authority . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 206MSF API Authority . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 206MSF File Authority . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207

Mail Applications That Use MSF . . . . . . . . . . . . . . . . . . . . . . . . . . 207Installing Mail Applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207

Chapter 18. Error Handling in the Mail Server Framework . . . . . . . . . . . 208Where to Look for Error Information . . . . . . . . . . . . . . . . . . . . . . . . 208Error Messages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 209

Communicating Errors to MSF . . . . . . . . . . . . . . . . . . . . . . . . . . 209Errors Signalled by the Mail Server Framework . . . . . . . . . . . . . . . 211

MSF Journal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 213Description of the QZMF Journal . . . . . . . . . . . . . . . . . . . . . . . . 213Displaying the QZMF Journal . . . . . . . . . . . . . . . . . . . . . . . . . . . 214Journal Entry Type LG . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 219Journal Entry Type ER . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 221Journal Entry Type SY . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223Journal Entry Type CF . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 225

Common Problems Encountered When Using MSF . . . . . . . . . . . . . . . 227

Appendix A. Generic Envelope Type (GET) . . . . . . . . . . . . . . . . . . . . 228Contents of a Generic Envelope . . . . . . . . . . . . . . . . . . . . . . . . . . . 229

Generic Envelope Header . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 229Generic Attribute Definition . . . . . . . . . . . . . . . . . . . . . . . . . . . . 230General Considerations for GET Attributes . . . . . . . . . . . . . . . . . . 231Text Attributes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 231Date and Time Attributes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233Fixed Value Attributes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233Miscellaneous Attributes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 237GET Date/Time GMT Structure . . . . . . . . . . . . . . . . . . . . . . . . . . 239

OfficeVision/400 Use of the GET . . . . . . . . . . . . . . . . . . . . . . . . . . . 241Object Distribution Facility Use of the GET . . . . . . . . . . . . . . . . . . . . 242

viii AnyMail/400 MSF

Page 11: AnyMail/400 Mail Server Framework Developer Guide January 1995

Extensions to the GET . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 243

Appendix B. SNADS File Server APIs . . . . . . . . . . . . . . . . . . . . . . . 244File Server Operations — Overview . . . . . . . . . . . . . . . . . . . . . . . . 244

File Server Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 244File Servers Supported by FSO APIs . . . . . . . . . . . . . . . . . . . . . . 245Attachment References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 246Assign and Revoke APIs Example . . . . . . . . . . . . . . . . . . . . . . . . 246How Usage Counts Are Used . . . . . . . . . . . . . . . . . . . . . . . . . . . 246

Create SNADS File Server Object (QZDCRFSO) API . . . . . . . . . . . . . . 247Required Parameter Group . . . . . . . . . . . . . . . . . . . . . . . . . . . . 248Error Messages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 248

Write to SNADS File Server Object (QZDWTFSO) API . . . . . . . . . . . . . . 249Required Parameter Group . . . . . . . . . . . . . . . . . . . . . . . . . . . . 251Error Messages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 252

Read SNADS File Server Object (QZDRDFSO) API . . . . . . . . . . . . . . . 253Required Parameter Group . . . . . . . . . . . . . . . . . . . . . . . . . . . . 255Error Messages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 256

Assign SNADS File Server Object Access ID (QZDASNID) API . . . . . . . . 257Required Parameter Group . . . . . . . . . . . . . . . . . . . . . . . . . . . . 258Error Messages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 259

Revoke SNADS File Server Object Access ID (QZDRVKID) API . . . . . . . . 259Required Parameter Group . . . . . . . . . . . . . . . . . . . . . . . . . . . . 260Error Messages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 260

List SNADS File Server Object Access IDs (QZDLSTID) API . . . . . . . . . . 261Required Parameter Group . . . . . . . . . . . . . . . . . . . . . . . . . . . . 262Error Messages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 264

Retrieve SNADS File Server Object Access ID (QZDRTVID) API . . . . . . . 265Required Parameter Group . . . . . . . . . . . . . . . . . . . . . . . . . . . . 265Error Messages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 266

SNADS File Server APIs — Examples . . . . . . . . . . . . . . . . . . . . . . . 267

Appendix C. Using the AS/400 System Distribution Directory . . . . . . . . . 276Description of the System Distribution Directory . . . . . . . . . . . . . . . . . 276User-Defined Directory Fields . . . . . . . . . . . . . . . . . . . . . . . . . . . . 279Search System Directory API . . . . . . . . . . . . . . . . . . . . . . . . . . . . 280

A Program that Uses the Search System Directory API — Example . . . . 280Helpful Hints about the System Distribution Directory . . . . . . . . . . . . . . 290

Appendix D. QZMFSNPA Exit Point Program . . . . . . . . . . . . . . . . . . . 291Description of the QZMFSNPA Exit Point Program . . . . . . . . . . . . . . . . 291Use of the Preferred Address and Directory Search API . . . . . . . . . . . . 291

Use of User-Defined Addresses . . . . . . . . . . . . . . . . . . . . . . . . . 293

Appendix E. An MSF Application — Example . . . . . . . . . . . . . . . . . . . 294Header File Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 295

Header File Example — TESTTYPE . . . . . . . . . . . . . . . . . . . . . . . 295Header File Example — TESTMSG . . . . . . . . . . . . . . . . . . . . . . . . 296

Type Configuration Program — Example . . . . . . . . . . . . . . . . . . . . . . 297Results from the TCFGTYPE Program . . . . . . . . . . . . . . . . . . . . . . 307

Module and Program to Create MSF Messages — Example . . . . . . . . . . 308TCRTMSG Program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 320

List Expansion Exit Point Program — Example . . . . . . . . . . . . . . . . . . 322Address Resolution Exit Point Program — Example . . . . . . . . . . . . . . . 331Retrieval Exit Point Program — Example . . . . . . . . . . . . . . . . . . . . . 335

Contents ix

Page 12: AnyMail/400 Mail Server Framework Developer Guide January 1995

Program to Reserve and Query Message — Example . . . . . . . . . . . . . . 350Removal of Test Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 355

Appendix F. Qzmf Header File . . . . . . . . . . . . . . . . . . . . . . . . . . . 356

Appendix G. Qzmfasrv Header File . . . . . . . . . . . . . . . . . . . . . . . . 375

Glossary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 382

Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 391

x AnyMail/400 MSF

Page 13: AnyMail/400 Mail Server Framework Developer Guide January 1995

Figures

1. MSF Processing a Message . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 2. Expanding the Mail Server Framework Mail Engine . . . . . . . . . . . . 3 3. MSF Message flow . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 4. Addressing Group Exit Points and Exit Point Programs . . . . . . . . . . 6 5. Pre-Delivery Group Exit Points and Exit Point Programs . . . . . . . . . . 8 6. Delivery Group Exit Points and Exit Point Programs . . . . . . . . . . . . 10 7. Management Group Exit Points and Exit Point Programs . . . . . . . . . 12 8. Messages Across a Network . . . . . . . . . . . . . . . . . . . . . . . . . . 14 9. Exit Point Program Registration . . . . . . . . . . . . . . . . . . . . . . . . 1610. The MSF Configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1811. Work with Registration Information Display . . . . . . . . . . . . . . . . . 2312. Work with Exit Programs Display . . . . . . . . . . . . . . . . . . . . . . . . 2413. Add Exit Program Display . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2414. Add Exit Program Display (After Pressing F10) . . . . . . . . . . . . . . . 2515. Add Exit Program Display (After Paging Down) . . . . . . . . . . . . . . . 2616. Work with Exit Programs Display . . . . . . . . . . . . . . . . . . . . . . . . 2617. Copying the MSF Configuration . . . . . . . . . . . . . . . . . . . . . . . . 3018. Existing MSF Messages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3219. MSF Messages Being Placed on the MSF Queue During STRMSF . . . . 3320. MSF Messages Being Cleared . . . . . . . . . . . . . . . . . . . . . . . . . 3421. MSF Message Being Resumed at Termination Point . . . . . . . . . . . . 3522. MSF Message Being Reset . . . . . . . . . . . . . . . . . . . . . . . . . . . 3623. STRMSF Submitting QMSF Jobs . . . . . . . . . . . . . . . . . . . . . . . . 3724. MSF Ending Immediate and Controlled . . . . . . . . . . . . . . . . . . . . 3925. MSF Jobs Getting MSF Messages From the Queue . . . . . . . . . . . . 4126. An MSF Message is a Collection of Lists . . . . . . . . . . . . . . . . . . . 4527. How An MSF Message Is Created Using QzmfCrtMailMsg API . . . . . . 4728. Common Header Format For All Lists . . . . . . . . . . . . . . . . . . . . . 5029. Common List Entry Format. . . . . . . . . . . . . . . . . . . . . . . . . . . . 5230. MSF Message Originator List . . . . . . . . . . . . . . . . . . . . . . . . . . 5331. MSF Message Envelope List . . . . . . . . . . . . . . . . . . . . . . . . . . 5632. MSF Message Recipient List . . . . . . . . . . . . . . . . . . . . . . . . . . 5933. MSF Message Attachment Reference List . . . . . . . . . . . . . . . . . . 6234. MSF Message′s Original Recipient List . . . . . . . . . . . . . . . . . . . . 6435. MSF Message Reply-To List . . . . . . . . . . . . . . . . . . . . . . . . . . 6736. An MSF Message Report-to List . . . . . . . . . . . . . . . . . . . . . . . . 6937. An MSF Message Report-on List . . . . . . . . . . . . . . . . . . . . . . . . 7138. MSF Message Exit Program History List . . . . . . . . . . . . . . . . . . . 7439. An MSF Message Recipient History List . . . . . . . . . . . . . . . . . . . 7640. MSF Exit Points and Exit Point Programs . . . . . . . . . . . . . . . . . . . 8141. MSF Exit Point Programs Do Two Things . . . . . . . . . . . . . . . . . . . 8642. Multiple Exit Point Programs per Exit Point . . . . . . . . . . . . . . . . . 8743. MSF Data Types Used in Exit Point Configuration . . . . . . . . . . . . . . 8744. Recipient List Data Types Matched to Exit Program Data . . . . . . . . . 8845. Two Exit Point Programs at Same MSF Exit Point . . . . . . . . . . . . . . 9046. MSF Calls Exit Point Program PROGRAM1 First . . . . . . . . . . . . . . 9147. MSF Calls Exit Point Program PROGRAM2 Next . . . . . . . . . . . . . . 9248. Two Exit Point Programs at Same MSF Exit Point . . . . . . . . . . . . . . 9349. Only PROGRAM1 Is Called by MSF . . . . . . . . . . . . . . . . . . . . . . 9450. MSF Exit Point Programs can ″Put Back″ Recipients . . . . . . . . . . . . 9651. Next MSF Exit Point Program Called After a ″Put Back″ . . . . . . . . . . 97

Copyright IBM Corp. 1995 xi

Page 14: AnyMail/400 Mail Server Framework Developer Guide January 1995

52. Using Different Data Types when Evaluating Exit Points . . . . . . . . . . 9953. Addressing Group Exit Points Are Skipped by MSF . . . . . . . . . . . . 10054. MSF Selects and Calls PROGRAM2 . . . . . . . . . . . . . . . . . . . . . 10255. PROGRAM2 Changes Message Recipient List and Returns . . . . . . . 10356. MSF Reevaluates and Calls PROGRAM1 . . . . . . . . . . . . . . . . . . 10457. MSF Selects and Calls Address Resolution Exit Point Program . . . . 10558. Program Changes Message Recipient List and Returns . . . . . . . . . 10659. MSF Reevaluates List Expansion and Calls a Program . . . . . . . . . 10760. MSF Reevaluates Address Resolution . . . . . . . . . . . . . . . . . . . 10961. Using the Status Field when Evaluating Exit Points . . . . . . . . . . . . 11162. An Exit Point Program Changes an MSF Message . . . . . . . . . . . . 11563. MSF Makes the Changes when the Program Returns . . . . . . . . . . 11664. Exit Point Programs Shipped in V3R1. . . . . . . . . . . . . . . . . . . . . 12265. Track Changes Exit Point . . . . . . . . . . . . . . . . . . . . . . . . . . . 12466. Validate Data Field Exit Point . . . . . . . . . . . . . . . . . . . . . . . . . 12667. QzmfCrtMailMsg and Validate Data Field Exit Example . . . . . . . . . 12768. QzmfCrtMailMsg Calls Validate Data Field Exit Programs . . . . . . . . 12869. QzmfChgMailMsg and Validate Data Field Exit Example . . . . . . . . . 13070. QzmfChgMailMsg Calls Validate Data Field Exit Programs . . . . . . . 13171. MSF Configuration APIs Accessing MSF Configuration . . . . . . . . . 13472. Programs Using MSF Message APIs to Manage an MSF Message . . 13573. Message Descriptor Array and Message List . . . . . . . . . . . . . . . 14774. Display Journal (First Display) . . . . . . . . . . . . . . . . . . . . . . . . 21575. Display Journal (Second Display) . . . . . . . . . . . . . . . . . . . . . . 21576. Display Journal (Third Display) . . . . . . . . . . . . . . . . . . . . . . . . 21677. Display Journal Entries Display . . . . . . . . . . . . . . . . . . . . . . . 21778. Detail Display of a Journal Entry — Example . . . . . . . . . . . . . . . . 21879. Display Journal Entry (Type LG) . . . . . . . . . . . . . . . . . . . . . . . 21980. Display Journal Entry (Type ER) . . . . . . . . . . . . . . . . . . . . . . . 22181. Display Journal Entry (Type SY) . . . . . . . . . . . . . . . . . . . . . . . 22382. Display Journal Entry (Type CF) . . . . . . . . . . . . . . . . . . . . . . . 22583. Display Directory Entry (First Display) . . . . . . . . . . . . . . . . . . . . 27784. Display Directory Entry (Second Display) . . . . . . . . . . . . . . . . . . 27785. Display Directory Entry (Third Display) . . . . . . . . . . . . . . . . . . . 27886. Display Directory Entry (Fourth Display) . . . . . . . . . . . . . . . . . . 27887. MSF Exit Point Program Searching the Directory . . . . . . . . . . . . . 27988. QZMFSNPA Exit Point Program Switching Addresses . . . . . . . . . . 292

xii AnyMail/400 MSF

Page 15: AnyMail/400 Mail Server Framework Developer Guide January 1995

Tables

1. MSF Type Groups and Character Identifiers . . . . . . . . . . . . . . . . . 18 2. IBM-Supplied Address Types . . . . . . . . . . . . . . . . . . . . . . . . . . 20 3. IBM-Supplied Message Types . . . . . . . . . . . . . . . . . . . . . . . . . 20 4. IBM-Supplied Envelope Types . . . . . . . . . . . . . . . . . . . . . . . . . 20 5. IBM-Supplied Attachment Reference Types . . . . . . . . . . . . . . . . . 21 6. IBM-Supplied Exit Points for the MSF . . . . . . . . . . . . . . . . . . . . . 22 7. IBM-Supplied Exit Point Programs for the MSF . . . . . . . . . . . . . . . 22 8. Exit Point Program Data Format Names . . . . . . . . . . . . . . . . . . . 27 9. Common List Header . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5010. Selection Criteria and Parameters Passed for Addressing Exit Points 11811. Selection Criteria and Parameters Passed for Pre-Delivery Exit Points 11912. Selection Criteria and Parameters Passed for Delivery Exit Points . . 11913. Selection Criteria and Parameters Passed for Management Exit Points 12014. Changes Allowed by Exit Point . . . . . . . . . . . . . . . . . . . . . . . . 12115. MSF Configuration API Descriptions . . . . . . . . . . . . . . . . . . . . . 13316. MSF Message API Descriptions . . . . . . . . . . . . . . . . . . . . . . . 13317. ADDC0100 Format . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13718. DLTC0100 Format . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14019. LSTL0100 Format . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14320. LSTC0100 Format . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14321. MSF API Programs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20622. Type LG Journal Entries for MSF Messages . . . . . . . . . . . . . . . . 22023. Type ER Journal Entries for MSF Message Errors . . . . . . . . . . . . 22224. Type SY Journal Entries for the MSF System Level Events Table

Changes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22425. Type CF Journal Entries for MSF Configuration Changes . . . . . . . . 22626. IBM Defined Attributes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22927. File Server Name Structure . . . . . . . . . . . . . . . . . . . . . . . . . . 24828. User Space Name Structure . . . . . . . . . . . . . . . . . . . . . . . . . 26229. Input Parameter Section . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26330. Header Section . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26331. ACID0100 Format . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26332. Example MSF Exit Point Programs . . . . . . . . . . . . . . . . . . . . . . 349

Copyright IBM Corp. 1995 xiii

Page 16: AnyMail/400 Mail Server Framework Developer Guide January 1995

Special Notices

This publication is intended to help AS/400 software developers to work with theAnyMail/400 Mail Server Framework. The information in this publication is notintended as the specification of any programming interfaces that are provided byOS/400. See the PUBLICATIONS section of the IBM Programming Announcementfor OS/400 for more information about what publications are considered to beproduct documentation.

References in this publication to IBM products, programs or services do notimply that IBM intends to make these available in all countries in which IBMoperates. Any reference to an IBM product, program, or service is not intendedto state or imply that only IBM′s product, program, or service may be used. Anyfunctionally equivalent program that does not infringe any of IBM′s intellectualproperty rights may be used instead of the IBM product, program or service.

Information in this book was developed in conjunction with use of the equipmentspecified, and is limited in application to those specific hardware and softwareproducts and levels.

IBM may have patents or pending patent applications covering subject matter inthis document. The furnishing of this document does not give you any license tothese patents. You can send license inquiries, in writing, to the IBM Director ofLicensing, IBM Corporation, 500 Columbus Avenue, Thornwood, NY 10594 USA.

The information contained in this document has not been submitted to anyformal IBM test and is distributed AS IS. The information about non-IBM(VENDOR) products in this manual has been supplied by the vendor and IBMassumes no responsibility for its accuracy or completeness. The use of thisinformation or the implementation of any of these techniques is a customerresponsibility and depends on the customer′s ability to evaluate and integratethem into the customer′s operational environment. While each item may havebeen reviewed by IBM for accuracy in a specific situation, there is no guaranteethat the same or similar results will be obtained elsewhere. Customersattempting to adapt these techniques to their own environments do so at theirown risk.

The following document contains examples of data and reports used in dailybusiness operations. To illustrate them as completely as possible, the examplescontain the names of individuals, companies, brands, and products. All of thesenames are fictitious and any similarity to the names and addresses used by anactual business enterprise is entirely coincidental.

The following terms, which are denoted by an asterisk (*) in this publication, aretrademarks of the International Business Machines Corporation in the UnitedStates and/or other countries:

The following terms, which are denoted by a double asterisk (**) in thispublication, are trademarks of other companies:

Application System/400 AS/400C/400 IBMILE OfficeVisionOfficeVision/400 OS/400Ult imedia 400

xiv Copyright IBM Corp. 1995

Page 17: AnyMail/400 Mail Server Framework Developer Guide January 1995

Other trademarks are trademarks of their respective companies.

cc:Mail Lotus Development Corporation.

Special Notices xv

Page 18: AnyMail/400 Mail Server Framework Developer Guide January 1995

Preface

This document is intended to provide a detailed description of the AnyMail/400Mail Server Framework. It contains detailed technical information about theAnyMail/400 Mail Server Framework (MSF), its APIs, its commands, and its datastructures.

This document is intended for OS/400 programmers or product designers thatwant detailed information that is necessary to write or design programs that useAnyMail/400 APIs to provide functions related to the distribution of electronicmail or messaging on OS/400*.

How This Document is OrganizedThe document is organized as follows:

• Chapter 1, “Introduction to AnyMail/400 Mail Server Framework”

This chapter provides an introduction to AnyMail/400 Mail Server Framework.

• Chapter 2, “Mail Server Framework Concepts”

This chapter describes the MSF capabilities.

• Chapter 3, “Mail Server Framework Configuration”

This chapter describes the MSF configuration.

• Chapter 4, “Mail Server Framework Operation”

This chapter provides a functional description of MSF. This includes how touse the MSF commands and a description of the MSF job structure.

• Chapter 5, “Mail Server Framework Message”

This chapter provides a detailed description of the MSF message. It definesall the component parts that make up an MSF message and gives examplesof these parts.

• Chapter 6, “Mail Server Framework Exit Points”

This chapter provides information about how MSF uses the OS/400 exit pointsupport. It defines the MSF snap-in concept and gives examples.

• Chapter 7, “Summary of the Mail Server Framework APIs”

This chapter lists the MSF APIs.

• Chapter 8, “Mail Server Framework Configuration APIs”

This chapter describes the MSF Configuration APIs.

• Chapter 9, “Working with Mail Message Lists”

This chapter describes how to define and construct a list for an MSFmessage.

• Chapter 10, “Creating a Mail Message”

This chapter describes how to use the Create Mail Message(QzmfCrtMailMsg) API to create MSF messages.

• Chapter 11, “Retrieving Mail Message Information”

xvi Copyright IBM Corp. 1995

Page 19: AnyMail/400 Mail Server Framework Developer Guide January 1995

This chapter describes how to use the Retrieve Mail Message(QzmfRtvMailMsg) API to retrieve MSF message information.

• Chapter 12, “Changing a Mail Message”

This chapter describes how to use the Change Mail Message(QzmfChgMailMsg) API to change an MSF message.

• Chapter 13, “Other Message APIs”

This chapter describes the Reserve Mail Message Identifier(QzmfRsvMailMsgId) API, the Remove Reserved Mail Message Identifier(QzmfRmvRsvMailMsgId) API, the Query Mail Message Identifier(QzmfQryMailMsgId) API, and the Complete Creation Sequence(QzmfCrtCmpMailMsg) API.

• Chapter 14, “Additional Exit Point Interfaces”

This chapter describes the Validate Data Field exit point and the Track MailChanges exit point.

• Chapter 15, “Snap-In Call Exit Point Interface”

This chapter describes the data passed to programs configured for theSnap-In Call exit point.

• Chapter 16, “Creating an MSF Program in ILE C/400”

This chapter describes how an application can be created using MSF.

• Chapter 17, “Security and Authority”

This chapter provides information on security and authority aspects ofOS/400 in general and MSF in particular.

• Chapter 18, “Error Handling in the Mail Server Framework”

This chapter provides assistance in handling errors.

• Appendix A, “Generic Envelope Type (GET)”

This appendix describes the generic envelope defined by MSF.

• Appendix B, “SNADS File Server APIs”

This appendix describes the SNADS file server APIs and how to use them.

• Appendix C, “Using the AS/400 System Distribution Directory”

This appendix describes how the AS/400 system distribution directory can beused by MSF programs.

• Appendix D, “QZMFSNPA Exit Point Program”

This appendix describes the IBM-supplied QZMFSNPA program.

• Appendix E, “An MSF Application — Example”

This appendix gives example programs that use MSF. These programs canbe used as a starting point for MSF application developers.

• Appendix F, “Qzmf Header File”

This appendix describes the MSF header file qzmf.h.

• Appendix G, “Qzmfasrv Header File”

This appendix describes the MSF header file qzmfasrv.h.

Preface xvii

Page 20: AnyMail/400 Mail Server Framework Developer Guide January 1995

Diskette

There is a diskette that comes with this document. You will find it inside theback cover. The instructions to download the files in it can be found at thevery beginning of Appendix E, “An MSF Application — Example” onpage 294.

Related PublicationsThe publications listed in this section are considered particularly suitable for amore detailed discussion of the topics covered in this document.

• AnyMail/400 Mail Server Framework Support, SC41-3411

• CL Reference, SC41-3722

• Integrated Language Environment Concepts, SC41-3606

• ILE C/400 Reference Summary, SX09-1288

• ILE C/400 Programmer’s Guide, SC09-1820

• ILE C/400 Programmer’s Reference, SC09-1821

• Security - Basic, SC41-3301

• Security - Reference, SC41-3302

• SNA Distribution Services, SC41-3410

• System API Programming, SC41-3800

• System API Reference, SC41-3801

• Work Management, SC41-3306

International Technical Support Organization PublicationsA complete list of International Technical Support Organization publications, witha brief description of each, may be found in:

Bibliography of International Technical Support Organization TechnicalBulletins, GG24-3070.

To get listings of ITSO technical publications (known as “redbooks”) online,VNET users may type:

TOOLS SENDTO WTSCPOK TOOLS REDBOOKS GET REDBOOKS CATALOG

How to Order ITSO Technical Publications

IBM employees in the USA may order ITSO books and CD-ROMs usingPUBORDER. Customers in the USA may order by calling 1-800-879-2755 or byfaxing 1-800-284-4721. Visa and Master Cards are accepted. Outside theUSA, customers should contact their local IBM office.

Customers may order hardcopy ITSO books individually or in customizedsets, called GBOFs, which relate to specific functions of interest. IBMemployees and customers may also order ITSO books in online format onCD-ROM collections, which contain books on a variety of products.

xviii AnyMail/400 MSF

Page 21: AnyMail/400 Mail Server Framework Developer Guide January 1995

Below is a list of ITSO publications that are currently available which relate tothe AS/400.

AS/400 redbooks are also available on CD-ROM, by adding feature code #8053 toyour OS/400 software profile.

• System/36 to AS/400 System Migration, GG24-3249-01• System/36 to AS/400 Application Migration, GG24-3250-01• AS/400: System/38 Application Migration to AS/400, GG24-3251-00• AS/400 Communication Migration, GG24-3253--00• AS/400 Office in a DIA/SNADS Network, GG24-3268-00• Converting S/36 Environment Application to Native, GG24-3304-01• AS/400 Communications Problem Determination, GG24-3305-00• SQL/400: A Guide for Implementation OS/400 V2R2, GG24-3321-03• AS/400 - S/370 Connectivity, GG24-3336-00• AS/400, S/38 and PS/2 as T2.1 Nodes in a Subarea Network, GG24-3420-00• Writing SAA Applications for AS/400, GG24-3438-00• IBM AS/400 TCP/IP Operation and Configuration, GG24-3442-02• IBM AS/400 in Large Networks: A Case Study, GG24-3447-00• AS/400 Communications Definitions Examples, GG24-3449-00• AS/400 Object Distribution Facility and SNA RSCS PROFS, GG24-3479-00• IBM AS/400 ISDN Connectivity, GG24-3517-00• OfficeVision/400 and AS/400 Query Applications in a Multilingual

Environment, GG24-3579--00• Managing Multiple AS/400s in a Peer Network, GG24-3614-02• OfficeVision/400 in a DIA/SNADS Network, GG24-3625-00• AS/400 Audit and Security Enhancements in OS/400, GG24-3639-00• WAF/400 5363 Optical Subsystem Configuration and Installation,

GG24-3680-00• OfficeVision/400 Printing, GG24-3697-00• AS/400 Printing II, GG24-3704-00• AS/400 APPN with PS/2 APPN, 3174 APPN, 5394 and Subareas, GG24-3717-00• AS/400 CPI Communications Selected Topics, GG24-3722-00• AS/400 Performance Management V2R2, GG24-3723-01• Multimedia Examples with the AS/400 Using AVC, GG24-3743-00• Getting Started with AS/400 OSI, GG24-3758-00• AS/400 Communication Definition Examples Volume 2, GG24-3763-00• Installation Considerations for National Language, GG24-3790-00• Artificial Intelligence and AS/400: Neural Networks and Knowledge Based

Systems, GG24-3793-00• Facsimile Support/400 Implementation, GG24-3797-00• Application Development on the AS/400, GG24-3806-00• PC Support/400 Asynchronous and SDLC Configuration Examples,

GG24-3808-00• 5494 & OS/2 ES: Connecting Remote User Groups, GG24-3828-00• AS/400 Automation Using NetView and SNA MS Transport, GG24-3841-00• DOS PCS/400 in OS/2 V2 Virtual DOS Machine, GG24-3856-00• WAF/400 Administration and User Examples, GG24-3866-00• OfficeVision/400 Application Enabler, GG24-3868-00• Cooperative Processing and GUI in an AS/400 Environment, GG24-3877-00• OfficeVision/400 Application Programming Interfaces V2R2, GG24-3885-00• OfficeVision/400 Integration with CallPath/400 and Fax Support, GG24-3896-00• AS/400 Performance Capacity Planning V2R2, GG24-3908-00• AS/400 System Availability and Recovery for V2R2, GG24-3912-00• AS/400 Network Routing Facility, GG24-3918-00• AD/CYCLE Code/400, ADM/400 and ADS/400, GG24-3928-00

Preface xix

Page 22: AnyMail/400 Mail Server Framework Developer Guide January 1995

• OfficeVision/400 V2 Technical Tips and Techniques, GG24-3937-00• CICS/400 Migration from Mainframe CICS, GG24-4006-00• Using DOS PC Support/400 with Novell NetWare 3.11 and NetWare for SAA

1.3, GG24-4013-00• Ultimedia Video Delivery System/400, GG24-4020-00• AS/400 Client Series - Products and Positioning, GG24-4027-01• IBM AS/400 Printing III, GG24-4028-00• Performance Benchmarking for the AS/400, GG24-4030-00• AS/400 and RISC System/6000 Connectivity, GG24-4039-00• Using V2R3 DOS and OS/2 PC Support/400 under OS/2 2.1, GG24-4070-01• Apple Macintosh and the AS/400, GG24-4071-00• OfficeVision/400 Application Enabler Version 2 Release 3, GG24-4072-00• The IBM AS/400 as a TCP/IP Network File Server, GG24-4092-00• ENVY/400 Hints and Tips, GG24-4094-00• Introduction to ENVY/400, GG24-4126-00• Managing Operations on AS/400s with IBM SAA SystemView OMEGAMON

Services/400, GG24-4136-00• AS/400 Integrated Language Environment, GG24-4148-00• CICS/400 V2R3 Task Book, GG24-4182-00• AS/400 V2R3 Software Life Cycle Mgmt with ADM/400, GG24-4187-00• An Implementation Guide for AS/400 Security and Auditing including C2,

Cryptography, Communications and PC Connectivity, GG24-4200-00• IBM AS/400 APPN Problem Management, GG24-4222-00• DB2/400 Advanced Database Functions, GG24-4249-00• V2R3 PC Support/400 and Microsoft Windows 3.1 Advanced Topics,

GG24-4253-00• OfficeVision/400: Printer Setup in an OfficeVision Environment, GG24-4283-00• AS/400 Client Series Handbook, GG24-4285-00• Backup Recovery and Media Services/400 Implementation Tips and

Techniques, GG24-4300-00• IBM Current-OV/400 Workgroup Program V1 R1 Modification 0 Refresh 1,

GG24-4377-00• LAN Server/400 A Guide to Using AS/400 as a File Server, GG24-4378-00• Client Access/400 Planning Guide, GG24-4422-00• Implementing Hierarchical Storage on the AS/400, GG24-4450-00

xx AnyMail/400 MSF

Page 23: AnyMail/400 Mail Server Framework Developer Guide January 1995

AcknowledgmentsThe authors of this document are:

Debasish BanerjeeAS/400 Communications Development,IBM Rochester

Corey CarlsonAS/400 Communications Development,IBM Rochester

Frank GilchristAS/400 Communications Development,IBM Rochester

Terry ForrestKeane, Inc.,Rochester, MN

John RipstraAS/400 Communications Development,IBM Rochester

George RomanoAS/400 Communications Development,IBM Rochester

Laurie WylandAS/400 Communications Development,IBM Rochester

Thanks to the following people for the assistance provided in the production ofthis document:

Greg WattsAS/400 Communications Development,IBM Rochester

The advisor for this project was:

Jorgelina EliggiInternational Technical Support Organization, Rochester Center

Preface xxi

Page 24: AnyMail/400 Mail Server Framework Developer Guide January 1995

xxii AnyMail/400 MSF

Page 25: AnyMail/400 Mail Server Framework Developer Guide January 1995

Chapter 1. Introduction to AnyMail/400 Mail Server Framework

AnyMail/400 is a family of functions that support mail applications on theAS/400*. The AnyMail/400 mail server framework (MSF) is a part of theAnyMail/400 family that is provided with the OS/400* licensed program. Theprimary function of MSF is to allow the processing of electronic messages.Electronic messages may contain text, voice, video, etc.

Mail applications are groups of programs and functions that create and deliverelectronic messages. Examples of mail applications include the mail function ofIBM WorkGroup and OfficeVision/400*. The mail server framework is not a mailapplication, but rather an open structure that allows mail applications to bedeveloped and run on OS/400. MSF supports mail applications by providing ameans to create and distribute electronic messages. In processing electronicmessages, MSF provides the services of a mail engine (or multiple mailengines). MSF can take an electronic message and give it to the appropriatemail applications. As shown in Figure 1, these mail applications perform thetask of actually sending the message to its recipients.

Figure 1. MSF Processing a Message

In processing electronic messages, MSF follows a set sequence of steps. Youcan construct programs to manipulate the electronic message (via MSFapplication programming interfaces) in each of these processing steps. For

Copyright IBM Corp. 1995 1

Page 26: AnyMail/400 Mail Server Framework Developer Guide January 1995

more information on the sequence of steps followed by MSF, see Chapter 2,“Mail Server Framework Concepts” on page 3.

A program uses an MSF interface to create an MSF message. This message isthen put on a queue, where it waits to be processed by the distribution portion ofMSF. MSF takes the message from the queue and processes it by giving themessage ′s information to various exit programs. Once all the exit programshave processed the message, MSF assumes all processing for that message hasbeen completed.

Each of these topics are detailed in the following chapters.

Benefits of the Mail Server FrameworkBy making use of the mail server framework′s open structure, MSF can be usedto provide solutions to a wide range of opportunities. For example, it is possibleto use MSF to create an application that takes an incoming message, convertsthe recipient′s E-mail address to a facsimile address (a telephone number) andautomatically faxes the message to the recipient′s fax machine. Anotherexample is SNA distribution services (SNADS). SNADS is implemented inOS/400 using MSF. SNADS creates MSF messages and provides programsintegrated into MSF that processes those messages.

Since SNADS is implemented to take advantage of MSF′s open structure, otherprograms using MSF also have access to SNADS messages. You can provideadditional programs to access these messages and augment the existing SNADSfunctions.

The mail server framework controls the flow of processing electronic messages.MSF always processes messages in a specific sequence (list expansionprocessing, then address resolution processing, etc.). You need to be concernedonly about what should be done for each step in the sequence. MSF is alsoflexible enough to allow you to determine which of the steps should be skippedentirely (only a subset of the steps may need to be performed).

Multiple applications can be active in MSF simultaneously. For example,assume three mail applications exist on the system. One application mayprocess SNADS messages, one may process X.400 messages, and one mayprocess SMTP messages. All three mail applications can process messages atthe same time. MSF distinguishes which mail application should process aspecific message by using the MSF configuration and the message′s attributes.

You can tailor the amount of resources that are given to the mail environment ona particular system. Because processing performed by MSF is done in AS/400batch jobs, varying the number of jobs that process MSF will affect performance.By increasing the number of OS/400 jobs processing MSF, you put a greateremphasis on the electronic mail for that system.

2 AnyMail/400 MSF

Page 27: AnyMail/400 Mail Server Framework Developer Guide January 1995

Chapter 2. Mail Server Framework Concepts

Chapter 1, “Introduction to AnyMail/400 Mail Server Framework” on page 1introduced the concept that AnyMail is a framework within which electronic mailcan be handled. A message (or mail item) is created by an application via theCreate Mail Message API. The MSF message is then processed by MSF with theintention to deliver it to a local recipient or forward it to a remote recipient. Thischapter introduces the concepts of how the processing of an MSF message takesplace.

MSF Exit Points

Figure 2. Expanding the Mail Server Framework Mail Engine

Taking a more detailed look at the mail engine that was introduced in Chapter 1,“Introduction to AnyMail/400 Mail Server Framework” on page 1 by expandingon the internal workings of the mail server framework, you can see that thereare several exit points that are provided by MSF (see Figure 2).

An MSF exit point is a place within the mail server framework where a call ismade to programs that are configured to provide specific functions. Theseprograms are referred to as exit point programs. Each of these exit points areprovided to allow specific functions that typically occur during the processing ofan E-mail message. The exit points (and their respective exit point names) are:

Copyright IBM Corp. 1995 3

Page 28: AnyMail/400 Mail Server Framework Developer Guide January 1995

• Addressing Exit Points

− List Expansion (QIBM_QZMFMSF_LST_EXP)

− Address Resolution (QIBM_QZMFMSF_ADR_RSL)

See “Addressing Group Exit Points” on page 6 for further explanation ofthese exit points.

• Pre-delivery Processing Exit Points

− Envelope Processing (QIBM_QZMFMSF_ENV_PSS)

− Attachment Conversion (QIBM_QZMFMSF_ATT_CNV)

− Security and Authority (QIBM_QZMFMSF_SEC_AUT)

See “Pre-delivery Processing Group Exit Points” on page 8 for furtherexplanation of these exit points.

• Delivery Points

− Local Delivery (QIBM_QZMFMSF_LCL_DEL)

− Message Forwarding (QIBM_QZMFMSF_MSG_FWD)

See “Delivery Group Exit Points” on page 10 for further explanation of theseexit points.

• Management Exit Points

− Non-Delivery (QIBM_QZMFMSF_NON_DEL)

− Attachment Management (QIBM_QZMFMSF_ATT_MGT)

− Accounting (QIBM_QZMFMSF_ACT)

See “Management Group Exit Points” on page 11 for further explanation ofthese exit points.

As a message flows through the mail server framework, each exit point isprocessed in this order which forms a sequence of operations on the message.See Figure 3 on page 5. List expansion is processed first followed by addressresolution, followed by envelope processing, until processing of the messagecompletes after the last exit point. MSF ensures messages are processedaccording to the above sequence. However, MSF does not provide any functionthat is to be performed within each exit point. It provides an organization of theprocessing of E-mail messages by the exit point programs. The exit pointprograms provide the actual function.

4 AnyMail/400 MSF

Page 29: AnyMail/400 Mail Server Framework Developer Guide January 1995

Figure 3. MSF Message f low

Typing of MSF DataOne of the aspects of the mail server framework is to be able to have typedinformation within a message. Typing of data within a message is a way ofindicating the type of information it carries and the format it takes. It is thistyping of information that controls how a message is handled by MSF. Each datatype must be registered with MSF so that it can be considered valid informationto be carried within the framework. For additional information on how these datatypes are used by MSF, see “Determining the Exit Point Program to Call” onpage 16.

The data types that can be configured to the framework are the following:

Address typeThis data type is used to indicate the format of the electronic mail addressthat is being used to identify a user. This data type can be used in therecipient list, the originator list, the reply-to list, report on list, the report tolist and the original recipient list. The address type that is identified for eachrecipient in the recipient list is used to determine the program to call withinthe addressing group of the framework.

Message typeThis data type is used to indicate two different areas within MSF. First, whena message is created, the message type must be specified. This is anindicator of the mail application that originated the message. Second, the

Chapter 2. Mail Server Framework Concepts 5

Page 30: AnyMail/400 Mail Server Framework Developer Guide January 1995

message type indicates, for each recipient in the recipient list, the mailapplication to be used to process the message in the remaining groups (thatis, the groups after the addressing group).

Envelope typeThis data type is used to indicate the format of information within a particularenvelope within the envelope list.

Attachment reference typeThis data type is used to indicate the format of information within a particularattachment reference. Note that it is assumed that the attachment referenceinformation is an actual reference to a permanently stored object, like adocument, within which the actual attachment content is contained.

For information on how to define these data types to the framework, seeChapter 3, “Mail Server Framework Configuration” on page 18.

Addressing Group Exit PointsThe first set of exit points make up the addressing group. Two exit points makeup the addressing group: list expansion and address resolution. The mainpurpose of this set of exit points is to expand distribution lists and resolve theappropriate processing that needs to be done in the following exit points.

Figure 4. Addressing Group Exit Points and Exit Point Programs

6 AnyMail/400 MSF

Page 31: AnyMail/400 Mail Server Framework Developer Guide January 1995

List Expansion (QIBM_QZMFMSF_LST_EXP)The first exit point, list expansion, is intended to provide a place where aprogram can take an entry in the recipient list, determine if it is actually adistribution list, and replace it with the actual E-mail addresses of recipients thatare identified by the distribution list. This can be done using the change API. Forexample, if an entry in the list of recipients is DEPT44C DISTLIST, a listexpansion exit point program configured to handle this type of recipient entrywould look up the name of the list in a distribution list directory. If it isdetermined that it is a distribution list, the list expansion exit point programwould change the message by replacing DEPT44C DISTLIST with the E-mailaddresses of the members of the list; for example, JOE CHICAGO, JOHNCHICAGO, SUE CHICAGO and JANE NEWYORK. The recipient list DEPT44CDISTLIST has thus been expanded by the exit point program. The message willnow be delivered to JOE, JOHN, SUE and JANE rather than DEPT44C.

It is possible that distribution lists can contain other distribution lists. That is, ifDEPT44C DISTLIST contained another entry, such as DEPT44A DISTLIST that isitself a distribution list, then it also needs to be expanded. To accomplish this,when entries are added to the recipient list via list expansion, the MSF messagewill go back through the list expansion exit point again. This will occur as longas new entries are added to the recipient list. When no additional entries areadded to the recipient list (that is, all distribution lists have been expanded), thenprocessing continues with the address resolution exit point. The mail serverframework assumes that if an entry is added, it may be a distribution list thatmay need to be expanded.

For details on how an exit point program that is configured in the list expansionexit point goes about performing this type of function see Chapter 6, “MailServer Framework Exit Points” on page 80.

Address Resolution (QIBM_QZMFMSF_ADR_RSL)When list expansion has completed, processing continues with the addressresolution exit point. It is expected that exit point programs configured here willperform the following functions:

• Look up recipients in a directory.

• Determine the status of each recipient, whether local, remote orundeliverable.

• Determine the method of delivery to the E-mail address.

• Change the recipients to reflect the new status and method of delivery usingthe change API.

It is the responsibility of address resolution exit point programs to direct themessage to local delivery, remote delivery or non-delivery exit points for eachrecipient in the list. This is done using the change API to set the status of eachrecipient to local, remote or non-delivery and to set the message type for eachrecipient. This will direct the message to a particular exit point and exit pointprogram in either the local delivery, message forwarding or the non-delivery exitpoints.

If an exit point program in address resolution changes the message by adding anew entry to or replacing an entry in the recipient list, it is possible that theentry is a distribution list. Therefore, when a new entry is added to the recipientlist, processing starts back at the beginning of list expansion using the new

Chapter 2. Mail Server Framework Concepts 7

Page 32: AnyMail/400 Mail Server Framework Developer Guide January 1995

entries added to the recipient list. It is possible that this can occur within the listexpansion exit point as well as between the address resolution and listexpansion exit points. Only until processing is complete for the addressresolution exit point and no new recipients have been added will the mail serverframework continue to the envelope processing exit point.

Note: When processing has been completed for the address group of exitpoints, recipients must have been assigned a status and a message type.If any recipients have not been assigned a status and message type, themail server framework will assign the default status of non-deliverableand a message type of 9998. These recipients can then be processed byany non-delivery exit point programs that are configured to handle them.

For details on how an exit point program configured in the address resolutionexit point goes about performing this type of function, see Chapter 6, “MailServer Framework Exit Points” on page 80.

Pre-delivery Processing Group Exit PointsWhen the addressing group of the framework has completed, processingcontinues with the pre-delivery group. This set of exit points makes up theprocessing group that occurs prior to the actual delivery to local or remoterecipients. Three exit points make up the pre-delivery processing group;envelope processing, attachment conversion and security and authority. Thepurpose of these exit points is to provide any processing that is to occur beforethe MSF message is delivered or forwarded.

Figure 5. Pre-Delivery Group Exit Points and Exit Point Programs

8 AnyMail/400 MSF

Page 33: AnyMail/400 Mail Server Framework Developer Guide January 1995

Envelope Processing (QIBM_QZMFMSF_ENV_PSS)It is within this first exit point of envelope processing that applications canhandle information about an MSF message that is contained in something calledan envelope. The type of information about an MSF message might be thesubject, the creation date of the E-mail message, the priority of the E-mailmessage or if the item is personal. It is within this exit point that conversionfrom one format of an envelope to another can take place. For example, if aparticular message is to be delivered to an SMTP recipient and the envelope listdoes not contain an SMTP specific envelope, an exit program could create anSMTP specific envelope from one of the envelopes already in the list. The newenvelope could then be added to the envelope list using the change API.

Note: Because MSF can support any mail application that has provided exitpoint programs, a generic form of envelope information has beenestablished. For more information on the generic envelope, seeAppendix A, “Generic Envelope Type (GET)” on page 228. The intent ofthe generic envelope is to provide a mail application independentrepresentation of this type of information so that each mail applicationcan share information with other mail applications. It is expected thateach mail application that provides exit point programs has its ownrepresentation of their envelope. However, to encourage sharing and,possibly providing easier gateway support between mail applications,each mail application should support the creating and processing of thegeneric envelope.

For details on how an exit point program configured in the envelope processingexit point goes about performing this type of function, see Chapter 6, “MailServer Framework Exit Points” on page 80.

Attachment Conversion (QIBM_QZMFMSF_ATT_CNV)The attachment reference list contains a list of attachment references. Eachentry in the list is a reference to an object that contains the content of theattachment.

Within this exit point, it is expected that exit point programs determine if anyconversion of an attachment from one format to another needs to be done. Forexample, if the attachment is a referenced DIA (Document InterchangeArchitecture) FFT (Final Form Text) document and the recipient is using a PCtype document editor, a conversion to a flat ASCII PC file could be done. In thiscase, the document conversion takes place and, rather than a single DIA FFTdocument, the message contains an additional attachment, which is the ASCIIrepresentation of the same document. The original DIA FFT document would notbe deleted. It may be the case that the message is being delivered to both a PCuser and an OfficeVision/400 user. In one case, an ASCII representation isneeded. In the other case, a DIA FFT document is needed. Thus, the tworeferenced attachments for the DIA FFT and the ASCII documents both representthe same information but in different formats that are compatible with theirrespective mail applications.

For details on how an exit point program configured in the attachmentconversion exit point goes about performing this type of function see Chapter 6,“Mail Server Framework Exit Points” on page 80.

Chapter 2. Mail Server Framework Concepts 9

Page 34: AnyMail/400 Mail Server Framework Developer Guide January 1995

Security and Authority (QIBM_QZMFMSF_SEC_AUT)Just before the delivery group processing for an MSF message the security andauthority exit point processing occurs. It is within this exit point that an exit pointprogram could indicate when a message is not to be delivered or forwarded to aparticular recipient. For example, if a message is to be delivered to an externalsite, a check for confidential information could be made. If the message containscompany confidential information, the status for each recipient could be changedby that exit point program to non-delivery or security violation for some or all ofthe intended recipients of the message.

For details on how an exit point program configured in the security and authorityexit point goes about performing this type of function see Chapter 6, “MailServer Framework Exit Points” on page 80.

Delivery Group Exit PointsWhen the pre-delivery processing has been completed, the next group is usedfor the actual delivery or forwarding to the particular mail application. This setof exit points make up the delivery group where messages are actually deliveredto local or forwarded to remote recipients. Two exit points make up the deliverygroup; local delivery and message forwarding.

Figure 6. Delivery Group Exit Points and Exit Point Programs

10 AnyMail/400 MSF

Page 35: AnyMail/400 Mail Server Framework Developer Guide January 1995

Local Delivery (QIBM_QZMFMSF_LCL_DEL)The first exit point is for local delivery. If the status of a recipient was set tolocal by an address resolution exit point program, then a local delivery exit pointprogram is called to make the delivery to the local recipient.

To ensure that the processing of messages through the mail server framework isas efficient as possible, it is highly recommended that a local delivery exit pointprogram copies the message to its own storage and queues up the message tothe actual delivery program. The complete delivery would actually occur outsidethe processing within the framework. This should be done so that MSF jobs cancomplete this message and continue to process other messages.

For details on how an exit point program configured in the local delivery exitpoint goes about performing this type of function see Chapter 6, “Mail ServerFramework Exit Points” on page 80.

Message Forwarding (QIBM_QZMFMSF_MSG_FWD)The second exit point for delivery is for message forwarding. If the status of arecipient was set to remote by an address resolution exit point program, then aremote delivery exit point program is called to forward the message to theremote recipient.

To ensure that the processing of messages through the mail server framework isas efficient as possible, it is highly recommended that a message forwarding exitpoint program copies the message to its own storage and queues up themessage to the actual forwarding program. The complete forwarding wouldactually occur outside the processing within the framework. This should be doneso that MSF jobs can complete this message and continue to process othermessages. For example, if a message was to be sent to the next node in thenetwork, the actual line connection would not be made from within the messageforwarding exit point program. Rather, a mechanism for queuing the message forlater transport to the next node should be used so that actual line connection isdone asynchronously to the processing within the framework.

For details on how an exit point program configured in the message forwardingexit point goes about performing this type of function see Chapter 6, “MailServer Framework Exit Points” on page 80.

Management Group Exit PointsWhen the delivery group has been completed, processing continues with themanagement group. The last set of exit points make up the management groupwhere the processing of messages is about to end. Three exit points make upthe management group; non-delivery, attachment management and accounting.The purpose of these exit points is to provide cleanup activity with respect to theMSF message prior to the message being deleted.

Chapter 2. Mail Server Framework Concepts 11

Page 36: AnyMail/400 Mail Server Framework Developer Guide January 1995

Figure 7. Management Group Exit Points and Exit Point Programs

Non-Delivery (QIBM_QZMFMSF_NON_DEL)The first exit point within the delivery group is the non-delivery exit point. If aparticular recipient has a status of non-deliverable, the message is passed to theexit point programs configured for this exit point.

It is highly recommended that the processing done in this exit point is that whichis necessary to deal with non-deliverable mail. For example, the information inthe message could be sent back to the originator, or a new MSF message couldbe sent back to the originator that reports back that the piece of E-mail was notdelivered to one or more of the recipients. Another possibility might be to routethe message to a special ″dead letter box″ or forwarded to a default recipient sothat it can be dealt with. Each mail application decides the appropriate actionwith respect to non-deliverable mail.

For details on how an exit point program configured in the non-delivery exit pointgoes about performing this type of function see Chapter 6, “Mail ServerFramework Exit Points” on page 80.

Attachment Management (QIBM_QZMFMSF_ATT_MGT)The next exit point of the management group is attachment management.Because attachments within a message are normally references to somestorage area (for example, a database file), it is within this exit point that anymanagement of the attachment can be done. For example, when the messagewas created, an attachment may have been temporarily copied into a databasefile. A reference was placed into the mail server framework message and thendelivered to a list of recipients. The database file could then be deleted because

12 AnyMail/400 MSF

Page 37: AnyMail/400 Mail Server Framework Developer Guide January 1995

it was a temporary holding place while the message was being processed withinthe framework.

For details on how an exit point program configured in the attachmentmanagement exit point goes about performing this type of function seeChapter 6, “Mail Server Framework Exit Points” on page 80.

Accounting (QIBM_QZMFMSF_ACT)The last exit point in the management group and the last exit point in the mailserver framework is the accounting exit point. This is the last exit point that cando any processing with respect to the mail server framework message since themessage will be deleted when the exit point has completed processing.

It is expected that any accounting that is to be done by a mail application wouldbe done within this exit point. For example, if a particular mail application has acharge-back capability to the originator of all messages, then within this exitpoint an exit point program could log the charge in a database file.

For detail on how an exit point program configured in the accounting exit pointgoes about performing this type of function see Chapter 6, “Mail ServerFramework Exit Points” on page 80.

Creating MSF MessagesWhen MSF has been configured, it is then possible to create messages using thecreate mail message API. The MSF message represents the work that is to beprocessed by the framework. The MSF message is made up of a variety of listsof typed information. The lists that can be created for a message may includethe following:

• Recipient list (required). This is a list of recipients that are to receive themessage.

• Envelope list (required). This is a list of envelopes within which informationlike the subject, reference, creation date, creation time and priority is stored.

• Originator list (required). This is the address(es) of the person that originatedthe message.

• Attachment reference list (optional). This is a list of references to associatedattachments that accompany a message.

• Reply-to list (optional). This is a list of those that are to receive a reply whenone is created.

• Original recipient list (optional). This is a complete list of all the recipients ofa message. It specifies whether a reply is expected from the recipient andwhether they are considered as a primary recipient (TO:), carbon copyrecipient (CC:) or a blind carbon copy recipient (BCC:).

• Report-on list (optional). This is a list of recipients that are being reported oneither because a message could not be delivered to a recipient or if anapplication is reporting on the delivery of a message. An example of thiswould be when reporting COD (confirmation of delivery).

• Report-to list (optional). This is a list of addresses that a status is to be sentto if a message cannot be delivered to one or more recipients.

Chapter 2. Mail Server Framework Concepts 13

Page 38: AnyMail/400 Mail Server Framework Developer Guide January 1995

For more detailed information about the contents of a message, see Chapter 5,“Mail Server Framework Message” on page 44.

Mail server framework messages are created by applications like electronic mailor workflow. OfficeVision/400 and Object Distribution Facility are two suchapplications for AS/400 that create mail server framework messages. Anyapplication, through the creation of messages and a series of exit pointprograms, can use the framework to provide an asynchronous transport of data.It is within the framework that a combination of applications can interchangedata and provide solutions to customers varying needs for electronic mail andthe various different E-mail applications.

Figure 8. Messages Across a Network

14 AnyMail/400 MSF

Page 39: AnyMail/400 Mail Server Framework Developer Guide January 1995

Creating messages occurs whenever the framework and its exit point programsare used to process the information in an E-mail message. You can create amessage when the message is being sent from the originator′s server system.This allows the framework′s exit point programs to determine how the MSFmessage information should be changed, converted, delivered, or forwarded,and what accounting might have to be done for that message.

The message forwarding exit point program′s function is to figure out how to getthe E-mail information to another system in the network. If the E-mail messageis forwarded from one system to another system that also uses MSF, anotherMSF message gets created on the receiving system as shown in Figure 8 onpage 14. In this case, the E-mail message is being sent using the X.400 protocol.

To MSF on the receiving system, the creation of the MSF message serves thesame function: to determine how its information should be changed, converted,delivered, forwarded and accounted. However, this time it is the receivingsystem ′s framework and exit point programs that are using the MSF messageinformation.

The information in the MSF message could be different than what was originallyused to create the MSF message on the sending system because exit pointprograms are allowed to change this information. Also, the message forwardingexit point, the transport protocol it uses, or the network the E-mail messages useto get between systems could all have modified the information in some way.

The frameworks used on the sending or receiving systems make no distinctionbetween the creations done in this scenario for sending the E-mail message onone system versus receiving the same E-mail message on another. In bothinstances, creating the MSF message allows MSF on either system to call theexit point programs. The exit point programs provide the send and receivefunctions to process the E-mail message.

MSF Message FlowWhen a message has been created it is then processed by the mail serverframework and its associated exit point programs. It is not predetermined howthat message may be handled. It is through dynamic means that a message maybe handled differently. This can involve a single exit point program for any givenexit point, multiple exit point programs or no exit point programs.

For example, a user could indicate that mail was to be delivered to his home viafacsimile one day or via OfficeVision/400 the next. An address resolution exitpoint program determines what type of servicing is needed. This can be done viathe preferred address indicated in the system distribution directory. Foradditional information on this, see Appendix C, “Using the AS/400 SystemDistribution Directory” on page 276.

As another example, assume there is a company policy against sendingconfidential mail outside the company. A program configured in the security andauthority exit point could determine if any of the recipients are to be forwardedremotely to a system outside the company and that the message containedconfidential information. The exit point program could set the status of eachrecipient to non-deliverable so that the message is handed to thenon-deliverable exit point rather than the message forwarding exit point.

Chapter 2. Mail Server Framework Concepts 15

Page 40: AnyMail/400 Mail Server Framework Developer Guide January 1995

These are just two examples of the way exit point programs can be utilized todynamically determine the processing of a message within the framework.

Determining the Exit Point Program to CallAs previously discussed, there is a certain sequence to the processing of anMSF message that is created by an application. That is, list expansion occursfirst followed by address resolution, and so on until the message has beenprocessed by each exit point.

However, not all messages are processed by all programs configured for aparticular exit point. For example, if a message is for an OfficeVision/400recipient, it is a SNADS program that performs the local delivery function, ratherthan an SMTP program. It is this selectivity mechanism that is defined by themail server framework that defines which exit point programs are called for theparticular exit point.

For the addressing group of MSF, it is the address type of each recipient in therecipient list that controls which program to call. When you use the WRKREGINFCL command to register an exit point program, it is required that thecorresponding address types that it processes be configured as well. Forexample, if an address resolution program wants to process SNADS addresseswhich use address types 01A1, 01A2 and 01A3, then the exit point program datamust be provided as shown in Figure 9.

Figure 9. Exit Point Program Registration

Note that the data specified is SPCL010001A101A201A3. SPCL0100 indicates theformat of the data that is to be given to the exit point program. The01A101A201A3 are the types that are matched with the address type in eachrecipient entry in the recipient list to trigger the calling of that program. When amessage is created with recipients that have this type, MSF calls this program.

For the pre-delivery processing and the management exit points of MSF, it is themessage type that is assigned to each recipient that controls which program tocall. For example, if an envelope processing program wants to be called whenthere are SMTP message types, then the exit point program data must beprovided as SPCL010002AF.

For additional information on how to use the WRKREGINF command to configureexit point programs for MSF, see Chapter 3, “Mail Server FrameworkConfiguration” on page 18.

For the delivery groups of the framework, it is a combination of the messagetype that is assigned to each recipient along with the status of each recipient.For example, recipients of a certain message type that are assigned a status oflocal will trigger the calling of a program configured in the local delivery exitpoint with data that indicates it handles that message type. Similarly, recipients

16 AnyMail/400 MSF

Page 41: AnyMail/400 Mail Server Framework Developer Guide January 1995

assigned a status of remote or non-delivery are processed by the appropriateexit point program configured for message forwarding or non-delivery,respectively.

During the configuration of exit point programs, it may be the case that multipleprograms are configured to handle the same data type. When this is the case,the program with the lowest program number in the configuration is triggered.

It is also possible that an exit point program can be configured to process alldata types. This can be done by specifying 9999 for the data type. For additionalconsiderations when multiple programs are configured for the same data type orall data types, see “Multiple Exit Point Programs” on page 87.

Chapter 2. Mail Server Framework Concepts 17

Page 42: AnyMail/400 Mail Server Framework Developer Guide January 1995

Chapter 3. Mail Server Framework Configuration

The MSF configuration consists of two parts: the APIs that are used to managethe data type definitions and the registration facility that is used to register exitpoint programs in one of the exit points of the mail server framework. Figure 10shows the parts of the MSF configuration.

Figure 10. The MSF Configuration

MSF Data TypesChapter 2, “Mail Server Framework Concepts” on page 3 describes the differentkinds of data that can be represented in a message. The phrase data type or theword type is used to represent that data. The mail server framework uses thedata type to define the format of the information contained in an MSF message.The mail server framework also uses the data type to select the exit pointprograms used to process a message. See “Typing of MSF Data” on page 5 formore information about the MSF data types. See Chapter 6, “Mail ServerFramework Exit Points” on page 80 for more information about exit pointprograms.

The mail server framework defines four type groups. As shown in Table 1, eachof the four type groups has a two-character identifier that distinguishes it fromthe others. The type group is used by the configuration APIs for data typedefinitions.

Table 1 (Page 1 of 2). MSF Type Groups and CharacterIdentifiers

Type Group Character

Address data type 01

18 Copyright IBM Corp. 1995

Page 43: AnyMail/400 Mail Server Framework Developer Guide January 1995

Table 1 (Page 2 of 2). MSF Type Groups and CharacterIdentifiers

Type Group Character

Message data type 02

Envelope data type 03

Attachment reference data type 04

Rules for MSF Data Type DefinitionsEvery MSF data type definition is associated with a type group and consists of adata type value, type name, and type text. Each type group in the MSFconfiguration allows for a maximum of 128 data type definitions with a total of512 data type definitions for the four groups. There are a small number ofIBM-supplied data types that are predefined in the MSF configuration and areshipped with the OS/400 licensed program. See “List of IBM-Supplied DataTypes” for more information on the IBM-supplied data types.

The data type value is a unique 4-character representation. Allowed charactervalues are A through Z and 0 through 9. Type values that contain blanks are notallowed. The following type values have special meaning to the mail serverframework.

• 0xxx to 1xxx are reserved for use by IBM.

Warning

It is not recommended to define a data type using this range. IBM may, ata later time, add additional predefined data types within this range. If adata type definition is found in this range and it is not supplied by IBM,this could cause problems for MSF mail applications.

• 9998 is reserved for use as the non-delivery message data type.

• 9999 is not a real data type but is reserved for use in specifying that an exitpoint program is configured to process all address or message data types.

The type name is the name of the data type being configured. This is a unique8-character mnemonic representation. Allowed character values are A through Zand 0 through 9. Type names that contain imbedded blanks are not allowed. Foraddress data type definitions, the type name could be an association to thesystem distribution directory. See Appendix C, “Using the AS/400 SystemDistribution Directory” on page 276 for information about the system distributiondirectory.

The type text is a description of the data type definition. The type text maycontain any character value that describes the data type.

List of IBM-Supplied Data TypesThe following tables contain all of the predefined data types that are supplied byIBM in Version 3 Release 1. More data types may be added at a later time.“Rules for MSF Data Type Definitions” shows the range of IBM-reserved datatypes.

Note: These data types may not be in use by electronic mail applicationscreating MSF messages or by IBM-supplied exit point programs.

Chapter 3. Mail Server Framework Configuration 19

Page 44: AnyMail/400 Mail Server Framework Developer Guide January 1995

The following table contains all predefined address data types.

The following table contains all predefined message data types.

The following table contains all predefined envelope data types.

Table 2. IBM-Supplied Address Types

Data Type Type Name Type Text

01A1 ATDGNDEN User address user identifier address type

01A2 ATRGEDGE System address system name user address useridentifier address type

01A3 ATSVDS System view distribution services address type

01A4 USER User profile address type

01A5 FULNAM Full name address type

01A6 NETUSRID Network user identifier address type

01A7 TELNBR1 Telephone number one address type

01A8 TELNBR2 Telephone number two address type

01AA ORNAME X.400 O/R address type

01AB CCMAIL cc:Mail** address type

01B0 SMTP Simple mail transfer protocol address type

01A9 FAXTELNB Facsimile telephone number address type

Table 3. IBM-Supplied Message Types

Data Type Type Name Type Text

02A1 MTDIA Document interchange architecture message type

02A2 MTOBJDST Object distribution message type

02A3 MTDLS Document library services message type

02A4 MTDSNX Distributed system node executive message type

02A5 MTSVDS System view distribution services message type

02AF MTSYSMS System message store message type

9998 MTNONDLV Nondeliverable message type

Table 4. IBM-Supplied Envelope Types

Data Type Type Name Type Text

03A1 DIAET Document interchange architecture envelope type

03A2 ETOBJDST Object distribution envelope type

03A3 ETDLS Document library services envelope type

03A4 ETDSNX Distributed system node executive envelope type

03A5 ETSVDS System view distribution services envelope type

03AF ETG Generic envelope type

20 AnyMail/400 MSF

Page 45: AnyMail/400 Mail Server Framework Developer Guide January 1995

The following table contains all predefined attachment reference data types.

Table 5. IBM-Supplied Attachment Reference Types

Data Type Type Name Type Text

04A1 RTGFS SNADS general file server attachment reference type

04A2 RTDIA Document interchange architecture file serverattachment reference type

MSF Configuration APIsThe mail server framework configuration APIs are used to manage data typedefinitions within the MSF configuration. The three MSF configuration APIs arethe following:

• The Add Mail Server Framework Configuration (QzmfAddMailCfg) API adds adata type definition to the MSF configuration.

• The Remove Mail Server Framework Configuration (QzmfRmvMailCfg) APIremoves an existing data type definition from the MSF configuration.

• The List Mail Server Framework Configuration (QzmfLstMailCfg) API lists allor some of the existing data type definitions in the MSF configuration.

For information about how to use the configuration APIs, see Chapter 8, “MailServer Framework Configuration APIs” on page 137. For a program example,see “Type Configuration Program — Example” on page 297. For specificinformation about the configuration APIs, see System API Reference.

Chapter 3. Mail Server Framework Configuration 21

Page 46: AnyMail/400 Mail Server Framework Developer Guide January 1995

OS/400 User Registration FacilityNote: The OS/400 User Registration Facility is not part of the mail server

framework. It is part of the OS/400 licensed program.

The registration facility is used to manage the exit points and exit programs ofthe mail server framework. The registration facility consits of the Work withRegistration Information (WRKREGINF) command and five APIs.

IBM-Supplied Exit Points for the MSFThere are twelve IBM-supplied exit points predefined for the mail serverframework configuration and are shipped with the OS/400 licensed program.Table 6 shows these predefined exit points. For more information about theMSF exit points and exit point programs, see Chapter 6, “Mail ServerFramework Exit Points” on page 80.

Table 6. IBM-Supplied Exit Points for the MSF

Exit Point NameFormatName Exit Point Description

QIBM_QZMFMSF_ACT MSFF0100 MSF Accounting Exit

QIBM_QZMFMSF_ADR_RSL MSFF0100 MSF Address Resolution

QIBM_QZMFMSF_ATT_CNV MSFF0100 MSF Attachment Conversion

QIBM_QZMFMSF_ATT_MGT MSFF0100 MSF Attachment Management

QIBM_QZMFMSF_ENL_PSS MSFF0100 MSF Envelope Processing

QIBM_QZMFMSF_LCL_DEL MSFF0100 MSF Local Delivery

QIBM_QZMFMSF_LST_EXP MSFF0100 MSF List Expansion

QIBM_QZMFMSF_MSG_FWD MSFF0100 MSF Message Forwarding

QIBM_QZMFMSF_NON_DEL MSFF0100 MSF Non Delivery

QIBM_QZMFMSF_SEC_AUT MSFF0100 MSF Security and Authority

QIBM_QZMFMSF_TRK_CHG MSFF0100 MSF Track Mail Message Changes

QIBM_QZMFMSF_VLD_TYP MSFF0100 MSF Valid Type

IBM-Supplied Exit Point Programs for the MSFA small number of IBM-supplied exit point programs are predefined for the MSFconfiguration and are shipped with the OS/400 licensed program. Table 7 showsthese predefined exit point programs. For more information about the MSF exitpoints and exit point programs, see Chapter 6, “Mail Server Framework ExitPoints” on page 80.

Table 7 (Page 1 of 2). IBM-Supplied Exit Point Programs for the MSF

Exit Program Name

ExitProgramNumber Exit Point Name Exit Program Data

QSYS/QZDSNPAC 1000 QIBM_QZMFMSF_ACT SPCL010002A102A202A302A402A5

QSYS/QZDSNPAD 1000 QIBM_QZMFMSF_ADR_RSL SPCL010001A101A201A3

QSYS/QZMFSNPA 2000 QIBM_QZMFMSF_ADR_RSL SPCL01009999

QSYS/QZDSNPAM 1000 QIBM_QZMFMSF_ATT_MGT SPCL01009999

22 AnyMail/400 MSF

Page 47: AnyMail/400 Mail Server Framework Developer Guide January 1995

Table 7 (Page 2 of 2). IBM-Supplied Exit Point Programs for the MSF

Exit Program Name

ExitProgramNumber Exit Point Name Exit Program Data

QSYS/QZDSNPLD 1000 QIBM_QZMFMSF_LCL_DEL SPCL010002A102A202A302A4

QSYS/QZDSNPLE 1000 QIBM_QZMFMSF_LST_EXP SPCL010001C0

QSYS/QZDSNPMF 1000 QIBM_QZMFMSF_MSG_FWD SPCL010002A102A202A302A4

QSYS/QZDSNPND 1000 QIBM_QZMFMSF_NON_DEL SPCL010002A102A202A302A4

Registering Exit Point ProgramsAppendix E, “An MSF Application — Example” on page 294 contains programexamples of exit point programs for the mail server framework. This topic usesone of these programs to demonstrate how to add an exit point program to anexit point. See “Type Configuration Program — Example” on page 297 for theprogram used.

From the command line, enter the WRKREGINF command. Use the MSF0100format name to display the mail server framework exit points. Select option 8(Work with exit programs) to add the sample exit point program to the localdelivery exit point. See Figure 11.

� �Work with Registration Information

Type options, press Enter.5=Display exit point 8=Work with exit programs

ExitExit Point

Opt Point Format Registered TextQIBM_QZMFMSF_ACT MSFF0100 *YES MSF Accounting ExitQIBM_QZMFMSF_ADR_RSL MSFF0100 *YES MSF Address ResolutionQIBM_QZMFMSF_ATT_CNV MSFF0100 *YES MSF Attachment ConversionQIBM_QZMFMSF_ATT_MGT MSFF0100 *YES MSF Attachment ManagementQIBM_QZMFMSF_ENL_PSS MSFF0100 *YES MSF Envelope Processing

8 QIBM_QZMFMSF_LCL_DEL MSFF0100 *YES MSF Local DeliveryQIBM_QZMFMSF_LST_EXP MSFF0100 *YES MSF List ExpansionQIBM_QZMFMSF_MSG_FWD MSFF0100 *YES MSF Message ForwardingQIBM_QZMFMSF_NON_DEL MSFF0100 *YES MSF Non DeliveryQIBM_QZMFMSF_SEC_AUT MSFF0100 *YES MSF Security and AuthorityQIBM_QZMFMSF_TRK_CHG MSFF0100 *YES MSF Track Mail Message Change

More...Command ===> F3=Exit F4=Prompt F9=Retrieve F12=Cancel

� �Figure 11. Work with Registration Information Display

From the Work with Exit Programs display, select option 1 (Add) to add exit pointprogram QZMFSAMPLE/TRTVMSG. See Figure 12 on page 24.

Chapter 3. Mail Server Framework Configuration 23

Page 48: AnyMail/400 Mail Server Framework Developer Guide January 1995

� �Work with Exit Programs

Exit point: QIBM_QZMFMSF_LCL_DEL Format: MSFF0100

Type options, press Enter. 1=Add 4=Remove 5=Display 10=Replace

ExitProgram Exit

Opt Number Program Library 1 TRTVMSG QZMFSAMPLE

1000 QZDSNPLD QSYS

Bottom Command ===> F3=Exit F4=Prompt F5=Refresh F9=Retrieve F12=Cancel

� �Figure 12. Work with Exit Programs Display

From the Add Exit Program display, select the program number to use for yourexit point program. This example uses the value 1 to make the program first inthe list. See Figure 13.

� �Add Exit Program (ADDEXITPGM)

Type choices, press Enter.

Exit point . . . . . . . . . . . > QIBM_QZMFMSF_LCL_DEL Exit point format . . . . . . . > MSFF0100 Name Program number . . . . . . . . . > 1 1-2147483647, *LOW, *HIGH Program . . . . . . . . . . . . > TRTVMSG Name

Library . . . . . . . . . . . > QZMFSAMPLE Name, *CURLIB Text ′ description′ . . . . . . . Add exit point program TRTVMSG

BottomF3=Exit F4=Prompt F5=Refresh F10=Additional parameters F12=Cancel F13=How to use this display F24=More keys

� �Figure 13. Add Exit Program Display

Next, press F10 (Additional parameters). See Figure 14 on page 25.

24 AnyMail/400 MSF

Page 49: AnyMail/400 Mail Server Framework Developer Guide January 1995

� �Add Exit Program (ADDEXITPGM)

Type choices, press Enter.

Exit point . . . . . . . . . . . > QIBM_QZMFMSF_LCL_DEL Exit point format . . . . . . . > MSFF0100 Name Program number . . . . . . . . . > 1 1-2147483647, *LOW, *HIGH Program . . . . . . . . . . . . > TRTVMSG Name

Library . . . . . . . . . . . > QZMFSAMPLE Name, *CURLIB Text ′ description′ . . . . . . . Add exit point program TRTVMSG

Additional Parameters

Replace existing entry . . . . . > *NO *YES, *NO Create exit point . . . . . . . *NO *YES, *NO

More...F3=Exit F4=Prompt F5=Refresh F12=Cancel F13=How to use this display F24=More keys

� �Figure 14. Add Exit Program Display (After Pressing F10)

Page down to the second page of the Add Exit Program display. Enter both thelength of the exit program data and the exit program data. The value 12 is usedas the length because the exit program data will contain 12 characters.

The program data must consist of the format name for the exit point programand some number of data type values of the data type definitions that you wantto use. The format name is 8 characters long and is SPCL0100 for this exit point.Data type values are 4 characters long and is 02TV for this example. The datatype value used for this exit point must be from the message type group. SeeFigure 15 on page 26.

Chapter 3. Mail Server Framework Configuration 25

Page 50: AnyMail/400 Mail Server Framework Developer Guide January 1995

� �Add Exit Program (ADDEXITPGM)

Type choices, press Enter.

Exit program data:Coded character set ID . . . . *NONE Number, *NONE, *JOBLength of data . . . . . . . . 12 0-2048, *CALCProgram data . . . . . . . . . SPCL010002TV

...

BottomF3=Exit F4=Prompt F5=Refresh F12=Cancel F13=How to use this display F24=More keys

� �Figure 15. Add Exit Program Display (After Paging Down)

Next, press the enter key. You are now back at the Work with Exit Programsdisplay. The exit program has been added to the local delivery exit point. SeeFigure 16.

� �Work with Exit Programs

Exit point: QIBM_QZMFMSF_LCL_DEL Format: MSFF0100

Type options, press Enter. 1=Add 4=Remove 5=Display 10=Replace

ExitProgram Exit

Opt Number Program Library

1 TRTVMSG QZMFSAMPLE1000 QZDSNPLD QSYS

Bottom Command ===> F3=Exit F4=Prompt F5=Refresh F9=Retrieve F12=Cancel

� �Figure 16. Work with Exit Programs Display

26 AnyMail/400 MSF

Page 51: AnyMail/400 Mail Server Framework Developer Guide January 1995

Rules for MSF Exit Point Program DataYou are allowed to add exit point programs to each of the MSF exit points.However, there are some rules that you will need to follow for the data that youplace in the exit point program data.

Each of the mail server framework exit points requires program data for each ofthe exit point programs that are registered. The program data consists of aformat name and up to 128 data type values from a specific type group,depending on the exit point. The length of the program data is always equal tothe program data format name and the data type values used. Data type valuesused must be defined to the MSF configuration to be used in exit point programdata.

IBM uses specific numbers that end in 000 for the exit point programs that areIBM-supplied. For example, 1000, 2000...10000, 11000.

Warning

It is not recommended to add an exit point program using one of the exitpoint program numbers that are used by IBM. It is also not recommended tochange or remove an exit program number for an exit point program that isIBM-supplied. Unexpected results could occur.

See Table 8 for additional requirements.

Table 8. Exit Point Program Data Format Names

Exit Point Name Format Data Type Values Allowed

QIBM_QZMFMSF_ACT SPCL0100 Data type values from message type group.Multiple type values from 1 to 128.

QIBM_QZMFMSF_ADR_RSL SPCL0100 Data type values from address type group.Multiple type values from 1 to 128.

QIBM_QZMFMSF_ATT_CNV SPCL0100 Data type values from message type group.Multiple type values from 1 to 128.

QIBM_QZMFMSF_ATT_MGT SPCL0100 Data type values from message type group.Multiple type values from 1 to 128.

QIBM_QZMFMSF_ENL_PSS SPCL0100 Data type values from message type group.Multiple type values from 1 to 128.

QIBM_QZMFMSF_LCL_DEL SPCL0100 Data type values from message type group.Multiple type values from 1 to 128.

QIBM_QZMFMSF_LST_EXP SPCL0100 Data type values from address type group.Multiple type values from 1 to 128.

QIBM_QZMFMSF_MSG_FWD SPCL0100 Data type values from message type group.Multiple type values from 1 to 128.

QIBM_QZMFMSF_NON_DEL SPCL0100 Data type values from message type group.Multiple type values from 1 to 128.

QIBM_QZMFMSF_SEC_AUT SPCL0100 Data type values from message type group.Multiple type values from 1 to 128.

QIBM_QZMFMSF_TRK_CHG TCMM0100 Data type values not allowed.

QIBM_QZMFMSF_VLD_TYP VDFL0100 Data type values from any type group.Single type value only.Data type value must not be used by another exit point program.

Chapter 3. Mail Server Framework Configuration 27

Page 52: AnyMail/400 Mail Server Framework Developer Guide January 1995

Registration Facility APIsThe registration facility APIs are used to manage exit points and exit pointprograms within the registration facility. The five registration facility APIs are asfollows:

• The Register Exit Point (QusRegisterExitPoint) API registers an exit point withthe registration facility.

• The Deregister Exit Point (QusDeregisterExitPoint) API removes an exit pointand all associated exit point programs from the registration facility.

• The Add Exit Program (QusAddExitProgram) API adds an exit program entryto a specific exit point or replaces an existing exit program.

• The Remove Exit Program (QusRemoveExitProgram) API removes an exitprogram entry from a specific exit point.

• The Retrieve Exit Information (QusRetrieveExitInformation) API retrievesinformation about one or more exit points and their associated exitprograms.

For information about the registration facility APIs, see System API Reference.

28 AnyMail/400 MSF

Page 53: AnyMail/400 Mail Server Framework Developer Guide January 1995

Chapter 4. Mail Server Framework Operation

This chapter describes the control language (CL) commands used to start andend the mail server framework. It also describes some of the internal structuresof MSF, some of the internal processing done during MSF starting and ending,and the OS/400 jobs that process MSF messages.

Starting MSFMSF must be active in order to process MSF messages. When MSF is notactive, MSF messages may still be created but will be queued, waiting until MSFis started.

During the starting of MSF, the following basic tasks are done:

• Copy the MSF configuration• Prepare existing MSF messages for processing• Submit OS/400 jobs to do MSF processing

Use the Start Mail Server Framework (STRMSF) command to start MSF.

Start Mail Server Framework CommandThe Start Mail Server Framework (STRMSF) command starts the mail serverframework. There are two parameters that can be specified on the STRMSFcommand. The syntax of the STRMSF command follows:

STRMSF MSGOPT(Message_Option) NBRMSFJOB(Number_of_MSF_jobs)

MSGOPT (Message Option) ParameterThe MSGOPT parameter specifies how MSF processes existing MSFmessages.

*RESUME This is the default option. This option causes existingMSF messages to continue processing at the exit pointprogram where they were interrupted when the mailserver framework was previously ended.

*RESET This option causes existing MSF messages to beprocessed as if they were just created. The messagesare processed at the first exit point program.

*CLEAR This option causes all existing MSF messages to bedeleted. Use this option with care, since all messagesare deleted and cannot be recovered.

For more information on how existing messages are processed, see“Preparation of Existing MSF Messages” on page 31 and Chapter 2, “MailServer Framework Concepts” on page 3.

NBRMSFJOB (Number of Mail Server Framework Jobs) ParameterThe NBRMSFJOB parameter specifies the number of OS/400 batch jobs thatwill be started to do MSF processing. These MSF jobs run concurrently inthe QSYSWRK subsystem.

The minimum value for the NBRMSFJOB parameter is 1, and the maximumvalue is 99. Each of the MSF jobs processes a separate message. This

Copyright IBM Corp. 1995 29

Page 54: AnyMail/400 Mail Server Framework Developer Guide January 1995

allows for the concurrent processing of messages. If a large number of jobsis specified, electronic mail on the system can be handled quickly by MSF.However, if you have a large number of jobs processing MSF, there will beless system resources for non-mail applications when the jobs areprocessing messages. Therefore, care must be taken in choosing theappropriate value for each particular system. The default for theNBRMSFJOB parameter is three (3) jobs.

See the CL Reference for more information about the STRMSF command. Formore information about QSYSWRK, see the Work Management book.

Copying the MSF ConfigurationOne of the tasks done during the starting of MSF is the copying of the MSFconfiguration. The MSF has an external configuration and an internalconfiguration. The external configuration gets updated by the MSF configurationAPIs. For more information on configuration APIs, see Chapter 3, “Mail ServerFramework Configuration” on page 18 and Chapter 8, “Mail Server FrameworkConfiguration APIs” on page 137. The internal configuration is a space withinthe MSF environment that is accessed by the MSF jobs. When the Start MailServer Framework (STRMSF) command gets issued and MSF is starting, theexternal configuration is copied to the internal configuration. See Figure 17.

Figure 17. Copying the MSF Configuration

The internal MSF configuration and external MSF configuration are used for thefollowing reasons:

• The MSF configuration may be updated at any time without affecting currentMSF processing.

• Because the internal configuration does not change while the MSF jobs areprocessing, the MSF messages are processed under a consistentenvironment.

Because the MSF configuration is copied during the starting of MSF, the size ofthe MSF configuration has a direct effect on the STRMSF completion time. The

30 AnyMail/400 MSF

Page 55: AnyMail/400 Mail Server Framework Developer Guide January 1995

larger the MSF configuration (for example, many exit point programs areregistered and many types are defined), the longer it takes for the STRMSFcommand to complete.

Changing MSF Configuration

Changes to the MSF external configuration are copied to the internalconfiguration only during the starting of MSF. Therefore, any changes youmake to the MSF configuration do not actually take effect until the next timeMSF is started via the Start Mail Server Framework (STRMSF) command.

For more information on the MSF configuration, see Chapter 3, “Mail ServerFramework Configuration” on page 18.

Preparation of Existing MSF MessagesAnother task done during the starting of MSF is the preparation of existing MSFmessages (for a detailed description of what comprises an MSF message, seeChapter 5, “Mail Server Framework Message” on page 44). There are threeareas where MSF messages may exist at any given time in the MSFenvironment. Once an MSF message is created, it is put on the MSF queue.The MSF message then gets taken from the MSF queue and processed by anMSF job. Normally, the message is successfully processed, and the MSFmessage is deleted. However, it is possible that the MSF job may stop normalprocessing of a message due to an error encountered in an exit point program.In the case where an error is encountered while the MSF message is beingprocessed, the message gets set aside for later processing. At any given time,an MSF message may exist in one of the following three areas:

• In the MSF queue• In an MSF job• In a set aside area.

See Figure 18 on page 32 for an illustration of the three areas where MSFmessages may exist.

Chapter 4. Mail Server Framework Operation 31

Page 56: AnyMail/400 Mail Server Framework Developer Guide January 1995

Figure 18. Existing MSF Messages

During the starting of MSF, all the messages from the three possible areas areprepared for processing. All the existing MSF messages are put on the singleMSF queue to await processing by MSF. MSF messages are ordered on theMSF queue according to the time that they were created. The messages on thequeue have the following order:

1. The oldest MSF messages are put at the front of the queue. Usually, MSFmessages that were set aside due to an error are the oldest and are placedat the front of the MSF queue.

2. MSF messages that were interrupted during processing by the ending ofMSF.

3. MSF messages that were already on the MSF queue and had not started tobe processed.

Figure 19 on page 33 shows an example of how existing MSF messages areplaced on the MSF queue. Existing MSF messages in all three areas are beingprepared for processing during the starting of MSF. Once MSF messages havebeen prepared for processing, all the messages are on the queue, with noneremaining in the other two areas.

32 AnyMail/400 MSF

Page 57: AnyMail/400 Mail Server Framework Developer Guide January 1995

Figure 19. MSF Messages Being Placed on the MSF Queue During STRMSF

Once on the MSF queue, how each existing MSF message will get processed byMSF is determined by the value of the Message Option (MSGOPT) parameterused on the STRMSF command. Remember that the possible values for theMSGOPT parameter are *RESUME, *RESET, and *CLEAR.

Chapter 4. Mail Server Framework Operation 33

Page 58: AnyMail/400 Mail Server Framework Developer Guide January 1995

When the *CLEAR value is used for the MSGOPT parameter, the MSF queue isemptied and all MSF messages are discarded. MSF messages from all threeareas are discarded and are not able to be recovered. Therefore, only use theMSGOPT(*CLEAR) option under extreme conditions. Figure 20 on page 34shows all existing MSF messages being discarded.

Figure 20. MSF Messages Being Cleared

If an MSF job ends while processing an MSF message, the processing of theMSF message is interrupted. The use of *RESUME or *RESET values for theMSGOPT parameter of STRMSF affects MSF messages that were interruptedwhen MSF was last ended. When the *RESUME value is used, MSF messagesresume processing in MSF at the exit point program where they wereinterrupted. Figure 21 on page 35 shows an example. If an MSF message wasin a local delivery exit point program when MSF was last ended, the messageresumes processing in the same local delivery exit point program when STRMSFis issued with MSGOPT(*RESUME).

34 AnyMail/400 MSF

Page 59: AnyMail/400 Mail Server Framework Developer Guide January 1995

Figure 21. MSF Message Being Resumed at Termination Point

Note: The use of MSGOPT(*RESUME) does not guarantee how exit pointprograms resume processing an MSF message. For example, assume anMSF message is being processed by a message forwarding exit pointprogram and the message is half sent when the message is interrupted.When MSF is started with MSGOPT(*RESUME), the MSF message startsprocessing with the same message forwarding exit point program.However, that exit point program may resume sending the messagewhere it was interrupted, or it may start sending it again from thebeginning. How exit point programs resume processing of MSFmessages is decided by the exit point program.

When the *RESET value is used for the MSFOPT parameter, MSF messagesbegin processing in MSF at the first MSF exit point. Whatever changes that weredone to the MSF message before the starting of MSF are discarded. Therefore,if an MSF message was changed by one or more exit point programs beforeMSF ended, those changes are discarded and the message will now beprocessed again by the appropriate exit point programs. Figure 22 on page 36shows an example of an MSF message being processed by a local delivery exitpoint program when MSF is ended. The message does not resume processingin the local delivery exit point program when STRMSF is issued withMSGOPT(*RESET), but begins processing at the first MSF exit point (listexpansion).

Chapter 4. Mail Server Framework Operation 35

Page 60: AnyMail/400 Mail Server Framework Developer Guide January 1995

Figure 22. MSF Message Being Reset

Using the *RESET value for the MSGOPT parameter requires more processingtime than using the *RESUME value. This is because of the extra steps involvedin discarding changes that were done to the MSF messages by the exit pointprograms. This increase in processing time of the STRMSF command will benoticed only if there were many MSF messages (which implies many MSF jobs)that were interrupted the last time MSF ended.

QMSF Job SubmissionThe final task done during the starting of MSF is the submitting of OS/400 jobs todo MSF processing. As shown in Figure 23 on page 37, STRMSF submits theMSF batch jobs in the QSYSWRK subsystem. The MSF jobs are submitted with ajob name of QMSF and use the QMSF user profile. The QMSF job names andthe use of the QMSF profile cannot be changed. Figure 23 on page 37 showsSTRMSF submitting the QMSF jobs.

36 AnyMail/400 MSF

Page 61: AnyMail/400 Mail Server Framework Developer Guide January 1995

Figure 23. STRMSF Submitt ing QMSF Jobs

The NBRMSFJOB parameter on the Start Mail Server Framework (STRMSF)command specifies the number of OS/400 jobs that are submitted. For moreinformation regarding the MSF jobs, see “QMSF Job Structure” on page 39.

Ending MSFEnding MSF simply ends both the processing of MSF messages in MSF and theactive MSF jobs in the QSYSWRK subsystem.

The End Mail Server Framework (ENDMSF) command is used to end the mailserver framework. The ENDMSF command is equivalent to using the End Job(ENDJOB) command on all the QMSF jobs in the QSYSWRK subsystem.

End Mail Server Framework CommandThe End Mail Server Framework (ENDMSF) command ends the mail serverframework in an immediate or controlled manner. There are two parametersthat can be specified on the ENDMSF command. The syntax of the ENDMSFcommand follows:

ENDMSF OPTION(Option) DELAY(Delay)

OPTION (Option) ParameterThe OPTION parameter specifies whether the mail server framework jobs inthe QSYSWRK subsystem are to end either in an immediate or a controlledmanner.

Chapter 4. Mail Server Framework Operation 37

Page 62: AnyMail/400 Mail Server Framework Developer Guide January 1995

*CNTRLD Allows all MSF jobs to end in a controlled manner.This option allows each MSF job a chance to finishprocessing its current MSF message before the jobends. *CNTRLD is the default for the OPTIONparameter.

*IMMED Causes all MSF jobs to end immediately. The MSFmessages that are interrupted when the jobs end areprocessed again when the mail server framework isstarted.

DELAY (Delay) ParameterThe DELAY parameter specifies the maximum number of seconds to allowthe MSF jobs to end in a controlled manner. If the MSF jobs do not end bythe time DELAY seconds have passed, the MSF jobs will be endedimmediately. This parameter is used only if OPTION(*CNTRLD) is specified.

The valid values for the DELAY parameter range from 1 through 999999seconds. The default value for the DELAY parameter is 30 seconds.

For more information about the ENDMSF command, see the CL Reference.

Immediate or Controlled EndingThe ENDMSF command ends MSF in an immediate or controlled manner. WhenMSF is ended in an immediate manner, the MSF messages currently beingprocessed end immediately along with the QMSF jobs. The MSF messages thatare interrupted by the immediate ending are processed when MSF is startedagain according to the MSGOPT parameter of the STRMSF command.

When MSF is ended in a controlled manner, the MSF messages currently beingprocessed are given time to complete. The amount of time that they are given isspecified by the DELAY parameter of the ENDMSF command. If an MSFmessage does not complete in the amount of time given by the DELAYparameter, it is treated like an immediate end. Once the processing of thecurrent MSF message completes, the MSF job will end.

Figure 24 on page 39 shows what happens to an MSF message that is beingprocessed when MSF is ended immediately and when MSF is ended in acontrolled manner. In both examples, the MSF message is in a local deliveryexit point program at the time the ENDMSF command is issued. In the firstexample, MSF is ended immediately and the MSF message gets dropped. In thesecond example, MSF is ended in a controlled manner and the MSF messagegets completely processed before the DELAY time expires.

38 AnyMail/400 MSF

Page 63: AnyMail/400 Mail Server Framework Developer Guide January 1995

Figure 24. MSF Ending Immediate and Control led

QMSF Job StructureWhen MSF is active, there are MSF jobs in the QSYSWRK subsystem. Thesejobs do the actual processing of the MSF messages.

The MSF jobs are submitted during the starting of MSF by the STRMSFcommand and have the QMSF name. There may be multiple QMSF jobs inQSYSWRK if multiple jobs were specified by the NBRMSFJOB parameter of theSTRMSF command. Figure 23 on page 37 shows multiple QMSF jobs that aresubmitted and started in the QSYSWRK subsystem.

Once a QMSF job becomes active, it takes the next waiting MSF message fromthe MSF queue and begins to process it. Remember that MSF messages areordered on the MSF queue such that the oldest messages are taken from thequeue first. The details on how the MSF message is processed by the QMSF jobcan be found in Chapter 2, “Mail Server Framework Concepts” on page 3. Uponcompletion of the MSF message, the QMSF job processes the next message onthe MSF queue. If there are no messages on the MSF queue, the QMSF jobwaits for an MSF message to be created and put on the queue. The QMSF jobcontinues this cycle of taking an MSF message from the queue and processing ituntil the job ends.

Each of the active QMSF jobs can be thought of as a separate mail engine. Theyact independently of each other and process MSF messages identically. Thereis no difference between the QMSF jobs when they are submitted. Once a QMSFjob starts processing an MSF message, that is the only job that will process thatmessage until either the message completes or MSF is ended and restarted.

Chapter 4. Mail Server Framework Operation 39

Page 64: AnyMail/400 Mail Server Framework Developer Guide January 1995

Multiple Instances of the Same Exit Point Program

Exit point programs should be designed such that multiple instances of theprogram can be processing simultaneously.

Multiple instances of the same exit point program is possible because there maybe multiple QMSF jobs processing MSF messages. If more than one of theQMSF jobs is using the same exit point program to process messages, the exitpoint program must be able to process in parallel with itself. For instance, exitpoint programs must be able to share resources such as files.

MSF ScalabilityBecause the QMSF jobs act independently, they are able to process MSFmessages concurrently. Figure 25 on page 41 shows multiple QMSF jobsgetting MSF messages from the MSF queue. Because multiple MSF messagescan be processed concurrently, the performance of MSF can be tailored to meetthe needs of the local system. If you choose to have many QMSF jobs,messages can be serviced by MSF quicker. However, the jobs will takeresources from other areas of the system (non-mail areas) when the QMSF jobsare processing messages. Therefore, the number of QMSF jobs to start must bechosen in accordance with the mission of the system. A system that isdedicated as a mail gateway in a network, for example, will probably want tohave a very large number of QMSF jobs active.

40 AnyMail/400 MSF

Page 65: AnyMail/400 Mail Server Framework Developer Guide January 1995

Figure 25. MSF Jobs Getting MSF Messages From the Queue

The QMSF jobs may end in the following ways:

• End the jobs by using the ENDMSF command. This method ends all QMSFjobs together.

• End a QMSF job by using the End Job (ENDJOB) command. This method canbe used to reduce the number of jobs currently processing MSF withouthaving to restart MSF.

• A QMSF job ends because an error occurs while processing an MSFmessage. The QMSF job ends with a joblog, an entry is made in the MSFjournal, and the MSF message is set aside until the next time MSF is started.For more information on errors that cause the QMSF job to end, seeChapter 18, “Error Handling in the Mail Server Framework” on page 208.

Automatic Starting of MSFMSF Shipped to Automatically Start

The OS/400 subsystem description of QSYSWRK is shipped with an autostartjob entry that automatically issues the STRMSF command to start MSF.

Chapter 4. Mail Server Framework Operation 41

Page 66: AnyMail/400 Mail Server Framework Developer Guide January 1995

Whenever subsystem QSYSWRK is started, job QZMFECOX is started in thesubsystem. The QZMFECOX job simply uses the QZMFEJBD job description thatspecifies STRMSF MSGOPT(*RESUME) NBRMSFJOB(1) in its request data. This STRMSFcommand starts MSF and submits one QMSF job in the QSYSWRK subsystem.The QMSF job then begins MSF processing. Note that the STRMSF commandspecified by the QZMFEJBD job description starts one QMSF job rather than thecommand ′s default value of three jobs.

The autostart job entry is part of the QSYSWRK subsystem description for thefollowing reasons:

• Starting MSF automatically allows mail applications to be available as soonas the QSYSWRK subsystem is available. This avoids the extra task ofstarting MSF after the QSYSWRK subsystem becomes available.

• Starting MSF automatically keeps a consistent start routine for mailapplications that existed prior to the introduction of MSF. For example, theSNA distribution services (SNADS) start routine consisted of simply startingthe QSNADS subsystem prior to the introduction of MSF. Now, since SNADSuses MSF, MSF must be started before SNADS can route messages.However, since MSF is started when the QSYSWRK subsystem is started, theSNADS start routine still needs to start only the QSNADS subsystem.

If you do not want the ability to start MSF automatically, you can remove theautostart job entry from the QSYSWRK subsystem description. This can be doneby using the Remove Autostart Job Entry (RMVAJE) command as follows:

RMVAJE SBSD(QSYSWRK) JOB(QZMFECOX)

If you want the autostart job entry again, use the Add Autostart Job Entry(ADDAJE) command as follows:

ADDAJE SBSD(QSYSWRK) JOB(QZMFECOX) JOBD(QZMFEJBD)

If you want more than one QMSF job submitted during the automatic starting ofMSF, you can change the QZMFEJBD job description. Use the Change JobDescription (CHGJOBD) command to do this. An example of changing theQZMFEJBD job description to start five QMSF jobs in QSYSWRK follows:

CHGJOBD JOBD(QZMFEJBD) RQSDTA(′ STRMSF MSGOPT(*RESUME) NBRMSFJOB(5)′ )

You can also use the CHGJOBD command to change the value of the MSGOPTparameter used during the automatic starting of MSF.

Descriptions Reset During OS/400 Installation

When the OS/400 licensed program is installed, all subsystem descriptionsand job descriptions get replaced. Therefore, if either the QSYSWRKsubsystem description or QZMFEJBD job description is changed before aninstallation of OS/400, the changes will be lost after the installation iscompleted. For example, if the CHGJOBD command in the example abovewas used to change the number of jobs to 5, the job description will onlystart 1 job again after the next installation of OS/400. If the changes to thedescriptions need to be saved, the job description and subsystem descriptionobjects should be saved before the installation. These objects can then berestored after the installation completes. This can be done using the SaveObject (SAVOBJ) and Restore Object (RSTOBJ) commands.

42 AnyMail/400 MSF

Page 67: AnyMail/400 Mail Server Framework Developer Guide January 1995

MSF QueueThere have been previous references to the MSF queue. It is important to knowthat the MSF queue exists and how it is used by MSF.

There is only one MSF queue. This queue is internally implemented in MSF tocontain MSF messages that are waiting to be processed. MSF messages aretaken from the queue in a first-in, first-out (FIFO) manner. Therefore, MSFmessages that are created first will be processed by MSF first. Note that someMSF messages take longer to process than other MSF messages. Therefore,messages that are taken from the MSF queue first may not be the first to finishprocessing.

MSF messages are put on the queue by the Create Mail Message(QzmfCrtMailMsg) API. The messages are taken from the queue and processedby the QMSF jobs. MSF messages may still be created by the Create MailMessage API and put on the MSF queue when there are no active QMSF jobs.

Because this queue is implemented internally to MSF, it is not directlyaccessible by any other programs, including exit point programs.

Chapter 4. Mail Server Framework Operation 43

Page 68: AnyMail/400 Mail Server Framework Developer Guide January 1995

Chapter 5. Mail Server Framework Message

This chapter contains information on the contents of an MSF message. This is astructural description of what can be thought of as the main object that is usedby the mail server framework (MSF).

The MSF message represents the work that is to be processed by the frameworkand its associated exit point programs.

Keep in mind that the framework′s aim is to make sure that MSF messages aredynamic objects. Messages exist only as long as it takes the framework toidentify and call the exit point programs. After the last exit point program in thelast exit point gets its chance to process on an MSF message, the message isimmediately deleted by the framework. MSF is implemented with the intent thatthe cycle of processing MSF messages occurs as fast as possible.

MSF Message ContentAll the information about an E-mail message is kept in lists in an object knownas MSF message. These lists are how MSF organizes the information in an MSFmessage. The lists allow the information to be specified when creating,changing, or retrieving information from an MSF message. A representation ofsome of these lists is shown in Figure 26 on page 45. For example:

• Information about where an E-mail message originated is kept in the MSFmessage ′s originator list .

• Information about the attributes of an E-mail message such as its subject orpriority are kept in an envelope . All envelopes are in the MSF message′senvelope list .

• Information about where an E-mail message is being sent is kept in the MSFmessage ′s recipient list .

• If the E-mail message has attachments like a document or a video object, thereferences to those attachments are kept in the MSF message′s attachmentreference list .

44 Copyright IBM Corp. 1995

Page 69: AnyMail/400 Mail Server Framework Developer Guide January 1995

Figure 26. An MSF Message is a Collection of Lists

The information in the lists mentioned in Figure 26 is set either by the creationof an MSF message or by exit point programs when they change the MSFmessage. In addition to this information, the framework itself keeps someinformation in every MSF message. There is some basic information about themessage and two specific lists the framework uses to keep track of how an MSFmessage is being processed.

The basic information kept by the framework in each MSF message includes thefollowing:

• The MSF message identifier assigned to it when the MSF message wascreated.

• A date/time stamp that records when the message was created by theframework ′s Create Mail Message (QzmfCrtMailMsg) API.

• An original message type that can be set by the message′s creator to helpindicate to MSF exit point programs what kind of mail application created theMSF message.

The two lists the framework keeps in every message it creates are:

Chapter 5. Mail Server Framework Message 45

Page 70: AnyMail/400 Mail Server Framework Developer Guide January 1995

• Exit point call history list

This list is used to keep track of information about the exit point programsthat are called as the framework processes an MSF message.

• Recipient history list

This list tracks the modifications that are made to an MSF message′srecipient list due to list expansion or address resolution exit point programs.

The basic information and the two lists mentioned above can be updated only bythe framework. They cannot be set by the creator of a message or changed byexit point programs. However, an exit point program can retrieve the informationusing the Retrieve Mail Message API.

MSF Message IdentifiersMSF assigns an identifier to every message that is created using theframework ′s Create Mail Message (QzmfCrtMailMsg) API. The MSF messageidentifier is unique for every message and is not reused. It is returned to thecaller of the QzmfCrtMailMsg API. The MSF message ID is passed as aparameter on all exit point program calls to allow the called program to identifythe message. It is a required input parameter value when an exit program usesthe Create Mail Message (QzmfChgMailMsg) or Retrieve Mail Message(QzmfRtvMailMsg) APIs because it identifies the MSF message whoseinformation is being changed or retrieved.

Some of the OS/400 error messages used by the framework and the log entriesthat MSF makes when processing a specific MSF message include the MSFmessage ′s unique ID.

Although normally assigned only when an MSF message is created, you canreserve an identifier using the Reserve Mail Message ID (QzmfRsvMailMsgID)API. The reserved identifier can then be used when creating an MSF messageby passing it as an input parameter value on the QzmfCrtMailMsg API.

How an MSF Message Gets CreatedIt is important to understand the difference in creating an MSF message versusoriginating or sending an E-mail message. When you create an MSF message,you encapsulate information about an E-mail message that the creating functionwants to keep in the MSF message. The framework passes this information tothe exit point programs it calls when it processes the MSF message.

Whenever MSF is to be used to process an E-mail message on a system, anMSF message must be created. The creator of the message on each of thesystems must first assemble the information that it wants kept. It passes thisinformation through MSF on that system to the MSF exit point programs. TheMSF message information is in the form of lists that are described in thischapter. Once these lists are built, an MSF message is created by mailapplications using the QzmfCrtMailMsg API. See Figure 27 on page 47.

46 AnyMail/400 MSF

Page 71: AnyMail/400 Mail Server Framework Developer Guide January 1995

Figure 27. How An MSF Message Is Created Using QzmfCrtMailMsg API

When an MSF message is created, the original information passed to theQzmfCrtMailMsg API is kept and never changed until the message is deleted.Exit point programs can use the Change Mail Message (QzmfChgMailMsg) API tochange the message content. However, the framework actually is allowing onlya copy of the message′s original information to be changed.

Each exit point program changes an MSF message and returns processingcontrol of that message to MSF. The changes to the already modified copy ofthe MSF message are then applied. It is this changed copy of the message thatis processed by any subsequent MSF exit point programs. It is as if the MSFmessage ′s information is constantly being overlayed by changes made by anexit point program. However, the original information is still there.

By keeping the originally created MSF message information, MSF supports theability to reset all messages as part of restarting the framework (see “StartingMSF” on page 29 for more information on the STRMSF command). When usingthe STRMSF MSGOPT(*RESET) command, the modified copy of every MSF messageknown to MSF is destroyed. The original message information that was kept bythe framework when each message was created is used to reset it. Theframework restarts processing for a reset message with the first exit pointprogram in the first exit point.

Chapter 5. Mail Server Framework Message 47

Page 72: AnyMail/400 Mail Server Framework Developer Guide January 1995

MSF Message Information Data TypesThe mail server framework uses the configured data types to identify theinformation in the lists of an MSF message. Most of the lists in an MSF messageuse a data type, such as an address type , to help exit point programs recognizewhat kind of information is in a list entry. Either the MSF message creator or theexit point programs that change the message set the information in the MSFmessage ′s list entries. When they do they set the data type values that identifythe information. The data types used in the message list entries must beconfigured.

For most MSF message lists, the data types present in the list entries are notused by the framework. The exception is the address types and message typesin the recipient list . These types are the key pieces of information. They areused by the framework when making decisions about calling exit point programsto process an MSF message. For more details on how the framework uses therecipient list data types, see “Typing of MSF Data” on page 5.

MSF Message Lists — OverviewThis section describes the lists contained in an MSF message and list entriesthat are combined to make up the information in an MSF message.

Each list description includes the following:

• A description of why it is defined.

• A description of what a list entry looks like, its structure, fields, and possiblevalues.

• An example of what a list with entries really looks like.

The lists and their entry formats are defined in terms of how they appear whenpassed across an MSF API.

If you are reading this for the first time, start with the recipient list, originator list,envelope list, and the attachment reference list because these play the majorpart in how an MSF message gets handled by the framework. Specifically, focuson the recipient list. Most exit point program functions use the information injust these four lists.

Notice how the framework structures the list information and the specific patternof how lengths and offsets are used both in the standard list header and theentries in a list. Once you understand this pattern for one of the lists, the otherswill be easier to understand.

Only the originator list, envelope list, and recipient list are required to create anMSF message. Additionally, most MSF messages have an attachment referencelist.

48 AnyMail/400 MSF

Page 73: AnyMail/400 Mail Server Framework Developer Guide January 1995

Overall Rules for MSF Message ListsThe following are some general rules about MSF message lists:

• For most lists, there is no limit to the number of entries. The exception is therecipient list which can have only 32767 possible entries.

• There are no empty lists. For example, should an MSF message not refer toan attachment, then there will be no attachment reference list.

• Any list can appear only once in any given message. For example, therecan be only one recipient list in each MSF message.

• The originator list, envelope list, and recipient list are required to create anMSF message. Every MSF message will have these three lists and at leastone entry in each list.

In addition to these three required lists, most MSF messages can beexpected to have an attachment reference list. However, the attachmentreference list and all the other lists described here are optional and may ormay not appear in any given MSF message.

• No list can be larger that 16MB. The total sum of the length of all the entriesin the list plus the length of the list header must be less than 16000000 bytes.MSF will not create a message that has a list longer than 16MB and will notallow a list to be extended beyond this limit by an exit point program.

• Exit point programs can add list entries and change the entires of most ofthese lists using the MSF QzmfChgMailMsg API that is provided for thatpurpose. Exit point programs cannot delete list entries except by changinginformation in a list entry so that it cannot be used by other exit pointprograms.

This could mean marking a recipient list entry with a status attribute so thatit would be ignored by other exit points. It could mean changing the datatype of a list entry so that it appears as something else to other exit pointprograms. For example, instead of deleting an entry in an attachmentreference list and adding a new one, an exit point program could replace theattachment list entry. It can do this by changing the list entry′s attachmentreference type and the data associated with the list entry using the ChangeMail Message API.

• Exit point programs can use the Change Mail Message API to add anoptional list with entries if that list does not already appear in the MSFmessage. For example, an MSF message could be created with noreferenced attachments and therefore have no attachment reference list . Anexit point program that processes that MSF message could still add a newattachment reference list with attachment references by using theQzmfChgMailMsg API.

Chapter 5. Mail Server Framework Message 49

Page 74: AnyMail/400 Mail Server Framework Developer Guide January 1995

MSF Message Lists Common HeaderAll MSF message lists share the same common header format. The headerindicates the kind of information that is in the list entries, the total number of listentries, the total length of the list and the offset to the first list entry. The list′sentries immediately follow the list header. The entries must be contiguous.

Figure 28. Common Header Format For A l l Lists

The following table shows the structure of the common list header that is usedfor all the MSF message lists. The entry format name in every list headeridentifies the type of list.

Table 9 (Page 1 of 2). Common List Header

Offset

Type FieldDec Hex

0 0 BINARY(4) Length of this MSF message list

4 4 BINARY(4) Reserved (set to zero)

8 8 CHAR(8) Message list entry format name (can be thought ofas an MSF list name)

16 10 BINARY(4) Offset of the first entry in the list

20 14 BINARY(4) Number of entries in this MSF list

50 AnyMail/400 MSF

Page 75: AnyMail/400 Mail Server Framework Developer Guide January 1995

For the equivalent definition using ILE* C/400*, see the typedefQzmf_Msg_Desc_Hdr0100 in Appendix F, “Qzmf Header File” on page 356.

Field Descriptions

Length of this MSF message list . The length in bytes of this message list. Themaximum length of a message list is 16 million bytes.

Message list entry format name . This field identifies the kind of entry in themessage list. It can be used to identify the content and format of the informationprovided for every entry in the list. The possible values are:

ORGL0100 Originator listENVL0100 Envelope listRCPL0100 Recipient listATTL0100 Attachment reference listORCL0100 Original recipient listRPYL0100 Reply-to address listROAL0100 Report-on address listRTAL0100 Report-to address listEXCH0100 Exit call history listRCHL0100 Recipient history list

Offset of the first entry in the list . The offset from the beginning of this listheader to the first entry in the list.

Number of entries in this MSF list . The number of entries in this MSF messagelist. Although all the entries will have the same list entry format, do not assumethat all the list entries are the same size. Most of the list entry formats allowvariable length information.

Reserved . All reserved fields are zero.

MSF message list area . One or more list entries follow the common header.MSF message lists have a common header and a list of entries. The format ofeach entry in a list can be determined by the message list entry format nameassociated with the list, which is located in the header. The number of listentries in the list area is also defined in the header.

Table 9 (Page 2 of 2). Common List Header

Offset

Type FieldDec Hex

24 18 BINARY(4) Reserved (set to zero)

* * CHAR(*) MSF message list area

Chapter 5. Mail Server Framework Message 51

Page 76: AnyMail/400 Mail Server Framework Developer Guide January 1995

Common List Entry FormatMost MSF message list entries have a common format that includes the length ofthe list entry, the displacement to its data (for example, an address, envelope, orattachment reference in the list entry), and the length of the data. Usually anMSF data type in the list entry identifies something about the data. For examplethe type of address or envelope that is in the list entry′s data.

Figure 29. Common List Entry Format.

Some lists such as the recipient list, report-on list, and the recipient history listhave a more complex format in that each list entry has two data areas. Theheaders for list entries that appear in these lists have a displacement to each ofthe two areas of that list entry′s data and a length of each area of data.

Mail applications must build the list entry format correctly. MSF exit pointprograms designed to use or change MSF message information in a list entrymust also correctly read or rebuild the list entries.

List Entry IDsMSF assigns a unique list entry ID to each entry in an MSF message list. Theframework does this when the list is created or a new entry is added by an exitpoint program. Each list entry is assigned an integer ID in an ascendingsequence. The list entry IDs are set by the framework and cannot be changedby exit point programs. When lists are passed by the framework to an exit pointprogram, the list entry IDs are passed to that exit point program as part of eachlist entry.

An exit point program can use the list entry IDs to request changes to a specificmessage list entry. The list entry ID allows an exit point program to indicate tothe MSF Change Mail Message API which entry (or entries) in a list the programwants to change.

52 AnyMail/400 MSF

Page 77: AnyMail/400 Mail Server Framework Developer Guide January 1995

List Entry Reference IDsList entry IDs can also be used to allow entries in an MSF message list to referto other list entries in the same list. Any exit point program that adds orchanges a list entry can specify the unique list entry ID of a different list entry .

A relationship can exist between two different entries in a list. One entry cancontain the list entry ID of another in the reference unique ID field. The list entrybeing referenced must already exist in the list when this relationship isestablished by the exit point program. MSF does not define the relationshipbetween the entries.

For example, if an exit point program adds an attachment reference thatrepresents the same information in a different format of another attachment, itcan establish a relationship between the new attachment and the oldattachment. The exit point program can use the reference ID field in the entrybeing added to the attachment reference list. Setting the reference ID to theunique ID of another attachment reference list entry is how it can indicate whennew attachment references are related to other attachments.

Note: Not all MSF message lists have reference ID fields defined for theirentries.

Originator ListThe originator list contains E-mail address of the message′s originator. ThisMSF message list is passed to or can be retrieved by all the MSF exit pointprograms.

The originator list is required for every MSF message.

An MSF exit point program would most likely use the originator list to identify thesource of an E-mail message when the program delivers it or forwards it. AnMSF exit point program could use the originating E-mail address to authorizemail coming from other networks. For logging and accounting purposes, exitpoint programs could also keep a record of the originators of E-mail messagesalong with some other information about a message.

Figure 30. MSF Message Originator List

Chapter 5. Mail Server Framework Message 53

Page 78: AnyMail/400 Mail Server Framework Developer Guide January 1995

Note: Although MSF allows multiple originators, most mail applications allowonly a single originator to be specified for each message. However, asshown in Figure 30, the message may have a list of originator addresses.This may occur when some mail application′s exit point program isindicating that there are aliases or equivalent E-mail addresses for amessage ′s originator.

Originator List EntryEach entry contains the address of an originator of the message.

Field Descriptions

Length of this entry . The length in bytes of this entry. This is used to get to thenext entry.

Displacement of the originator address from the beginning of this entry . Thedisplacement in bytes from the beginning of this entry to the originator addressin this entry.

Length of the originator address . The length of the originator address for thisentry. The maximum length of an originator address is 1024 bytes.

Address type . The type of originator address that is contained in the entry.

Originator address coded character set identifier (CCSID) . The CCSID that isprovided for the originator address. Valid values for the CCSID are 1 through65533 and 65535.

Unique identifier . An identifier that differentiates each entry within a particularlist. Identifiers are generated by MSF for each list entry either when the list iscreated or when list entries are added as the list is changed. List entries arenumbered such that unique identifiers are in ascending order.

Unique identifier of a referenced entry . The unique identifier of another entry inthis list to which this entry refers. You can use this when adding or changingentries in this list to create entry cross references. The most common exampleis to indicate that a list entry that is added to the list is a logical replacement ormapping of another list entry.

Offset

Type FieldDec Hex

0 0 BINARY(4) Length of this entry

4 4 BINARY(4) Displacement of the originator address from thebeginning of this list entry

8 8 BINARY(4) Length of originator address

12 C CHAR(4) Address type

16 10 BINARY(4) Originator address coded character set identifier(CCSID)

20 14 BINARY(4) Unique identif ier

24 18 BINARY(4) Unique identifier of referenced entry

28 1C BINARY(4) Reserved (set to zero)

* * CHAR(*) Originator address

54 AnyMail/400 MSF

Page 79: AnyMail/400 Mail Server Framework Developer Guide January 1995

Reserved . All reserved fields are set to zero.

Originator address . A string that represents the E-mail address associated withthe originator of the message. The contents and format of the string are notdefined by the mail server framework. The mail application defines the contentsof the originator address field.

Chapter 5. Mail Server Framework Message 55

Page 80: AnyMail/400 Mail Server Framework Developer Guide January 1995

Envelope ListAn envelope is a string of data that represents information about the messageother than the originator address, attachments, and recipients. Attributes of amessage such as its subject, priority, and error notification requirements arekept in its envelope(s). An envelope may contain the entire text for a shortE-mail message or a description (subject) of the E-mail message attachments.

The envelope list is required for every MSF message.

MSF allows for a list of envelopes as shown in Figure 31. You can have morethan one envelope, each identified by an envelope type. This allows the sameinformation about a single message to be repeated in different formats. It alsoallows specific information about a message that may appear in one envelopeformat to be ignored by all exit point programs that do not understand thatenvelope ′s format and content.

An MSF exit point program uses the information in an MSF message envelopefor the following reasons:

• To determine if it should treat the E-mail message differently. For example,looking for a priority or a request for notification of delivery .

• To look for supplemental attributes such as a subject or a reference thatmight be shown when the mail is displayed.

• To look for the E-mail message′s original creation or expiration dates .

• When an exit point program function is to take the attributes that it found inone of the MSF message envelopes and map it to another envelope format.

This exit point program is creating a new envelope. It attaches thatenvelope to the MSF message so that it is available to other exit pointprograms. This is done by changing the envelope list using theQzmfChgMailMsg API.

Note: MSF has a predefined generic envelope format called GET (genericenvelope type). See Appendix A, “Generic Envelope Type (GET)” onpage 228 for more information on GET and how it is used.

Figure 31. MSF Message Envelope List

56 AnyMail/400 MSF

Page 81: AnyMail/400 Mail Server Framework Developer Guide January 1995

Envelope List EntryEach entry contains a single envelope.

Field Descriptions

Length of this entry . The length in bytes of this entry. This is used to get to thenext entry.

Displacement of the envelope from the beginning of this list entry . Thedisplacement from the beginning of this entry to the envelope in this entry.

Length of the envelope . The length of the envelope that is contained in theentry.

Envelope type . The type of envelope.

Unique identifier . An identifier that differentiates each entry within a particularlist. Identifiers are generated by MSF for each list entry either when the list iscreated or when list entries are added as the MSF message is changed. Listentries are numbered such that unique identifiers are in ascending order.

Unique identifier of a referenced entry . The unique identifier of another entry inthis list to which this entry refers. You can use this when adding or changingentries in this list to create entry cross references. The most common exampleis to indicate that a list entry that is added to the list is a logical replacement ormapping of another list entry.

Reserved . All reserved fields are set to zero.

Envelope . A string of data that represents information about the message, asidefrom the attachments and its recipients.

Offset

Type FieldDec Hex

0 0 BINARY(4) Length of this entry

4 4 BINARY(4) Displacement of envelope from the beginning of thislist entry

8 8 BINARY(4) Length of envelope

12 C CHAR(4) Envelope type

16 10 BINARY(4) Unique identif ier

20 14 BINARY(4) Unique identifier of referenced entry

24 18 BINARY(4) Reserved (set to zero)

* * CHAR(*) Envelope

Chapter 5. Mail Server Framework Message 57

Page 82: AnyMail/400 Mail Server Framework Developer Guide January 1995

Recipient ListThe recipient list contains the E-mail addresses of the recipients of an E-mailmessage as shown in Figure 32 on page 59. The addresses represent where anE-mail message is going. The framework assumes that where an E-mailmessage is going implies the type of processing that is required to get theE-mail message to its final destination. MSF uses the recipient list entry datatypes to select the exit point programs that it calls.

The recipient list is required for every MSF message.

Exit point programs can use the recipient list in the following ways:

• When a recipient E-mail address is the name of a distribution list of E-mailaddresses. The exit point program′s function would be to determine that it isthe name of a distribution list of E-mail addresses.

If it is a distribution list, the program could change the MSF message′srecipient list to substitute the E-mail address that it recognized with the newlist of E-mail addresses.

• When a recipient′s E-mail address is to be mapped to another protocolformat when bridging from one protocol to another to reach that E-mailrecipient ′s destination system. The exit point program could use a directory,table, or a mapping algorithm to get the equivalent E-mail address.

The exit point program can change the recipient list to substitute the newE-mail address.

• When it needs to add information that is part of determining how an E-mailmessage gets to its recipients. For example, part of the function thatresolves an address of an E-mail message could be identifying if the addressis local to the exit point program′s system or if it represents a recipient onanother system in a network.

If the recipient is local, the exit point program might identify an in-basket ormail box object for the local user and add that object′s name to therecipient ′s list entry. If the recipient is not local, the exit point program couldidentify either the next system to forward the E-mail message to or the nameof a queue on which a copy of the message should be put to reach therecipient ′s system in the network.

MSF provides an area for this information that is provided for each recipientlist entry by exit point programs. It is called the entry′s SPIN data field.

• When an exit point program′s function is to deliver an E-mail messagerepresented by an MSF message locally or to forward it to another system.

If you change a recipient list entry′s E-mail address or change a recipient listentry ′s message type and/or status, an exit point program can activate other exitpoint programs that follow.

These cooperating exit point programs can be designed to act in combination asa complete mail application that will resolve the addresses of recipients, convertan E-mail message′s information (if required), and then deliver or forward thatE-mail message to its recipients.

In this way, a mail application links together its exit point programs at variousMSF exit points. The unifying factor is the MSF message′s recipient list entry′saddress or message data types for which the application′s exit point programs

58 AnyMail/400 MSF

Page 83: AnyMail/400 Mail Server Framework Developer Guide January 1995

are configured to be called. For additional information about how exit pointprograms are called, see “Determining the Exit Point Program to Call” onpage 16.

Figure 32. MSF Message Recipient List

A Recipient List Entry ′s MSF Data Types

The recipient list is the most important list in an MSF message. The addressand message MSF data types and the status value of the MSF message′srecipient list entries are the most important fields in the recipient list entry.The values of these fields are used by the framework to determine what exitpoint programs to call at the framework′s exit points.

Recipient List EntryEach list entry contains the address of one recipient of the message and otherinformation about that recipient.

Offset

Type FieldDec Hex

0 0 BINARY(4) Length of this entry

4 4 BINARY(4) Displacement to the SPIN from the beginning of thislist entry

8 8 BINARY(4) Length of exit point program (snap-in) providedinformation (SPIN)

12 C BINARY(4) Displacement of the recipient address from thebeginning of this entry

16 10 BINARY(4) Length of recipient address

20 14 CHAR(4) Address type

24 18 BINARY(4) Recipient address coded character set identifier(CCSID)

28 1C BINARY(4) Reason code

32 20 BINARY(4) Diagnostic code

36 24 CHAR(4) Message type

40 28 BINARY(4) Status

44 2C BINARY(4) Reserved (formerly used for Distribution Type - seeOriginal Recipient List)

48 30 BINARY(4) Unique identif ier

Chapter 5. Mail Server Framework Message 59

Page 84: AnyMail/400 Mail Server Framework Developer Guide January 1995

Field Descriptions

Length of this entry . The length in bytes of this entry. This is used to get to thenext entry.

Displacement to the SPIN from the beginning of this list entry . The displacementfrom the beginning of this entry to the exit point program (snap-in) providedinformation (SPIN).

Length of the exit point program (snap-in) provided information (SPIN) . Thelength in bytes of the exit point program provided information (SPIN). Themaximum length of the SPIN is 256 bytes.

Displacement of the recipient address from the beginning of this entry . Thedisplacement from the beginning of this entry to the recipient address in thisentry.

Length of the recipient address . The length of the recipient address for thisentry. The maximum length of a recipient address is 1024 bytes.

Address type . The type of recipient address.

Recipient address coded character set identifier (CCSID) . The CCSID providedfor the recipient address. Valid values for the CCSID are 1 through 65533 and65535.

Reason code . A code that identifies reasons that are associated with themessage delivery to this recipient. In the case of a non-delivered entry, this fieldcontains the reason the delivery of this message to this recipient failed. MSFassumes the reason code contains the X.400 non-delivery reason code.

The reason code and diagnostic code fields are assumed by MSF to containvalues that are documented in CCITT Data Communication Networks MessageHandling Systems 1988 Recommendation for X.400-X.420 for theNon-delivery-reason-code field and the Non-delivery-diagnostic-code field.

Diagnostic code . A code that indicates the cause of a problem where thedelivery of a message to this address failed. MSF assumes the diagnostic codecontains the X.400 non-delivery diagnostic code.

Message type . The type of message that is associated with the entry.

Status . The status that is associated with each recipient entry. This informationis used by the framework to determine which exit point is to be processedbetween local delivery, message forwarding and non-delivery. The possiblevalues are:

Offset

Type FieldDec Hex

52 34 BINARY(4) Unique identifier of referenced entry

56 38 BINARY(4) Reserved (set to zero)

* * CHAR(*) Recipient address

* * CHAR(*) Exit point program (snap-in) provided information(SPIN)

60 AnyMail/400 MSF

Page 85: AnyMail/400 Mail Server Framework Developer Guide January 1995

1 Forwarded (remote)2 Ignore3 Local4 Non-deliverable5 Security violation

Reserved (formerly used for Distribution Type) . All reserved fields are zero.

Note: The first reserved field was originally used to hold a distribution type. Thisattribute has been moved to the original recipient list.

Unique identifier . An identifier that differentiates each entry within a particularlist. Identifiers are generated by MSF for each list entry either when the list iscreated or when list entries are added as the MSF message is changed. Listentries are numbered such that unique identifiers are in ascending order.

Unique identifier of a referenced entry . The unique identifier of another entry inthis list to which this entry refers. You can use this when adding or changingentries in this list to create entry cross references. The most common exampleis to indicate that a list entry that is added to the list is a logical replacement ormapping of another list entry.

Recipient address . A string that represents the address associated with therecipient of the message. The contents and format of the string are not definedby the mail server framework. It is assumed that the address type associatedwith the recipient address defines the contents of the recipient address field.

Exit point program (snap-in) provided information (SPIN) . An area where exitpoint programs can store information that other exit point programs may use.SPIN provides a place where information relating to a specific recipient can bestored and used by exit point programs in the same or different exit points. Thisinformation is defined by the mail application that sets the SPIN information.

A common use of SPIN is when a specific type of attribute needs to be applied toa subset of the recipients of a message but the address, status, and messagetypes cannot be used. For example, a subset of the recipients of an E-mailmessage may be fanned out to sets of queues that are known to a messageforwarding exit point program. The subset of recipients that go onto the samequeue all have that queue name in common. The queue name could be put intotheir SPIN data by an address resolution exit point program to be used by amessage forwarding exit point program to distribute the E-mail message.

Chapter 5. Mail Server Framework Message 61

Page 86: AnyMail/400 Mail Server Framework Developer Guide January 1995

Attachment Reference ListEach entry in an attachment reference contains a reference to an attachmentthat is associated with an MSF message. This can be done either when themessage is created or by an exit point program that changed the message. MSFassumes that a message does not contain the attachments (for instancedocuments, bit maps, or video clips), but rather has this list of referencesassociated with the attachment. This attachment reference list identifies how thedata should be accessed as shown in Figure 35 on page 67.

The attachment reference list is optional.

MSF does not define the attachment reference formats or how they are to beused by creators of MSF messages or exit point programs in the framework.The attachment references can be any length. They could contain the methodthat is used to access the attachment content, or more information about anattachment (such as what type of data is in the referenced attachment or thesize of the information).

An MSF exit point program could use the information in one of the attachmentreferences for the following reasons:

• To determine how it should treat an E-mail message. The program′sfunction could be to look for a special kind of attachment reference thatindicates that the E-mail should be processed in a special way (such as amessage with no attachments).

• When an exit point program′s function could be to take the information foundin a referenced attachment and map it to another format.

In this situation, the exit point program creates another attachment. Theprogram can add a new attachment reference to the MSF message so that itis available to other exit point programs. This new attachment reference canbe added by changing the MSF message′s attachment reference list usingthe QzmfChgMailMsg API.

Figure 33. MSF Message Attachment Reference List

62 AnyMail/400 MSF

Page 87: AnyMail/400 Mail Server Framework Developer Guide January 1995

Attachment Reference List EntryThere is at least one list entry for each attachment of the MSF message.

Note: Some attachment list entries can reference the converted forms of otherattachments. If there are two entries in the list, it should not be assumedthat the E-mail has two different attachments.

Field Descriptions

Length of this entry . The length in bytes of this entry. This is used to get to thenext entry.

Displacement of the attachment reference from the beginning of this entry . Thedisplacement from the beginning of this entry to the attachment reference in thisentry.

Length of the attachment reference . The length of the attachment reference thatis contained in the entry.

Attachment reference type . The type of attachment reference. This specifies theformat of the attachment reference field.

Unique identifier . An identifier that differentiates each entry within a particularlist. Identifiers are generated by MSF for each list entry either when the list iscreated or when list entries are added as the MSF message is changed. Listentries are numbered such that unique identifiers are in ascending order.

Unique identifier of a referenced entry . The unique identifier of another entry inthis list to which this entry refers. You can use this when adding or changingentries in this list to create entry cross references. The most common exampleis to indicate that a list entry that is added to the list is a logical replacement ormapping of another list entry .

Reserved . All reserved fields are set to zero.

Attachment Reference . A string of data that represents information about amessage ′s attachment.

Offset

Type FieldDec Hex

0 0 BINARY(4) Length of this entry

4 4 BINARY(4) Displacement of the attachment reference from thebeginning of this entry

8 8 BINARY(4) Length of attachment reference

12 C CHAR(4) Attachment reference type

16 10 BINARY(4) Unique identif ier

20 14 BINARY(4) Unique identifier of referenced entry

24 18 BINARY(4) Reserved (set to zero)

* * CHAR(*) Attachment Reference

Chapter 5. Mail Server Framework Message 63

Page 88: AnyMail/400 Mail Server Framework Developer Guide January 1995

Original Recipient ListThis list contains the list of recipients that were specified when an applicationsent the original E-mail message. The recipient list represents the current list ofrecipients. The difference is that a mail application may modify this current listwhen it delivers or forwards the E-mail message.

The original recipient list is optional.

For example, an application could specify that a note be sent to two recipients.Both of these recipients appear in the recipient list and in the original recipientlist of the E-mail message. When that MSF message is processed, a copy of thenote is delivered to one of these recipients and a copy forwarded to the otherrecipient on another system in their network.

When the forwarded note reaches the next system, the MSF message recipientlist would have only one name in it. This would be the name of the recipient towhom that note was forwarded. The MSF message original recipient listhowever is expected to still have both of the original recipient names in it. Thisis to allow the recipient of the note to be able to see all of the original recipientsto whom the note was sent.

Exit point programs use the original recipient list when they provide a functionthat is part of delivering or forwarding an E-mail message. The program can usethe original recipient list of E-mail addresses so that it could copy them as partof delivering or forwarding the E-mail message′s information.

Because some E-mail protocols contain the original list of recipients as part ofthe text of a note or document, some exit point programs might attempt to usethis list when converting or building an attachment that would have a list oforiginal recipients in the new attachment′s text.

MSF allows a distribution type to be specified for each of the original recipients.The distribution type specifies if a recipient should be processed in a specificway when a message is delivered. For example, original recipients with adistribution type of CC (carbon copy) could be displayed when the message isread with a receiving mail application. Other original recipients with adistribution type of BCC (blind carbon copy) might not be displayed.

Note: MSF allows exit point programs to add entries to the original recipient list.This capability allows these programs to specify a mapped or alias E-mailaddress for entries in the list.

Figure 34. MSF Message′s Original Recipient List

64 AnyMail/400 MSF

Page 89: AnyMail/400 Mail Server Framework Developer Guide January 1995

Original Recipient List EntryEach entry contains the address of an original recipient of the message alongwith other information.

Field Descriptions

Length of this entry . The length in bytes of this entry. This is used to get to thenext entry.

Displacement of the original recipient address from the beginning of this entry .The displacement from the beginning of this entry to the original recipientaddress in this entry.

Length of the original recipient address . The length of the original recipientaddress for this entry. The maximum length of an original recipient address is1024 bytes.

Address type . The type of address that is contained in the entry. This specifiesthe format of the original recipient address field.

Original recipient address coded character set identifier (CCSID) . The CCSIDthat is provided for the original recipient address. Valid values for the CCSIDare 1 through 65533 and 65535.

Distribution type . The type of distribution that is associated with each originalrecipient entry. The possible values are:

0 Normal message recipient1 CC (carbon copy) recipient2 BCC (blind carbon copy) recipient

Reply requested flag . A flag that indicates whether this original recipient shouldreply to the message. The possible values are:

0 A reply is not requested from this original recipient1 A reply is requested from this original recipient

Offset

Type FieldDec Hex

0 0 BINARY(4) Length of this entry

4 4 BINARY(4) Displacement of the original recipient address fromthe beginning of this entry

8 8 BINARY(4) Length of the original recipient address

12 C CHAR(4) Address type

16 10 BINARY(4) Original Recipient address coded character setidentifier (CCSID)

20 14 BINARY(4) Distribution type

24 18 BINARY(4) Reply requested flag

28 1C BINARY(4) Unique identif ier

32 20 BINARY(4) Unique identifier of referenced entry

36 24 BINARY(4) Reserved (set to zero)

* * CHAR(*) Original Recipient address

Chapter 5. Mail Server Framework Message 65

Page 90: AnyMail/400 Mail Server Framework Developer Guide January 1995

Unique identifier . An identifier that differentiates each entry within a particularlist. Identifiers are generated by MSF for each list entry either when the list iscreated or when list entries are added as the MSF message is changed. Listentries are numbered such that unique identifiers are in ascending order.

Unique identifier of referenced entry . The unique identifier of another entry inthis list to which this entry refers. You can use this when adding or changingentries in this list to create entry cross references. The most common exampleis to indicate that a list entry that is added to the list is a logical replacement ormapping of another list entry.

Reserved . All reserved fields are set to zero.

Original recipient address . A string that represents the address associated withthe original recipient of the message. The contents and format of the string arenot defined by the mail server framework. MSF assumes that the address typeassociated with the original recipient address defines the contents of the originalrecipient address field.

66 AnyMail/400 MSF

Page 91: AnyMail/400 Mail Server Framework Developer Guide January 1995

Reply-to ListMSF messages allow for a list of specific E-mail addresses to which replies tothe message should be sent as shown in Figure 35. This list allows the creatorof a message to specify these addresses so that exit point programs can use thereply-to addresses in their functions.

The reply-to list is optional.

MSF exit point programs use the reply-to list when they provide a function that ispart of delivering or forwarding an E-mail message. For example, when a useris responding to the E-mail message, the recipient list could be built using thereply-to list.

Because some E-mail protocols contain the reply-to list in an E-mail message aspart of the text of a note or document, some exit point programs use this listwhen building an attachment. The attachment would have the list of reply-toE-mail addresses in the new attachment′s text.

Figure 35. MSF Message Reply-To List

Reply-to List EntryEach entry contains a reply-to E-mail address for the message.

Offset

Type FieldDec Hex

0 0 BINARY(4) Length of this entry

4 4 BINARY(4) Displacement of the reply-to address from thebeginning of this entry

8 8 BINARY(4) Length of reply-to address

12 C CHAR(4) Address type

16 10 BINARY(4) Reply-to address coded character set identifier(CCSID)

20 14 BINARY(4) Unique identif ier

24 18 BINARY(4) Unique identifier of referenced entry

28 1C BINARY(4) Reserved (must be set to zero)

* * CHAR(*) Reply-to address

Chapter 5. Mail Server Framework Message 67

Page 92: AnyMail/400 Mail Server Framework Developer Guide January 1995

Field Descriptions

Length of this entry . The length in bytes of this entry. This is used to get to thenext entry.

Displacement of the reply-to address from the beginning of this entry . Thedisplacement from the beginning of this entry to the reply-to address in thisentry.

Length of the reply-to address . The length in bytes of the reply-to address. Themaximum length of a reply-to address is 1024 bytes.

Address type . The type of address that is contained in the entry. This specifiesthe format of the reply-to address field.

Reply-to address coded character set identifier (CCSID) . The CCSID that isprovided for the reply-to address. Valid values for the CCSID are 1 through65533 and 65535.

Unique identifier . An identifier that differentiates each entry within a particularlist. Identifiers are generated by MSF for each list entry either when the list iscreated or when list entries are added as the MSF message is changed. Listentries are numbered such that unique identifiers are in ascending order.

Unique identifier of a referenced entry . The unique identifier of another entry inthis list to which this entry refers. You can use this when adding or changingentries in this list to create entry cross references. The most common exampleis to indicate that a list entry that is added to the list is a logical replacement ormapping of another list entry.

Reserved . All reserved fields are set to zero.

Reply-to address . A string which represents the address to be replied to. Thecontents and format of the string are not defined by the mail server framework.It is assumed that the address type associated with the reply-to address definesthe contents of the reply-to address field.

68 AnyMail/400 MSF

Page 93: AnyMail/400 Mail Server Framework Developer Guide January 1995

Report-to ListReports can be generated by exit point programs that process an MSF message.Although MSF does not generate reports it may call exit point programs thatmay do so as part of their functions. The report-to list is the way for a creator ofan MSF message to inform an exit point program where it should send thereports that it generates.

The report-to list is optional.

MSF exit point programs use the report-to list when their function involvescreating reports. For example, an exit point program that generates reports maybe configured to be called when non-delivery status recipients are in an MSFmessage ′s recipient list.

MSF exit point programs that forward MSF message information may need touse the report-to list if they have to forward the report-to E-mail addresses toanother system.

Note: The report-to list may seem like it is the same as the reply-to list. Thedifference between these two lists is when the E-mail addresses in eachlist are used by a mail application that handles an E-mail message. Areply-to list is used after an E-mail message is delivered and is beingreplied to by the recipient of the mail as part of the function of handlingthe delivered mail. Compare this to the report-to list that is used when areport about an E-mail message must be generated in route as themessage is processed by a mail application.

If there were no report-to addresses specified in the message, mostmessage applications are designed to send all reports that are generatedfor a message to the E-mail message′s originator by default.

Figure 36. An MSF Message Report-to List

Report-to List EntryEach entry contains an E-mail address that specifies where any reports (such asa non-delivery report) should be sent.

Offset

Type FieldDec Hex

0 0 BINARY(4) Length of this entry

Chapter 5. Mail Server Framework Message 69

Page 94: AnyMail/400 Mail Server Framework Developer Guide January 1995

Field Descriptions

Length of this entry . The length in bytes of this entry. This is used to get to thenext entry.

Displacement of the report-to address from the beginning of this entry . Thedisplacement from the beginning of this entry to the report-to address in thisentry.

Length of the report-to address . The length of the report-to address for thisentry. The maximum length of a report-to address is 1024 bytes.

Address type . The type of address that is contained in the entry. This specifiesthe format of the report-to address field.

Report-to address coded character set identifier (CCSID) . The CCSID that isprovided for the report-to address. Valid values for the CCSID are 1 through65533 and 65535.

Unique identifier . An identifier that differentiates each entry within a particularlist. Identifiers are generated by MSF for each list entry either when the list iscreated or when list entries are added as the MSF message is changed. Listentries are numbered such that unique identifiers are in ascending order.

Unique identifier of a referenced entry . The unique identifier of another entry inthis list to which this entry refers. You can use this when adding or changingentries in this list to create entry cross references. The most common exampleis to indicate that a list entry that is added to the list is a logical replacement ormapping of another list entry.

Reserved . All reserved fields are set to zero.

Report-to address . A string which represents the address to be reported to.The contents and format of the string are not defined by the mail serverframework. It is assumed that the address type associated with the report-toaddress defines the contents of the report-to address field.

Offset

Type FieldDec Hex

4 4 BINARY(4) Displacement of the report-to address from thebeginning of this RTAL0100 entry

8 8 BINARY(4) Length of the report-to address

12 C CHAR(4) Address type

16 10 BINARY(4) Report-to address coded character set identifier(CCSID)

20 14 BINARY(4) Unique identif ier

24 18 BINARY(4) Unique identifier of referenced list entry

28 1C BINARY(4) Reserved (set to zero)

* * CHAR(*) Report-to address

70 AnyMail/400 MSF

Page 95: AnyMail/400 Mail Server Framework Developer Guide January 1995

Report-on ListMSF provides the report-on list for mail applications that generate E-mail reportsas part of their functions. E-mail reports are messages that are generated bythe mail application . This is used to report the delivery or non-delivery of anE-mail message. The report could be sent to the originator of the E-mailmessage or another E-mail address specified in the report-to list.

The report-to list is optional.

A mail application could create MSF messages with report-on lists when theapplication is trying to identify that the MSF message was a report. Thereport-on list is used to indicate to exit point programs which recipients of anE-mail message are being reported on. This is how the mail application caninform the originator which recipients did not receive the message and why.

An MSF exit point program uses report-on lists when that program′s function isto deliver or forward reports on E-mail back to the E-mail′s originators orreport-to E-mail addresses.

Note: Programs that create MSF messages that are reports may be MSF exitpoint programs that are invoking the QzmfCrtMailMsg API to create areport on another MSF message.

Figure 37. An MSF Message Report-on List

Report-on List EntryEach list entry contains a recipient address that is being reported-on, the reasonthat it is being reported-on, and any other information that might be applicableabout the report for that address.

Offset

Type FieldDec Hex

0 0 BINARY(4) Length of this entry

4 4 BINARY(4) Displacement of the snap-in provided information(SPIN) from the beginning of entry

8 8 BINARY(4) Length of snap-in provided information (SPIN)

12 C BINARY(4) Displacement of the report-on address from thebeginning of this entry

16 10 BINARY(4) Length of the report-on address.

Chapter 5. Mail Server Framework Message 71

Page 96: AnyMail/400 Mail Server Framework Developer Guide January 1995

Field Descriptions

Length of this entry . The length in bytes of this entry. This is used to get to thenext entry.

Displacement of the snap-in provided information (SPIN) of this entry . Thedisplacement from the beginning of this entry to the snap-in provided information(SPIN).

Length of the snap-in provided information (SPIN) . The length in bytes of thesnap-in exit program provided information (SPIN). The maximum length of theSPIN is 256 bytes.

Displacement of the report-on address from the beginning of this entry . Thedisplacement from the beginning of this entry to the report-on address in thisentry.

Length of the report-on address. . The length in bytes of the report-on address.The maximum length of a report-on address is 1024 bytes.

Address type . The type of address that is contained in the entry. This specifiesthe format of the report-on address field.

Report-on address coded character set identifier (CCSID) . The CCSID that isprovided for the report-on address. Valid values for the CCSID are 1 through65533 and 65535.

Reason code . A code that identifies reasons associated with the messagedelivery to this address. The code indicates the reason the report-on address isgetting reported on. In the case of a non-delivery entry, this field would containthe reason the delivery of this message to this recipient failed. MSF assumesthe reason code contains the X.400 non-delivery reason code.

The reason code and diagnostic code fields are assumed by MSF to containvalues that are documented in CCITT Data Communication Networks MessageHandling Systems 1988 Recommendation for X.400-X.420 for the fieldsNon-delivery-reason-code and Non-delivery-diagnostic-code.

Diagnostic code . A code that indicates the cause of a problem where thedelivery of a message to this address failed and a report is to be generated.

Offset

Type FieldDec Hex

20 14 CHAR(4) Address type

24 18 BINARY(4) Report-on address coded character set identifier(CCSID)

28 1C BINARY(4) Reason code

32 20 BINARY(4) Diagnostic code

36 24 BINARY(4) Unique identif ier

40 28 BINARY(4) Unique identifier of referenced entry

44 2C BINARY(4) Reserved (set to zero)

* * CHAR(*) Report-on address

* * CHAR(*) Snap-in provided information (SPIN)

72 AnyMail/400 MSF

Page 97: AnyMail/400 Mail Server Framework Developer Guide January 1995

MSF assumes the diagnositc code contains the X.400 nondelivery diagnosticcode.

Unique identifier . An identifier that differentiates each entry within a particularlist. Identifiers are generated by MSF for each list entry either when the list iscreated or when list entries are added as the MSF message is changed. Listentries are numbered such that unique identifiers are in ascending order.

Unique identifier of a referenced entry . The unique identifier of another entry inthis list to which this entry refers to. You can use this when adding or changingentries in this list to create entry cross references. The most common exampleis to indicate that a list entry that is added to the list is a logical replacement ormapping of another list entry.

Reserved . All reserved fields are set to zero.

Report-on address . A string which represents the address to be reported on.The contents and format of the string are not defined by the mail serverframework. It is assumed that the address type associated with the report-onaddress defines the contents of the report-on address field.

Snap-in provided information (SPIN) . An area where exit point programs canstore information that other exit point programs may use. SPIN provides a placewhere information that relates to a specific recipient can be stored and used byexit point programs in the same or different exit points. This information isdefined by the mail applications that set the SPIN information. In the report-onlist entry, the SPIN field allows specific information about the condition that isbeing reported for each recipient address.

Chapter 5. Mail Server Framework Message 73

Page 98: AnyMail/400 Mail Server Framework Developer Guide January 1995

Exit Point Call History ListAn exit point call history list is created by the framework for every MSFmessage. It can be updated only by MSF when the framework processes theMSF message. However, an exit point program can retrieve this informationusing the Retrieve Mail Message API.

As MSF processes an MSF message, it keeps track of every exit point programthat it calls. This is to allow exit point programs to use this history of exit pointprograms that are called for an MSF message in performing their functions.

The exit point call history is useful information when tracing which exit pointprograms have been triggered by MSF and changed an MSF message. The exitpoint call history list can also be helpful when you debug or test how a new exitpoint program is interacting with other exit point programs.

An exit point call history list entry contains both the time that an exit pointprogram was called and when it returned. This information could be used in anexit point program designed to track how much time was spent in each MSF exitpoint program that is called when processing an MSF message.

Every list entry has an indicator that is set by the framework when an exit pointprogram changes MSF message information.

The exit point call history list should be considered to be dynamic. When youdesign exit point programs that use the list′s information you should be awarethat it will continue to be updated. It is possible that more MSF exit pointprograms will be called as the MSF message continues to be processed by theframework after the program that uses the history list returns control to theframework.

Note: The exit program history is not reset for MSF messages when the STRMSFOPTION(*RESET) command is used to reset all MSF messages. The exitprogram history list is cumulative in that it continues to record which exitprograms are called when the message is processed again by MSF.

The mail server framework makes a special entry in the exit pointprogram history list whenever a reset of a message is done using theSTRMSF command. This allows MSF exit point programs to detect thatan MSF message was reset.

Figure 38. MSF Message Exit Program History List

74 AnyMail/400 MSF

Page 99: AnyMail/400 Mail Server Framework Developer Guide January 1995

Exit Point Call History List EntryEach entry contains information about an exit point program that was called toprocess the MSF message.

Field Descriptions

Mail server framework exit point name . The MSF exit point name from which theexit point program was called (for example, QIBM_ZMFMSF_LSTEXP for listexpansion).

Mail server framework exit point program name . The name of the program thatwas called at the mail server framework exit point.

Mail server framework exit point program library . The library name containingthe program that was called at the mail server framework exit point.

Exit point program number . A number assigned to the exit point program whenit is registered at an MSF exit point using the registration facility. This is thenumber in effect at the time the program was called.

Timestamp of when the exit point program was called . The format of thistimestamp is the same as that of the timestamp of when the message wascreated. See “GET Date/Time GMT Structure” on page 239 for additionalinformation on this format.

Timestamp of when the exit point program returned . The format of thistimestamp is the same as that of the timestamp of when the message wascreated.

Return code from the exit point program . The return code returned by the userexit point program.

Change indicator . An indicator of whether processing of the exit point programresulted in changes to the message.

0 There were no changes to the message as a result of this exit pointprogram being called.

1 There were changes to the message as a result of this exit pointprogram being called.

Offset

Type FieldDec Hex

0 0 CHAR(20) Mail server framework exit point name

20 14 CHAR(10) Mail server framework exit program name

30 1E CHAR(10) Mail server framework exit program library

40 28 BINARY(4) Exit program number

44 2C CHAR(16) Timestamp of when the exit program was called

60 3C CHAR(16) Timestamp of when the exit program returned

76 4C BINARY(4) Return code from the exit program

80 50 CHAR(1) Change indicator

81 51 CHAR(3) Reserved (set to blanks)

Chapter 5. Mail Server Framework Message 75

Page 100: AnyMail/400 Mail Server Framework Developer Guide January 1995

Recipient History ListA recipient history list is created by the framework for every MSF message. Itcan be updated only by MSF as the framework processes the MSF message.However, an exit point program can retrieve the information using the retrieveAPI.

An MSF exit point program uses the recipient history list when it needs todetermine how other exit point programs have already changed the recipient list.For example, an exit point program could log the recipients of every E-mailmessage processed by MSF and to show either when a recipient address wasmapped to another address or was expanded to a list of E-mail addresses. Arecipient history list can be useful in a program designed to help debug or testother exit point programs.

Figure 39. An MSF Message Recipient History List

Recipient History List EntryEach list entry contains the address of a recipient of the MSF message, includingthose recipients that were substituted for a new name or list of names. Each listentry refers to the unique identifier of its parent entry that it replaced. If theparent ′s unique identifier is zero, then the recipient address was specified by thecreator of the MSF message.

Offset

Type FieldDec Hex

0 0 BINARY(4) Length of this entry

4 4 BINARY(4) Displacement of the snap-in provided information(SPIN) of this entry

8 8 BINARY(4) Length of snap-in provided information (SPIN)

12 C BINARY(4) Displacement of the recipient address from thebeginning of this entry

16 10 BINARY(4) Length of recipient address

20 14 CHAR(4) Address type

24 18 BINARY(4) Recipient address coded character set identifier(CCSID)

28 1C CHAR(4) Message type

32 20 BINARY(4) Status

76 AnyMail/400 MSF

Page 101: AnyMail/400 Mail Server Framework Developer Guide January 1995

Field Descriptions

Length of this entry . The length in bytes of this entry. This is used to get to thenext entry.

Displacement of the snap-in provided information (SPIN) of this entry . Thedisplacement from the beginning of this entry to the snap-in provided information(SPIN).

Length of the snap-in provided information (SPIN) . The length in bytes of thesnap-in provided information (SPIN). The maximum length of the SPIN is 256bytes.

Displacement of the recipient address from the beginning of this entry . Thedisplacement from the beginning of this entry to the recipient address in thisentry.

Length of the recipient address . The length in bytes of the recipient address.The maximum length of a recipient address is 1024 bytes.

Address type . The type of address that is contained in the entry. This specifiesthe format of the recipient address field.

Recipient address coded character set identifier (CCSID) . The CCSID that isprovided for the recipient address. Valid values for the CCSID are 1 through65533 and 65535.

Message type . The type of message that is associated with the entry.

Status . The status associated with each recipient entry. The possible valuesare:

1 Forwarded (remote)2 Ignore3 Local4 Non-deliverable5 Security violation

Distribution type . The type of distribution associated with each recipient entry.The possible values are:

0 Normal message recipient1 CC (carbon copy) recipient2 BCC (blind carbon copy) recipient

Offset

Type FieldDec Hex

36 24 BINARY(4) Distribution type

40 28 BINARY(4) Unique identif ier

44 2C BINARY(4) Recipient status flag

48 30 BINARY(4) Unique identifier of parent entry

52 34 BINARY(4) Reserved (set to zero)

* * CHAR(*) Recipient address

* * CHAR(*) Snap-in provided information (SPIN)

Chapter 5. Mail Server Framework Message 77

Page 102: AnyMail/400 Mail Server Framework Developer Guide January 1995

Unique identifier . An identifier that differentiates each entry within a particularlist. Identifiers are generated for each list entry when the Create Mail Message(QzmfCrtMailMsg) API has successfully completed. These unique identifiers aretemporary and may change as the mail service processes a message. Listentries are placed in message descriptors such that unique identifiers are inascending order.

Recipient status flag . A flag which indicates whether or not this entry has beenreplaced by either one or multiple entries. Entries with this flag set to 1 arereferred to as parents. Entries with this flag set zero are referred to as children.

Unique identifier of the parent entry . The unique identifier associated with theparent entry of this entry. A parent entry is an entry that had been replaced by asingle or multiple entries. If this field is zero, then this entry was specified whenthe message was created.

Reserved . All reserved fields are set to zero.

Recipient address . A string that represents the address associated with arecipient of the message. The contents and format of the string are not definedby the mail server framework. It is assumed that the address type associatedwith the recipient address defines the contents of the recipient address field.

Snap-in provided information (SPIN) . An area where exit point programs canstore information that other exit point programs may use. SPIN provides a placewhere information relating to a specific recipient can be stored and used by exitpoint programs in the same or different exit points. This information is definedby the mail applications that set the SPIN information.

System Considerations for MSF MessagesThe MSF message has two representations, external and internal. The externalrepresentation of the message is important to you as a creator or user of theMSF message content and is the one that is described in this book. This is whythe MSF message is defined in terms of the structures that are passed acrossthe MSF APIs when a message is created (QzmfCrtMailMsg), changed(QzmfChgMailMsg), or retrieved (QzmfRtvMailMsg). When using the MSFframework, these structures are the MSF message.

There is an internal implementation to support the external image. This is anencapsulated form of the MSF message that is described is this book. MSFmessage contents are kept in internal OS/400 system space objects that areprotected from access except through the MSF APIs. These system objects andformats are not documented externally. They are mentioned here only to makesure that the external versus internal nature of MSF messages is understood andthat there are OS/400 system considerations, actions, or functions that might beperformed that affect these implementation objects that contain the MSFmessage information.

Following are some system considerations related to how the internal spaceobjects are used by MSF:

• All the internal space objects that MSF uses to store MSF messages are inthe QUSRSYS library. If that library is ever cleared, all MSF messages aredeleted.

78 AnyMail/400 MSF

Page 103: AnyMail/400 Mail Server Framework Developer Guide January 1995

• All the internal space objects that MSF uses to store MSF messages arepermanent system objects. They are not deleted due to a system IPL(normal or abnormal) or due to an installation of OS/400.

• All the internal space objects used by MSF are owned by the QMSF userprofile. To determine the amount of space used by the system for MSFmessages, you can display the amount of storage owned by the QMSF userprofile.

• The internal space objects that are used are pooled. They are allocatedfrom a pool of space objects maintained by the framework to store MSFmessage information temporarily. When the framework determines that itshould delete the MSF message, it recycles the system space objects usedfor that message back to the pool so that they can be reused to storeanother MSF message.

This pool of spaces grows larger if the number of MSF messages that existat the same time grows. As the backlog of MSF messages grows, thenumber of spaces in the pool grows. This is because more spaces will becreated by the framework once the pool of unused spaces is exhausted.

These spaces are eventually returned to the pool as the messages aredeleted. This could leave a very large number of available spaces in thepool. To reduce the number of unused spaces in the pool, use the ReclaimStorage (RCLSTG) command.

• The space objects that MSF uses to store MSF messages cannot be saved.When you perform a save of the system, MSF messages currently existing onthat system are not saved. MSF messages that were created on one systemcannot be restored onto another system.

As a designer of exit point programs or a creator of MSF messages, you may notbe concerned with these behaviors. However, if you test or support thesefunctions, you should be aware of some of the side effects of the internal systemobjects used.

Chapter 5. Mail Server Framework Message 79

Page 104: AnyMail/400 Mail Server Framework Developer Guide January 1995

Chapter 6. Mail Server Framework Exit Points

This chapter contains information on the MSF exit points and exit pointprograms. It covers some of the same material presented in Chapter 2, “MailServer Framework Concepts” on page 3, but in more detail. It also describesthe basic behavior of MSF in regards to how and when the framework calls exitpoint programs when processing a message.

Included in this chapter are descriptions of the following:

• How MSF decides when to call exit point programs at the various MSF exitpoints.

• How MSF decides which exit point programs to call and how an exit pointprogram ′s configuration affects this decision.

• The kinds of information in an MSF message that is passed to theseprograms based on the exit point program configuration and the MSF exitpoint.

• Restrictions that MSF imposes on an exit point program′s ability to changean MSF message′s information.

• How MSF controls when changes to an MSF message made by an exit pointprogram take effect.

MSF Exit Points Versus Snap-in Exit PointsMSF has defined twelve exit points. Of the twelve, there are ten that aredescribed here as “snap-in” exit points. The exit point programs configured inthese ten exit points are sometimes referred to as snap-ins.

These ten exit points are the ones where you can register the programs to becalled by MSF that are part of your mail applications.

Figure 40 on page 81 shows the ten snap-in exit points in the order that MSFuses when processing a message. When describing them, the ten snap-in exitpoints are collected into four groups.

• Addressing• Pre-delivery processing• Delivery• Management

These groups of exit points are described in Chapter 2, “Mail Server FrameworkConcepts” on page 3.

80 Copyright IBM Corp. 1995

Page 105: AnyMail/400 Mail Server Framework Developer Guide January 1995

Figure 40. MSF Exit Points and Exit Point Programs

Note: The two non snap-in exit points, QIBM_QZMFMSF_TRK_CHG (Track MailMessage Changes) and QIBM_QZMFMSF_VLD_TYP (Validate Data Field),are not shown in Figure 40. They are defined by the framework forspecial purposes. These are described in “Special Exit Points” onpage 123.

Chapter 6. Mail Server Framework Exit Points 81

Page 106: AnyMail/400 Mail Server Framework Developer Guide January 1995

OS/400 Registered Exit Points

If you are not familiar with the registered exit point concept, a simplifiedexplanation is that there are named places, called exit points, where you canregister (configure) programs, called exit point programs. You can see andconfigure these programs by using the Work with Registered Information(WRKREGINF) command.

OS/400 maintains a list of exit points known to the system. It providesinterfaces and objects that keep this information about which exit pointprograms are registered at what exit points on your system.

MSF uses this exit point registration function to configure the programs itcalls when processing MSF messages. MSF has defined its own exit points.Programs registered at each MSF exit point are assumed by MSF to be partof a mail application interested in processing MSF messages.

When MSF is started by using the STRMSF command, MSF will look at allMSF exit points and determine what programs are registered. By registeringa program at one of the MSF exit points, you can snap-in a program that canperform its function on the message the framework is processing.

Considerations for MSF Exit Point Program DesignersMSF is effectively a collection of exit points. The framework′s primary function isto sequentially examine these exit points and control what exit point programs tocall. As far as MSF is concerned, the exit point programs do all the work.

When designing exit point programs that are part of a mail application, youshould not forget that your mail application could be considered part of OS/400by the users of MSF. You must consider how your programs behave regardingother mail applications, to the framework, and OS/400 as a whole.

As a mail application designer, here are some things to think about whendesigning your exit point programs:

PerformanceMSF is not concerned with the work that the exit point programs actually dowhen it calls them. However, because it is calling these programs theframework is concerned that the programs return processing control as soon aspossible.

As an exit point program designer, you have to remember the functions yourprograms do are normally only part of the overall system function of processingmail. You always want the system MSF mail function to process its messages asfast as possible. Your programs are more valuable if the framework calls themmore frequently since they are doing their functions more often.

Your MSF exit point programs should not wait indefinitely for some other processor resource. The effect of any exit point program waiting is that the QMSF jobthat is calling the program also waits. While the QMSF job waits, more MSFmessages are being created and queued by other processes. The waiting QMSFjob is not available to process these other messages and a backlog of messagesdevelops.

82 AnyMail/400 MSF

Page 107: AnyMail/400 Mail Server Framework Developer Guide January 1995

For example, your exit point programs should not send a reply message to asystem operator and wait for a reply to that message. You should be carefulwhen using other functions that might do similar things.

Reentrant programmingMSF is designed so its impact on a system is scalable. The number of QMSFjobs that perform its function can be specified on the Start Mail ServerFramework (STRMSF) command. A system administrator can control how muchsystem resource MSF uses by starting any number of QMSF jobs.

As a designer of an MSF mail application, you have to be aware that theframework assumes that all exit point programs can be called at any time fromany one of the QMSF jobs. Therefore, your exit point programs must bedesigned to be reentrant.

For example, if you are designing an exit point program that creates a userspace in your OS/400 library as a working space, your design must allow anynumber of copies of your program to run at the same time. Therefore, the spacecreation segment of your program needs to generate a unique name becausemore than one user space object may be created in your library.

E-Mail SecurityMSF and its exit point programs are available to any program that creates anMSF message. This means that your mail application will be possibly handlingE-mail messages created by any number of applications for any number ofreasons. Your exit point programs will be considered a part of MSF. They willbe considered part of the system support for E-mail. Users of that support willassume that the security of the information they send in their E-mail extends tothe programs you are designing.

You must consider the security of MSF message information that your exit pointprograms may use or copy. Your design needs to allow for the protection of anyobject where your program might copy any information, even if it is only atemporary location , such as a user space object.

Whenever you save any kind of E-mail message information for the purposes ofhelping diagnose errors, you must consider that this is considered copyingE-mail message information. You must therefore protect its confidentiality.

Error HandlingAs a designer of mail applications, you have to consider the errors your programmay encounter. How does your program handle those errors? Part of your mailapplication′s value is how well it handles errors.

It may help to consider errors as being in separate “classes.”

One class of errors are those that occur due to how your program uses themessage ′s information. As designer, you have many options regarding howyour programs will handle these kind of errors. The more fault tolerant your exitpoint programs are, the better.

MSF has designed ways that a mail application can change an MSF message toindicate that a recipient has a non-deliverable status. It also allows recipients tobe given a status of ignore. When you consider error handling, consider how to

Chapter 6. Mail Server Framework Exit Points 83

Page 108: AnyMail/400 Mail Server Framework Developer Guide January 1995

best use these and other options when MSF message information causes anerror in your program.

For example, if your program is designed to look up a recipient′s E-mail addressto determine the name of their mailbox object. How does your program handlethe event that the address cannot be found? It may be better to have theprogram change that recipient′s list entry to have a non-deliverable status thanto simply signal the framework that your program has failed.

Another class of errors are design or coding errors. These kinds of errorsshould be handled by recording what kinds of information will be helpful indiagnosing the errors and servicing your mail application′s programs. Your mailapplication design should consider what kind of notification of failure isappropriate. Should a message be sent to the QMSF job log? How aboutsending messages to the system operator or network help desk?

An example of this kind of error is a program that calls the QzmfChgMailMsg APIbut does not always build the API parameter information correctly. This is acoding error. When QzmfChgMailMsg fails, MSF signals an error message orreturns a failure return code back to the calling program. If your design includesa call to QzmfChgMailMsg, you need to consider how your program handles thiserror. What kind of information could your program save that will help diagnosethis kind of error? Will it signal its own error message to the job log? How willit let MSF know that it failed?

Note: By signalling an exception to the calling framework, setting the returncode to a non-zero value, or simply failing due to any unmonitoredexception, a mail application can cause the QMSF job to end. Analertable message, CPFAF95, will be sent to the QSYSOPR messagequeue by MSF whenever this happens.

Interaction with Other Exit Point ProgramsAs a designer of mail applications you have to consider how an exit pointprogram may interact with other programs in the exit point. If your application ismade up of more than one exit point program you must also consider how thecollection of programs behaves as a whole . Do they work correctly in thesequence that they are called to provide your mail application functions? Whatmight be the impact of other exit point programs in this sequence to your mailapplication?

You can simplify this design problem. Exit point programs should be designedand configured to handle only those MSF messages that have specific MSFaddress types or message types. This allows the exit point data that is part ofthe program ′s configuration to help reduce the complexity of the program. Theprogram can assume that if it is called by MSF then there are recipient listentries with its configured types.

The problem of figuring out how exit point programs interact can be furthersimplified if it is the only exit point program configured at an exit point for aspecific data type. The program can assume that if it is not called by MSF, thereare no recipient list entries with its configured types1 .

1 As described in this chapter, the order that exit point programs are configured is important to MSF, not just what kind of datatypes are configured in their program data.

84 AnyMail/400 MSF

Page 109: AnyMail/400 Mail Server Framework Developer Guide January 1995

MSF Message Information and Exit Point ProgramsThe framework is primarily concerned with supporting E-mail applicationfunctions that are implemented in the configured exit programs called MSF exitpoint programs. To do this, it has to allow information in an MSF message to beavailable to the exit point programs. In order to understand the behavior of exitpoint programs and how to construct an exit point program, it is important youunderstand a basic premise of the MSF framework: Exit point programs are notpassed MSF messages but rather they are passed a copy of the MSF messageinformation .

When an MSF message is created and handed to the framework, the creatordefines the initial information. This initial information is encapsulated insideinternal system objects known only to the framework. As the frameworkprocesses an MSF message it reaches some point where it determines that itshould call an exit point program and give it some information about themessage.

At that point the framework transforms the internal MSF message into theexternal MSF message image described in Chapter 5, “Mail Server FrameworkMessage” on page 44. The framework creates its own user spaces to hold thisinformation. It is this external form, a copy of the MSF message information inuser space objects, that is passed to the exit point programs. Exit pointprograms are never given access to the encapsulated message. (Chapter 15,“Snap-In Call Exit Point Interface” on page 197 documents the interface fromMSF to the exit point programs.)

Exit point programs configured in certain MSF exit points are allowed to changethe MSF message information, but in order to do so these exit programs have touse the MSF QzmfChgMailMsg API. This is a request that MSF modifies theencapsulated form of the message information in some way.

For efficiency′s sake, the framework passes only some of the lists that make upthe external form of message information every time it calls an exit pointprogram configured at one of its exit points. Which of the message′s lists arepassed on the call to an exit point program varies with the MSF exit point. Forexample only the MSF message′s recipient list is passed by the framework whenit calls a program configured as a List Expansion exit point program. Howeverall the information in the encapsulated message is available to every exit pointprogram once it has been called.

Exit point programs can use the QzmfRtvMailMsg API provided by the frameworkto retrieve information about an MSF message that they were not automaticallypassed by the framework when they were called. Again, when an exit pointprogram uses this API to request message information, the framework constructsan external copy of the encapsulated information. The framework expects thecalling program to pass the names of the user spaces in which it should copythis information. A program using the QzmfRtvMailMsg API will not be returneddirect access to the encapsulated MSF message.

Chapter 15, “Snap-In Call Exit Point Interface” on page 197 documents theinterface from MSF to the exit point programs.

Chapter 6. Mail Server Framework Exit Points 85

Page 110: AnyMail/400 Mail Server Framework Developer Guide January 1995

Basic Design of Exit Point Programs

Figure 41. MSF Exit Point Programs Do Two Things

As shown in Figure 41, as far as MSF is concerned, exit point programs exist todo only two things:

1. They use an MSF message information or copy all or some of thatinformation someplace else to be used later.

2. They change the MSF message information by using the QzmfChgMailMsgAPI.

All MSF exit point programs are simply further extensions of one or both of thesebasic functions.

Every MSF exit point program′s initial design can be started with one or both ofthese functions.

86 AnyMail/400 MSF

Page 111: AnyMail/400 Mail Server Framework Developer Guide January 1995

Multiple Exit Point ProgramsAs Figure 42 shows, MSF allows for multiple exit point programs (up to 1024) tobe configured for any one of the ten snap-in exit points. This section describeshow MSF determines which exit point programs to call when there is more thanone exit point program configured at an exit point.

Figure 42. Multiple Exit Point Programs per Exit Point

Determining Which Exit Point Program to CallThink of MSF as taking an MSF message past each of the ten exit points while itis processing that message. At each exit point the framework has to evaluate ifit should call any exit point programs. If there is more than one exit pointprogram it has to decide which programs to call.

Basically MSF will call the first exit point program that is configured that meetsthe criteria it uses for that exit point. Different exit points are evaluated indifferent ways but the framework always uses two key pieces of information todecide which exit programs to call to process an MSF message:

1. The MSF data types used in the exit program data of the configured exitpoint programs.

When you configure an MSF exit point program, you can specify MSF datatypes in the exit program data. That program will only be called when anMSF message has entries in its recipient list that have data types that matchthose in the exit point data.

Figure 43. MSF Data Types Used in Exit Point Configuration

Figure 43 shows an MSF exit point, QIBM_QZMFMSF_ADR_RSL (1)configured with an exit point program, QSYS/QZDSNPAD (2). The exitprogram data is SPCL010001A101A201A3 (3). The MSF data types in this exitprogram data are 01A1, 01A2, and 01A3 . This tells the framework to only callthis program when processing an MSF message with these data types in itsrecipient list AND that it only wants to be passed the entries that have one ofthese three types.

Chapter 6. Mail Server Framework Exit Points 87

Page 112: AnyMail/400 Mail Server Framework Developer Guide January 1995

2. The MSF data types and status in MSF message ′s recipient list entries.

Figure 44. Recipient List Data Types Matched to Exit Program Data

Figure 44 shows how the MSF message data types in the message recipientlist are used to determine which programs to call.2

When MSF has decided to call an exit program it will subset the recipient list. Itpasses only those recipient list entries that have data types that match the typesfound in the exit program data. (This is explained again using a detailedexample in the next section.)

How does the framework call more than one exit point programs in an exit point?To understand how this works consider what happens when recipient list entrieshave data types that do not match the ones configured for the first programcalled. MSF will not pass these recipient list entries to that exit point program.

When the first program called returns, the framework reevaluates the recipientlist entries. This time it considers only those entries that it did not pass to thefirst program. It checks the next exit point program′s exit data to determine ifany of the remaining list entries have a data type that matches. If any match,then MSF will call that program.

This data type evaluation and call cycle continues for every exit point until one ofthe following occurs:

• All the recipient list entries have been passed to at least one exit pointprogram.

2 At times the recipient list entry status field is also used as explained in “How MSF Uses Recipient List Status” on page 110.

88 AnyMail/400 MSF

Page 113: AnyMail/400 Mail Server Framework Developer Guide January 1995

• All the exit point programs configured at an exit point have been evaluated.

When either one of these criteria are met, the data type evaluation and call cycleends for that exit point and MSF moves onto the next exit point and starts thecycle again.

Exit point programs themselves can control if another exit point programconfigured next in the same exit point should be called to process a message.Exit point programs can control how MSF′s data type evaluation and call cycleworks by using a special kind of invocation of the QzmfChgMailMsg API called a“put back.” See “Using QzmfChgMailMsg to Put Back Recipients” on page 95for a detailed example on how this works.

Note: Just as it is possible to have multiple exit point programs configured at anMSF exit point it is also possible to have no exit point programsconfigured for a given MSF exit point. An example is that MSF definesten exit points but not all are preconfigured by the system with exit pointprograms.

MSF is not aware of what configured exit point programs do with an MSFmessage ′s information. Likewise, it is not aware that the lack of theconfiguration of any specific exit point program means anything to theprocessing of MSF messages. MSF merely “skips over” those exit pointswhere there are no programs configured until it finds the next exit pointwith a program that should be called to process an MSF message.

Chapter 6. Mail Server Framework Exit Points 89

Page 114: AnyMail/400 Mail Server Framework Developer Guide January 1995

Data Type Evaluation and Call CycleThis section uses a detailed example to illustrate an MSF exit pointconfiguration. The MSF data type evaluation and call cycle uses the data typesin the recipient list to determine when to call the exit point programs.

In this example, MSF address data types are used.

Figure 45. Two Exit Point Programs at Same MSF Exit Point

Figure 45 shows the configuration used in this example. Both PROGRAM1 andPROGRAM2 are configured at the same MSF exit point.

• PROGRAM1 has an exit program number of 1000 and specifies that itprocesses MSF messages with recipient list entries that have address typesof 01A1, 01A2, and 01A3.

• PROGRAM2 has an exit program number of 2000 and is using a specialvalue in its program data. The value, 9999 indicates that PROGRAM2processes MSF messages with recipient list entries that have any addresstype.

Note: Figure 45 (and all the other figures in this chapter) illustrates the order ofconfigured exit point programs by showing the next program on order asbeing behind and to the right. Thus PROGRAM2 appears behind and to

90 AnyMail/400 MSF

Page 115: AnyMail/400 Mail Server Framework Developer Guide January 1995

the right of PROGRAM1 to show that it is the next program configuredafter PROGRAM1 at the same exit point.

MSF uses the exit program number associated with each exit point program todetermine the order they are evaluated. Since PROGRAM1 has an exit programnumber of 1000 it is first in the order of exit point programs MSF evaluates.

Figure 46. MSF Calls Exit Point Program PROGRAM1 First

As shown in Figure 46, MSF determines that there are recipient list entries withaddress types that match the ones PROGRAM1 is configured to handle. MSFcalls PROGRAM1 and passes PROGRAM1 a copy of the MSF message′srecipient list. The recipient list passed contains only the recipients that matchthe ones PROGRAM1 is configured to handle. In this example the recipients with01A1 and 01A2 data types are in the list passed by MSF.

Chapter 6. Mail Server Framework Exit Points 91

Page 116: AnyMail/400 Mail Server Framework Developer Guide January 1995

Eventually PROGRAM1 returns control to MSF after being called. MSF knowsthat there is still a recipient list entry that was not already passed to some exitpoint program. Therefore MSF will continue the data type evaluation and callcycle for this exit point.

In this example PROGRAM2 has an exit program number of 2000. It is the nextexit program MSF evaluates to determine if it should be called.

Figure 47. MSF Calls Exit Point Program PROGRAM2 Next

MSF determines that there are recipient list entries that were not already passedto PROGRAM1 and with address types that match the ones PROGRAM2 isconfigured to handle (PROGRAM2 handles all of them).

As shown in Figure 47, MSF calls PROGRAM2. MSF passes PROGRAM2 a copyof the MSF message′s recipient list but it contains only the recipients that werenot already passed to PROGRAM1 and that match the ones PROGRAM2 isconfigured to handle.

Eventually PROGRAM2 returns control to MSF after being called. This time thereare no recipient list entries that were not already passed to some exit pointprogram. Therefore MSF will stop the data type evaluation and call cycle for thisexit point.

The processing of this message continues with the next MSF exit point. The datatype evaluation and call cycle repeats itself until there are no more MSF exitpoints to evaluate.

92 AnyMail/400 MSF

Page 117: AnyMail/400 Mail Server Framework Developer Guide January 1995

Why Exit Point Program Order Is ImportantThis section uses a detailed example to illustrate why the order of exit programconfiguration is important. This is similar to the previous example. The MSFdata type evaluation and call cycle uses the data types in the recipient list todetermine which exit point program to call. What is being shown here is thatMSF will not continue its data type evaluation and call cycle when all therecipient list entries have been passed to an exit point program.

Again, in this example, MSF address data types are used.

Figure 48. Two Exit Point Programs at Same MSF Exit Point

Figure 48 shows the example configuration used in this example. BothPROGRAM1 and PROGRAM2 are configured at the same MSF exit point. In thisparticular configuration however,

• PROGRAM1 has an exit program number of 1000 and is using a specialvalue in its program data. The value 9999 indicates that PROGRAM1processes messages with list entries that have any address type.

• PROGRAM2 has an exit program number of 2000 and is also using a specialvalue in its program data. The value 9999 indicates that PROGRAM2processes messages with list entries that have any address type.

Again, MSF uses the exit program number associated with each exit pointprogram to determine the order they are evaluated. Since PROGRAM1 has anexit program number of 1000 it is first in the order of exit point programs MSFevaluates.

Chapter 6. Mail Server Framework Exit Points 93

Page 118: AnyMail/400 Mail Server Framework Developer Guide January 1995

Figure 49. Only PROGRAM1 Is Called by MSF

MSF determines that there are recipient list entries with address types thatmatch the ones PROGRAM1 is configured to handle (PROGRAM1 handles all ofthem).

As shown in Figure 49, MSF calls PROGRAM1. MSF passes PROGRAM1 a copyof the MSF message′s recipient list and in this example it contains all therecipients.

Eventually PROGRAM1 returns control to MSF after being called. This time thereare no recipient list entries that were not already passed to exit point programPROGRAM1. Therefore MSF will stop the data type evaluation and call cycle forthis exit point.

MSF does not call PROGRAM2. In fact, PROGRAM2 never gets called given theconfiguration of the two exit point programs in this example!

94 AnyMail/400 MSF

Page 119: AnyMail/400 Mail Server Framework Developer Guide January 1995

Changing How MSF Handles Multiple Programs

Why does MSF even allow a configuration as shown in this example?

The answer is that there are times when it is very useful or even required tobe able to configure exit point programs at the same exit point, all of whichwant to process the same MSF messages.

The only way this can work is that the exit point programs must be designedso that they make this happen.

Looking at the above example, the only way for PROGRAM2 to ever be calledby MSF is if PROGRAM1 does something that will allow the MSF data typeevaluation and call cycle to evaluate PROGRAM2′s configuration. That willnot happen unless, when PROGRAM1 returns to the framework, there are stillrecipient list entries that cause MSF to continue to cycle.

It is almost as if PROGRAM1 has to control what the framework does after itreturns to the framework! How does PROGRAM1 do this? It uses the “putback” option described in the next section.

Using QzmfChgMailMsg to Put Back RecipientsThis section uses the same detailed example used above to illustrate how anMSF exit point program uses the ability to change a recipient list to change theMSF data type evaluation and call cycle .

As before, in this example, MSF address data types are used. Both PROGRAM1and PROGRAM2 are configured at the same MSF exit point with the sameprogram data as before.

First, revisit the previous example starting with Figure 49 on page 94.

Again, MSF uses the exit program number associated with each exit pointprogram to determine the order they are evaluated. Since PROGRAM1 has anexit program number of 1000 it is first in the order of exit point programs MSFevaluates. The data type evaluation and call cycle uses the data types inrecipient list to determine when to call the exit point programs.

In Figure 51 on page 97, MSF determines that there are recipient list entrieswith address types that match the ones PROGRAM1 is configured to handle(PROGRAM1 handles all of them). MSF calls PROGRAM1. MSF passesPROGRAM1 a copy of the MSF message′s recipient list and in this example itcontains all the recipients

But this time PROGRAM1 does something different .

Chapter 6. Mail Server Framework Exit Points 95

Page 120: AnyMail/400 Mail Server Framework Developer Guide January 1995

Figure 50. MSF Exit Point Programs can ″Put Back″ Recipients

As shown in Figure 50, PROGRAM1 uses the QzmfChgMailMsg API in a specialmanner. It uses the API to tell MSF to “put back” some of the MSF message′srecipient list entries.

This is done like any other change to the recipient list entries that PROGRAM1may make. However, the “put back” change is not used to change theinformation the recipient list. It is used by PROGRAM1 to tell MSF to reevaluatethe recipient entries that are being “put back.”

PROGRAM1 does the “put back” on a per recipient basis by passing a recipientlist on the QzmfChgMailMsg API. The recipients that are to “put back” have aspecial value of negative one (-1) in the status field in this list′s entries. When a“put back” is done for a recipient in this manner MSF will ignore all otherchanges made on the same call of QzmfChgMailMsg for that recipient.

Eventually PROGRAM1 returns control to MSF after being called in the previousexample. Of course, this time PROGRAM1 has “put pack” the recipient listentries it was passed. MSF knows that this has happened due to a changemade by PROGRAM1. Therefore MSF will continue the data type evaluation and

96 AnyMail/400 MSF

Page 121: AnyMail/400 Mail Server Framework Developer Guide January 1995

call cycle for this exit point. It reevaluates all the recipient list entries “put back”by PROGRAM1.

In this example PROGRAM2 has an exit program number of 2000. It is the nextexit program MSF evaluates to determine if it should be called.

Figure 51. Next MSF Exit Point Program Called After a ″Put Back″

As shown in Figure 51, MSF determines that there are recipient list entries thatare to be reevaluated and with address types that match the ones PROGRAM2 isconfigured to handle (PROGRAM2 handles all of them). MSF calls PROGRAM2.MSF passes PROGRAM2 a copy of the MSF message′s recipient list. It containsthe recipients that were reevaluated and that match the ones PROGRAM2 isconfigured to handle.

Eventually PROGRAM2 returns control to MSF after being called. This time thereare no recipient list entries that were not already passed to some exit pointprogram. Therefore MSF will stop the data type evaluation and call cycle for thisexit point. Of course, PROGRAM2, has the option to also “put back” therecipients it was passed and cause MSF to reevaluate them.

Not shown in this example is that the QzmfChgMailMsg API allows for anynumber of the recipient list entries to be changed to be “put back.” Theprogram that was called by MSF and passed the recipients can, as part of itsfunction, decide that only some of the recipient list entries should be reevaluatedby the framework when it returns.

Note: There are some exit points where all exit point programs should bedesigned to put back all the recipient list entries that they might be

Chapter 6. Mail Server Framework Exit Points 97

Page 122: AnyMail/400 Mail Server Framework Developer Guide January 1995

passed. See the descriptions of the exit points that follow for more onwhy “put back” is necessary for some exit point programs.

How MSF Uses Recipient List Address and Message TypesThis section explains how MSF uses different information in the recipient listwhen evaluating what exit point program to call. The information MSF usesdepends on the exit point where it is doing the evaluation.

When, reading this, remember that the basic data type evaluation and call cycledoes not change. The change is what MSF is using in its evaluation cycle.

Figure 52 on page 99 shows that the framework is using different data types inthe recipient list:

• It uses the address type field values in the recipient list to evaluate whichexit point programs to call in the addressing group exit points3 .

MSF does not use any recipient list entry that already has its message typeand status values set when evaluating a recipient list for exit points in thisgroup.

• It uses the message type field values in the recipient list to evaluate whichexit point programs to call in the pre-delivery group exit points.

• It uses the message type and status fields values in the recipient list toevaluate which exit point programs to call in the delivery group exit pointsand the non-delivery exit point in the management group 4 .

• It uses the message type field value in the recipient list to evaluate whichexit point programs to call in the last two management group exit points.

MSF Will Default Message Type and Status

The framework must keep making its evaluation decisions once it has passedthe addressing group exit points. To make these decisions, MSF must havevalues set in the message type and status fields of every recipient list entry .

Before MSF continues processing a message past the addressing group exitpoints, it will check to make sure that all the entries have values set in theirmessage type and status fields. If there are any entries that do not, then MSFwill set them . MSF will assign a special value for the message type (9998)and a set the status to non-delivery for each recipient list entry that does notalready have these values set.

As a designer of exit point programs, you must understand this defaultbehavior of the framework, especially if you are designing a non-delivery exitpoint program.

3 See “Special Properties of the Addressing Group Exit Points” on page 101 for more information about the special propertiesof the addressing group exit points.

4 See “How MSF Uses Recipient List Status” on page 110 for more information about how the status field values are used.

98 AnyMail/400 MSF

Page 123: AnyMail/400 Mail Server Framework Developer Guide January 1995

Figure 52. Using Different Data Types when Evaluating Exit Points. Not al l the pre-delivery group exit points areshown

Chapter 6. Mail Server Framework Exit Points 99

Page 124: AnyMail/400 Mail Server Framework Developer Guide January 1995

Not shown in Figure 52 is that the exit point programs are assumed to beupdating the recipient list. The addressing group programs are changing therecipient list entries to set the message type and status values shown beingused further down in the framework.

Also not shown is that other exit point programs can also reset the messagetypes and change the status as part of their functions.

Presetting the Message Type and Status Fields

MSF allows the creator of an MSF message to set the message type andstatus fields in the recipient list entries of that message. Any or all of therecipient list entries can be created with these values already set.

When the message type and status are set for a recipient list entry, it is notused in the data type evaluation and call cycle for the addressing group exitpoints.

If all the recipient list entries have a message type and status set, then noaddressing group exit point programs will be called by MSF when processingthat message.

Figure 53 shows that this means that the creator of an MSF message cancause MSF to “skip” past all the addressing group exit points and go directlyto the first pre-delivery group exit point.

All the creating program has to do is create an MSF message making sure itsets the message types and status fields in all the recipient list entries.

Figure 53. Addressing Group Exit Points Are Skipped by MSF. MSF does not consider the recipient list entriesthat already have a message type and status value set when deciding what addressing group exit point program tocall

100 AnyMail/400 MSF

Page 125: AnyMail/400 Mail Server Framework Developer Guide January 1995

Special Properties of the Addressing Group Exit PointsThe addressing group is by far the most important set of exit points. Programsin these exit points can change the recipient list by adding or replacing listentries. Also programs in one of these exit points usually change the message′srecipient list entries setting the message type and status field values. Thesevalues are used to select all the other exit point programs that can be calledfrom MSF.

As a designer of an addressing group exit point program you also mustunderstand the exit points in the addressing group are related to each other in aspecial way. Even if you do not design exit point programs that snap in to theaddressing group exit points, you may want to know how these programs inthese exit points behave.

For example, there is a preconfigured address resolution exit point programcalled QSYS/QZMFSNPA. This program uses the properties described in thissection to do its function. It uses information in the OS/400 system distributiondirectory to switch E-mail addresses on MSF messages. How this programworks can affect the functions of all other MSF exit point programs. (SeeAppendix D, “QZMFSNPA Exit Point Program” on page 291 for more informationon this program.)

Exit point programs in the addressing group exit points both change and operateon a message recipient list. One exit point program′s changes to the recipientlist can cause MSF to reevaluate if it should restart the data type evaluation andcall cycle for these exit points. This reevaluation occurs only for the addressinggroup exit points.

This is different than the function described in “Using QzmfChgMailMsg to PutBack Recipients” on page 95. “Putting back” a recipient list entry is how an exitpoint program can control if recipient list entries are continued to be used byMSF when it does its data type evaluation and call cycle for other programs inthe same exit point. Exit point programs must use the QzmfChgMailMsg API tomark recipient list entries and indicate to MSF that they are to be reused.

What is being described here happens automatically for the addressing groupexit points when they do either of the following:

• Change the recipient list by adding a new list entry.

• Change the recipient list by replacing an existing list entry.

Chapter 6. Mail Server Framework Exit Points 101

Page 126: AnyMail/400 Mail Server Framework Developer Guide January 1995

List Expansion Exit Point ReevaluationList expansion exit point reevaluation is best illustrated by an example. In thisexample there are two list expansion exit point programs. MSF is processing amessage that has a single recipient list entry with an address type of 01C0.

As shown in Figure 54, the framework has done its data type evaluation and callcycle for the message and has called PROGRAM2. It passes PROGRAM2 therecipient list entry.

Figure 54. MSF Selects and Calls PROGRAM2. PROGRAM1 was not called since no list entry address typematched its exit program data

The function of PROGRAM2 is to expand single recipient list entries into multipleE-mail addresses. In this example it is configured to look at any recipient listentry regardless of address type to identify what are possibly the names ofdistribution lists attached to MSF messages.

PROGRAM2 decides to expand the single recipient list entry into a list of E-Mailaddresses.

102 AnyMail/400 MSF

Page 127: AnyMail/400 Mail Server Framework Developer Guide January 1995

Figure 55. PROGRAM2 Changes Message Recipient List and Returns

Figure 55 shows that PROGRAM2 makes the change to the MSF message usingthe QzmfChgMailMsg API. It tells the framework to replace the recipient listentry with three new entries. These have an address type of 01A1 .

Eventually PROGRAM2 returns to the framework and MSF changes the message5

.

There are no recipient list entries that were not already passed to some exitpoint program. Normally MSF will stop the data type evaluation and call cyclefor this exit point and go on to the next one. However, since PROGRAM2 is a listexpansion exit point program and it has changed the recipient list by adding anew list entry, the framework will restart the data type evaluation and call cyclefor this exit point.

Restarting the data type evaluation and call cycle means that MSF has toconsider PROGRAM1 first. It is the first program configured in the list expansionexit point.

MSF is again trying to determine which exit point program to call using theaddress types in the message recipient list. In this example, PROGRAM2 hasadded three new recipient list entries. Even if there were other recipient listentries, only the ones added are used by MSF when evaluating which program tocall. MSF keeps track of which of the recipient list entries it has alreadyconsidered in the previous data type evaluation and call cycle for this exit point.

5 For more information on how this works see “How an Exit Point Program Changes a Message” on page 114.

Chapter 6. Mail Server Framework Exit Points 103

Page 128: AnyMail/400 Mail Server Framework Developer Guide January 1995

Figure 56. MSF Reevaluates and Calls PROGRAM1

Figure 56 shows that, as a result of the reevaluation made by MSF, PROGRAM1is called and passed the new recipient list entries. Even if there were otherrecipient list entries only the ones added are passed by MSF on the call toPROGRAM1.

Address Resolution Exit Point ReevaluationWe will use another example to illustrate the property of address resolution exitpoint reevaluation. This example is more complex since this property is aboutthe relationship between the list expansion and the address resolution exitpoints. This property only has an effect on how a message is processed if anaddress resolution exit point program uses the QzmfChgMailMsg API to add orreplace an entry in the message recipient list.

This example uses two exit point programs. One is configured in the listexpansion exit point and one is configured in the address resolution exit point.

MSF is processing a message that has a recipient list entry with three entries.As shown in Figure 57 on page 105 the framework has already done its datatype evaluation and call cycle for the list expansion exit point.

MSF does its data type evaluation and call cycle for the address resolution exitpoint. The message recipient list includes address types that match those forthe configured program.

104 AnyMail/400 MSF

Page 129: AnyMail/400 Mail Server Framework Developer Guide January 1995

Figure 57. MSF Selects and Calls Address Resolution Exit Point Program. The list expansion exit point hasalready been evaluated by MSF

In Figure 57 MSF has called the address resolution program. It passes thisprogram the three recipient list entries since all three had address types thatmatched those in the exit program data.

Chapter 6. Mail Server Framework Exit Points 105

Page 130: AnyMail/400 Mail Server Framework Developer Guide January 1995

Figure 58. Program Changes Message Recipient List and Returns. It replaces the 01A1 type entry with a newentry that has 01C0 as its address type

Figure 58 shows that the address resolution program decides to replace one ofthe recipient list entries (1). The example shows the new list entry having adifferent address type; 01C0.

The program uses the QzmfChgMailMsg API to tell MSF to replace a recipientlist entry (2).

Note: This program may make other changes to the recipient list but for thesake of clarity these are not shown in this example.

When this address resolution exit point program returns, MSF makes theupdates requested to the recipient list6 . There are no more addressingresolution exit point programs. MSF has finished the data type evaluation and

6 For more information on how this works see “How an Exit Point Program Changes a Message” on page 114.

106 AnyMail/400 MSF

Page 131: AnyMail/400 Mail Server Framework Developer Guide January 1995

call cycle for this exit point. Normally, the framework would continue processingthis message with the pre-delivery group exit points. In this example howeverthe address resolution exit point program has changed the recipient list.Therefore MSF will reevaluate both the list expansion and the address resolutionexit points.

Figure 59. MSF Reevaluates List Expansion and Calls a Program. MSF reevaluates the list expansion exit pointafter an entry was replaced in the recipient list

Figure 59 shows that MSF will reevaluate the list expansion exit point. Only theentries replaced or added by an address resolution exit point program are used indata type evaluation and call cycle when MSF does this reevaluation!

In our example, only the recipient list entry that was replaced (with the 01C0address type) is used to determine if a list expansion exit point program shouldbe called.

MSF determines if there is a program that has an address type that matches thereplaced list entries. As Figure 59 shows, MSF calls that list expansion exitpoint program.

MSF passes only the recipient list entries that match the exit program dataaddress type and that the framework used in the data type evaluation and callcycle for the exit point.

In this example there is only one such recipient list entry. Even if there weremore recipient list entries that had an address type of 01C0, if these entries werenot added or replaced by an address resolution exit point program,

Chapter 6. Mail Server Framework Exit Points 107

Page 132: AnyMail/400 Mail Server Framework Developer Guide January 1995

• they would not be part of the MSF reevaluation′s data type evaluation andcall cycle ,

• they would not be passed to any exit point program that was called as partof this cycle.

Why Go Back to the List Expansion Exit Point?

Whenever a recipient list entry is added or replaced it is possible that thenew entry represents the name of a recipient list. The dilemma is that MSFhas already passed by the list expansion exit point (and the programs thatmight want to check to see if the new entry is a list).

To handle this situation, MSF builds the reevaluation function to automaticallyreturn back to the list expansion exit point whenever any change is made byan address resolution exit point program.

It should be noted that reevaluation keeps occurring over and over as long asthere is an address resolution exit point program that keeps adding orreplacing recipient list entries.

After all the data type evaluation and call cycle completes for list expansion exitpoint, the reevaluation of the message due to the changes made to the recipientlist continues.

108 AnyMail/400 MSF

Page 133: AnyMail/400 Mail Server Framework Developer Guide January 1995

Figure 60. MSF Reevaluates Address Resolution. MSF does not call the exit point program since the 01A2recipient list entries are not part of the reevaluation

Figure 60 shows that the address resolution exit point is also reevaluated byMSF. In this example no further changes to the recipient list were made by a listexpansion exit point program.

The message being processed has two recipient list entries that have the 01A2address type. These entries were not added or replaced so they are not used inthe data type evaluation and call cycle used to determine if MSF calls aprogram.

As Figure 60 shows, MSF does not call any address resolution exit pointprograms. No further reevaluation of any addressing group exit point is done byMSF since there were no more recipient list entries added or replaced. It cannow continue processing the message with the first of the pre-delivery exitpoints.

Chapter 6. Mail Server Framework Exit Points 109

Page 134: AnyMail/400 Mail Server Framework Developer Guide January 1995

How MSF Uses Recipient List StatusWe have already explained the concepts involved in the MSF data typeevaluation and call cycle . Some groups use the recipient list address data typeand others use the message type. This section explains how MSF uses differentvalues in the recipient list status field when evaluating what exit point programto call. How the MSF uses the status field depends on the exit point where it isdoing the evaluation.

Note: The message type and status fields in a message recipient list should beconsidered as corequisites. When either field is set, then the other mustalso be set at the same time.

When reading this remember again that the basic data type evaluation and callcycle does not change. The change is what MSF is using in its evaluation cycle.

Figure 61 on page 111 shows that the framework is using the status field in therecipient list entries:

• The recipient list entries that have the message type and status field valuesset are not used by MSF when evaluating which addressing group exit pointprogram to call. Effectively the status field values are not used when MSFevaluates the addressing group exit points7 .

• When evaluating an exit point in the pre-delivery group , only the messagetype field values are used to determine which programs to call.

• MSF uses the message type and status fields values in the recipient list toevaluate which exit point programs to call in the delivery group exit pointsand the non-delivery exit point in the management group .

− Only those recipients that have a local status field value are used whendetermining which local delivery exit point program to call.

− Only those recipients that have a remote status field value are usedwhen determining which message forwarding exit point program to call.

− Only those recipients that have a non-delivery status field value are usedwhen determining which non-delivery exit point program to call.

If the status field value is not one of these three values the recipient listentry is not used by MSF when evaluating which exit point program to call.

• MSF uses the message type field value in the recipient list to evaluate whichexit point programs to call in the last two management group exit points.

If the field value is ignore, MSF will simply ignore all recipient list entries thathave this status when making any kind of evaluation for any of these exitpoints.

7 In fact the expectation is that exit point programs in this addressing group will set the message type and status field values.

110 AnyMail/400 MSF

Page 135: AnyMail/400 Mail Server Framework Developer Guide January 1995

Figure 61. Using the Status Field when Evaluating Exit Points. Not al l the pre-delivery group exit points areshown

Chapter 6. Mail Server Framework Exit Points 111

Page 136: AnyMail/400 Mail Server Framework Developer Guide January 1995

Not shown in Figure 61 is that the exit point programs are assumed to beupdating the message recipient list. The addressing group programs arechanging the recipient list entries to set the message type and status valuesshown being used further down in the framework.

The figure also does not show that other exit point programs may also reset themessage types and change the status as part of their functions.

Special Status Field ValuesWe have seen how the local , remote , and non-delivery status values are used toallow recipient list entries to route the processing of an MSF message to one ofthree exit points. There are two other values that can be used to set the statusfield: Ignore and Security Violation .

Ignore StatusThe ignore status is how an exit point program can logically remove an MSFmessage recipient list entry. As a designer of exit point programs you need tounderstand how the framework uses the ignore status when it is set in a listentry. You may want to use the ignore status in your program or need tounderstand how another exit point program is using it.

MSF does not provide any other way to delete recipient list entries. Setting thestatus of a recipient list entry to ignore is how an exit point program caneffectively remove a recipient, or possibly all recipients, from being used byMSF. The processing of a message is controlled by how MSF uses the recipientlist entries. This makes setting the status field to ignore a very powerful optionfor exit point programs.

Every exit point program that can change the recipient list can set the status flagof any recipient list entry to ignore. Once the flag has been set using theQzmfChgMailMsg API, MSF ignores that recipient list entry. This means that:

• MSF will never use the list entry data type in any evaluation of any exit point.

If every entry in a message′s recipient list was set to the ignore status by anexit point program, no other exit point programs would be called by MSF inthe processing of that message.

• MSF will never pass the list entry to any exit point program.

This is true even if that program has used the 9999 value in its configuredprogram data to indicate the program wants to be passed all of the recipientlist, regardless of data type.

Entries with an ignore status are still in the message′s recipient list.

• They are still tracked by MSF.

• They are included in the recipient history list .

• They are included in the total number of recipient list entries.

• Most importantly, they are passed when an exit point program uses theQzmfRtvMailMsg API to retrieve the entire message′s recipient list.

In this sense, the ignore status entries are still able to be “seen” by other exitpoint programs.

112 AnyMail/400 MSF

Page 137: AnyMail/400 Mail Server Framework Developer Guide January 1995

Security Violation StatusThe security violation status is a way for an exit point program to set the statusof a recipient list entry to cause it not to be used in the evaluation of the localdelivery , message forwarding and non-delivery exit points.

The primary user of this status would be a security and authority exit pointprogram. It gives a designer of one of these programs the ability to “hide” arecipient list entry from the local delivery , message forwarding , and non-deliveryexit points. It is a very useful tool for these programs in that it still allows themanagement group exit points to be evaluated by the framework8 .

Using a special status value allows the security and authority exit point programto mark recipients that violate some security policy that the program enforces.The program′s designer knows that MSF will not use the recipient in evaluatingwhich local delivery , message forwarding , and non-delivery exit point program tocall. MSF also does not pass that recipient to any of the exit point programs itcalls.

On the other hand, MSF will still use that recipient list entry to determine whichattachment management or accounting exit point programs should be called aspart of processing that MSF message.

Note: A special property of the security violation status value is that, once setby an exit point program, MSF will not allow it to be changed to any othervalue by another exit point program.

8 This is in contrast to the ignore status that would cause these MSF to ignore these exit points for the ignore status recipients.

Chapter 6. Mail Server Framework Exit Points 113

Page 138: AnyMail/400 Mail Server Framework Developer Guide January 1995

How an Exit Point Program Changes a MessageAs explained in “Basic Design of Exit Point Programs” on page 86, the designaspect of exit point programs is that they are interested in two things: using (orcopying) the MSF message′s information or changing something about thatinformation so that subsequent exit point programs will see the change.

An exit point program must use the QzmfChgMailMsg API when it needs tomodify the MSF message′s information. Remember that exit point programs arepassed the copy of an MSF message, not a direct access to the message object.An exit point program can change the information it is passed when called fromMSF by modifying the information as passed in user spaces from the framework.It could also copy this information from the user space to storage known to theprogram, change it there and pass the changed local storage version as aparameter on the QzmfChgMailMsg API.

To make a change to an MSF message, the exit point program must use theQzmfChgMailMsg API to tell MSF that the internal message object that is beingprotected by the framework should be changed. When an exit point programmakes a change to an MSF message′s information, it is not changing the actualMSF message information until it calls the QzmfChgMailMsg API.

The framework saves the changes that are being made by the program until thatprogram successfully returns to the framework with zero (0) return code. Whenthe program returns, MSF applies all these changes to the MSF message.

Note: The program can also return to the framework with a non-zero returncode. It can return a 1 (one) to indicate that all the changes that it mayhave made using the QzmfChgMailMsg API should not be made to theMSF message.

The following is an example of the use of the QzmfChgMailMsg API. In thisexample, a list expansion exit point program is interested in looking at the MSFmessage ′s recipient list. Its function is to find the address types that couldindicate that an E-mail address is actually the name of a distribution list.

First, the program has to find a recipient list entry with an address type for whichit is looking. The program looks at the E-mail address string in that recipient listentry. It would use that address to determine if it is really the name of adistribution list that has to be expanded into several recipient E-mail addresses.

114 AnyMail/400 MSF

Page 139: AnyMail/400 Mail Server Framework Developer Guide January 1995

Figure 62. An Exit Point Program Changes an MSF Message. This figure illustrates a list expansion function

If the address string is the name of a distribution list the program recognizes,the program would then be interested in making a change to the MSF messagerecipient list. As Figure 62 shows, the program decides to change a recipientlist entry.

The exit point program calls the QzmfChgMailMsg API to tell MSF to replace thesingle recipient list entry that held the name of the distribution list with new listentries that hold the E-mail addresses from the distribution list.

Chapter 6. Mail Server Framework Exit Points 115

Page 140: AnyMail/400 Mail Server Framework Developer Guide January 1995

Figure 63. MSF Makes the Changes when the Program Returns. MSF replaces the 01C0 type recipient list entry

Figure 63 shows that the list expansion exit point program returns control to theframework with a zero return code. MSF applies the recipient list changes itmade to the message when the program returns to the framework. In thisexample, the message recipient list now has four entries.

By making this change to the message′s recipient list using theQzmfChgMailMsg API, the exit point program changes how the MSF messagewill be processed from then on. The recipient list entry that was replaced withthe distribution list′s E-mail addresses will not be seen by any other exit pointprogram9 .

Subsequent MSF exit point programs called from MSF would deliver or forwardthe MSF message′s information to the expanded list of recipients that nowincludes those added by the list expansion exit point program.

9 MSF keeps a recipient history list in every message that can be retrieved by any exit point program. This list can be used todetermine if any entries were replaced in the recipient l ist.

116 AnyMail/400 MSF

Page 141: AnyMail/400 Mail Server Framework Developer Guide January 1995

When Changes to a Message Take Effect

An exit point program can use the QzmfChgMailMsg API many times as partof its function. The framework holds these changes internally. However, asshown in Figure 63, the changes are not actually made to the internal MSFmessage object until the exit point program successfully returns to theframework with a 0 return code. This includes the changes made by an exitpoint program to “put back” recipient list entries.

If the exit point program that made a change

• fails for any reason (for example due to an unmonitored exception),

• returns to MSF with a non-zero return code,

• does not return to MSF and the QMSF job fails or is cancelled

then none of the changes made by that program would actually be applied tothe MSF message it changed.

If an exit point program has changed an MSF message and returns to theframework, the changes made are applied to the encapsulated message′sinformation at that time.

A record of the exit point program and an indicator that it changed the MSFmessage is added to the exit point call history list that MSF keeps in themessage.

For example, an exit point program is called to do a list expansion function. Itlooks at the recipient list that was passed to it and decides to expand a recipientE-mail address into a new list of recipient addresses. This program then callsthe QzmfChgMailMsg API to change the MSF message recipient list.

After successfully making the change to the MSF message, the same programmay find another recipient list entry that it decides to expand. This timehowever, the program fails due to some unmonitored exception and the exitpoint program resignals this exception to MSF and ends.

Even though the failing program has previously called the QzmfChgMailMsg APIsuccessfully, none of its changes will be made to the message by MSF becausethe program did not successfully return to the framework.

Chapter 6. Mail Server Framework Exit Points 117

Page 142: AnyMail/400 Mail Server Framework Developer Guide January 1995

Exit Point Program Rules Tables

Exit Point API Rules Overview:p,The tables in this section provide an overview of the rules for the MSF exitpoints. They address the following:

1. What information is used to select an exit point program in that exit point.

2. What parts of an MSF message are passed automatically when an exit pointprogram is called.

Notes:

a. All exit point programs are passed the MSF message ID.

b. All exit point programs can retrieve any part of an MSF message usingthe QzmfChgMailMsg API.

3. What exit point programs at that exit point are allowed to change using theQzmfChgMailMsg API.

There are no rules given for what an exit point program can retrieve using theQzmfRtvMailMsg API except that the message type list cannot be retrieved fromthe addressing group exit points. All programs can retrieve any list from theMSF message they are processing.

Also not shown in these tables is that no exit point program is allowed to changethe recipient history list or the exit point call history list .

Table 10. Selection Criteria and Parameters Passed for Addressing Exit Points

Exit PointName

Exit Point Selection Data Message Lists Passed

List Expansion Recipient address type Recipient ListEnvelope List

AddressResolution

Recipient address type Recipient ListEnvelope ListOriginator ListReport-to ListReport-on ListReply-to ListOriginal Recipient List

118 AnyMail/400 MSF

Page 143: AnyMail/400 Mail Server Framework Developer Guide January 1995

Table 11. Selection Criteria and Parameters Passed for Pre-Delivery Exit Points

Exit PointName

Exit Point Selection Data Message Lists Passed

EnvelopeProcessing

Recipient message type Message Type ListRecipient ListReport-on ListEnvelope ListAttachment Reference ListReport-to ListReply-to ListOriginal Recipient ListOriginator List

AttachmentConversion

Recipient message type Message Type ListRecipient ListAttachment Reference ListEnvelope List

Security andAuthori ty

Recipient message type Recipient ListAttachment Reference ListOriginator List

Table 12. Selection Criteria and Parameters Passed for Del ivery Exit Points

Exit PointName

Exit Point Selection Data Message Lists Passed

Local Del ivery Recipient message typeRecipient status (local only)

Recipient ListEnvelope ListAttachment Reference ListOriginator ListReport-on ListReport-to ListReply-to ListOriginal Recipient ListCreation Attributes

MessageForwarding

Recipient message typeRecipient status (remote only)

Recipient ListEnvelope ListAttachment Reference ListOriginator ListReport-on ListReport-to ListReply-to ListOriginal Recipient ListCreation Attributes

Chapter 6. Mail Server Framework Exit Points 119

Page 144: AnyMail/400 Mail Server Framework Developer Guide January 1995

Table 13. Selection Criteria and Parameters Passed for Management Exit Points

Exit PointName

Exit Point Selection Data Message Lists Passed

Non-Delivery Recipient message typeRecipient status (non-delivery

only)

Recipient ListEnvelope ListAttachment Reference ListOriginator ListReport-to List

AttachmentManagement

Recipient message type Recipient ListAttachment Reference List

Accounting Recipient message type Recipient ListEnvelope ListAttachment Reference ListOriginator ListReport-to ListReply-to ListOriginal Recipient ListCreation Attributes

120 AnyMail/400 MSF

Page 145: AnyMail/400 Mail Server Framework Developer Guide January 1995

Table 14. Changes Al lowed by Exit Point

Exit Point Name Changes Allowed

List Expansion Recipient message type, status and SPINReplace recipient address with a list of addresses

Additions to the following:Originator l istReport-to listReply-to listOriginal Recipient list

Address Resolution Recipient message type, status and SPINReplace recipient address with new address

Additions to the following:Envelope listOriginator l istReport-to listReply-to listOriginal Recipient listReport-on list

Envelope Processing Recipient message typeRecipient status (non-delivery, security violation

or ignore)Recipient SPIN

Additions to the following:Envelope listAttachment reference l ist

Attachment Conversion Recipient message type and SPINRecipient status (non-delivery, security violation

or ignore)

Additions to the following:Envelope listAttachment reference l ist

Security and Authority Recipient message type and SPINRecipient status (security violation or ignore)

Local Del ivery Recipient status (non-delivery or ignore)Recipient SPIN

Message Forwarding Recipient status (non-delivery or ignore)Recipient SPIN

Non-Delivery Recipient SPIN

Attachment Management No changes allowed

Accounting No changes allowed

Chapter 6. Mail Server Framework Exit Points 121

Page 146: AnyMail/400 Mail Server Framework Developer Guide January 1995

Exit Point Programs Shipped in V3R1V3R1 includes some exit point programs that are already “snapped-in” to theMSF framework when the release is installed. For the most part, these exit pointprograms combine to perform the functions that SNADS would have done inprior releases in the QSNADS subsystem job QROUTER.

Figure 64. Exit Point Programs Shipped in V3R1.

122 AnyMail/400 MSF

Page 147: AnyMail/400 Mail Server Framework Developer Guide January 1995

Special Exit PointsThere are two special exit points that are defined by MSF. These areQIBM_QZMFMSF_TRK_CHG and QIBM_QZMFMSF_VLD_TYP. There are no exitpoint programs preconfigured for these exit points. They have differentrestrictions on their configuration than the other ten MSF exit points.

Exit point programs registered in these exit points do not serve the same kind offunction in how MSF processes messages as the other ten MSF exit pointsdescribed previously.

Track Changes Exit Point (QIBM_QZMFMSF_TRK_CHG)The track changes exit point is provided by MSF to help mail applicationdesigners debug or test their exit point programs. This exit point is not intendedto be part of a mail application.

Note: MSF restricts the track changes exit point configuration to allow only oneexit point program to be configured.

The most common function that a track changes exit point program provides isto record some or all of an MSF message′s information every time it is changedby any exit point program. This exit point is not intended to be used as asnap-in location for a logging function. The accounting exit point is defined forthat kind of application.

The track changes exit point is called after any exit point program changes amessage and returns control to MSF. It is called between exit point programs inthe same exit point as each program changes an MSF message.

The track change program is passed both the name of the exit point and thename of the exit point program that changed the message. The only specificinformation about a message that is passed to a track changes exit pointprogram is the messages ID.

As a designer of one of these programs, you may need to know how to use theQzmfRtvMailMsg API to retrieve the information in the message you want yourprogram to use. The advantage of this is that your program can test themessage ID, the exit point, or the exit point program name that changed themessage. It can use this information to selectively retrieve and track variousmessage information.

The track changes exit point program cannot change an MSF message.

See “Retrieve Mail Message (QzmfRtvMailMsg) API” on page 168 for moreinformation on the QzmfRtvMailMsg API.

“Track Mail Message Changes Exit Point” on page 194 describes the interfacefrom MSF to the track changes exit point program.

Every call to the track changes exit point program is recorded by MSF in the exitpoint call history list kept in the MSF message.

Chapter 6. Mail Server Framework Exit Points 123

Page 148: AnyMail/400 Mail Server Framework Developer Guide January 1995

Track Changes Exit Point Example“How an Exit Point Program Changes a Message” on page 114 explains how anMSF exit point program changes message information. To illustrate how a trackchanges exit point program gets called, this section uses the change examplethat starts with Figure 62 on page 115.

In the change example a list expansion exit point program changes an MSFmessage recipient list. Figure 62 on page 115 shows that when that programreturns to MSF, the framework makes the changes to the message.

Whenever MSF changes a message, it determines if there is a track changes exitpoint program configured. Figure 65 shows that there is a program,TRACKPGM, so MSF calls it.

Figure 65. Track Changes Exit Point. This exit point is used whenever an MSF message is changed by an exitpoint program

TRACKPGM is passed the name of the MSF exit point where the message isgetting changed. (QIBM_QZMFMSF_LST_EXP in this example.) TRACKPGM ispassed both the name of the list expansion exit point program that made thechange and the ID of the changed message.

124 AnyMail/400 MSF

Page 149: AnyMail/400 Mail Server Framework Developer Guide January 1995

Validate Data Field Exit Point (QIBM_QZMFMSF_VLD_TYP)The validate data field exit point is provided by MSF to support the ability to adda function that parses and checks the syntax of any information passed into MSFwhen a message is created or changed. This is important to you if you aredefining your own MSF data types, especially envelopes or attachmentreferences.

For example, your mail application includes a definition of an envelope that isrequired to have an exact format and limited values in its fields10 . Your mailapplication programs that create or change MSF messages can recognize yourown envelopes by their MSF data types and can be coded to assume theseenvelopes only have the formats and values that your design requires.

It is possible that some other program that is part of some other mail applicationmay also want to use your envelope. You are willing to allow this, but you wantto assure that this application follows your exact specifications for what theenvelopes must look like! How can you make sure that any program that wouldever create or change your envelope constructs it correctly?

You can do this by creating and configuring a validate data field exit pointprogram. MSF automatically looks to see if there is an exit point program that isconfigured to validate any MSF data type information when an MSF message iscreated or changed.

In our example, your validation program is called and is passed your envelopeswhen any program passes an envelope list on an MSF API with your envelope init. Your validation program enforces the format and field value specifications foryour envelopes. This happens before an MSF message is created or changedwith your envelope in it.

If an envelope is correct according to your validation program, that program cantell MSF to allow the create or change that is being done to proceed.

If an envelope is not correct according to your program, that program can tellMSF to reject the create or change that is being done with your envelope. MSFindicates that the create or change operation failed because your validationprogram did not like the way the caller of the MSF API has constructed yourenvelope.

The following example illustrates how you can use the validate data field exitpoint to check your envelopes. However, this exit point can be used to validateany envelope, attachment reference, or address that is passed across an MSFQzmfCrtMailMsg or QzmfChgMailMsg API.

“Validate Data Field Exit Point” on page 192 describes the interface from MSF tothe validate data field exit point programs.

Note: MSF restricts the validate data field exit point configuration to allow onlyone exit point program to be configured to validate any one MSF datatype.

When an exit point program is configured it must specify which MSFconfigured data type it validates in that exit program data.

10 You must define the envelope data type to MSF as part of your application′s configuration.

Chapter 6. Mail Server Framework Exit Points 125

Page 150: AnyMail/400 Mail Server Framework Developer Guide January 1995

The validate data field exit point is used in an unusual way. As Figure 66 onpage 126 shows,

Figure 66. Validate Data Field Exit Point

MSF evaluates the exit point in two instances:

• When the QzmfCrtMailMsg API is used. At in Figure 66.

• When the QzmfChgMailMsg API is used. At in Figure 66.

In either instance, MSF evaluates the same validate data field exit point. Itselects and calls the same exit point programs.

126 AnyMail/400 MSF

Page 151: AnyMail/400 Mail Server Framework Developer Guide January 1995

Validate Data Field Exit Point and QzmfCrtMailMsg ExampleThis example illustrates how you can use the validate data field exit point whena message is created. Figure 67 shows a mail application that is usingQzmfCrtMailMsg to create an MSF message. The application has built anoriginator list, a recipient list, an envelope list, and an attachment reference list.It has passed these lists as parameters on the API.

Figure 67. QzmfCrtMailMsg and Validate Data Field Exit Example

Figure 67 shows the contents of both the recipient list and the envelope list thatare being passed as parameters.

As part of the QzmfCrtMailMsg API function, MSF looks at every data type inevery list passed and determines if there is a validate data field exit pointprogram that is configured for that MSF data type. If there is an exit pointprogram that validates the list entries with that type, MSF gathers all the listentries that have the same data type into a temporary list and calls the program.

Chapter 6. Mail Server Framework Exit Points 127

Page 152: AnyMail/400 Mail Server Framework Developer Guide January 1995

Figure 68. QzmfCrtMailMsg Calls Validate Data Field Exit Programs

Figure 68 shows that the MSF QzmfCrtMailMsg first calls exit point program

VALIDAT1 at .

VALIDAT1 is configured so that it is always called whenever any MSF list entrywith a 01A4 data type is passed. The recipient list being passed toQzmfCrtMailMsg has two entries with this data type. Both of these are passedto VALIDAT1 when it is called by MSF QzmfCrtMailMsg.

VALIDAT1 does its validation on the two recipients of data type 01A4 . In thisexample VALIDAT1 approves the entries it was passed. It returns with a returncode of 0 to tell QzmfCrtMailMsg that the 01A4 entries that were passed to it arevalid and the creation of the message may proceed.

When VALIDAT1 returns to MSF, Figure 68 shows that QzmfCrtMailMsg nextdetermines there is another validate data field exit point program, VALIDAT2,that validates MSF list entries with a 03A1 data type.

Figure 68 shows that QzmfCrtMailMsg calls exit point program VALIDAT2 at

.

VALIDAT2 is configured so that it always is called when any MSF list entry with a03A1 data type is passed. The envelope list being passed to QzmfCrtMailMsg

128 AnyMail/400 MSF

Page 153: AnyMail/400 Mail Server Framework Developer Guide January 1995

has an entry with this data type. This entry is passed to VALIDAT2 when it iscalled by MSF QzmfCrtMailMsg.

VALIDAT2 validates the envelope with data type 03A1 . In this example,VALIDAT2 approves the envelope it was passed. It returns with a return code of0 to tell QzmfCrtMailMsg that the envelope that was passed is valid and thecreation of the message may proceed.

When VALIDAT2 returns to MSF, Figure 68 on page 128 shows thatQzmfCrtMailMsg determines there are no other validate data field exit pointprograms that it must call. In this example there is only one other program,VALIDAT3, and the MSF message being created does not have any list entrieswith the MSF data type that VALIDAT3 validates. Program VALIDAT3 is notcalled.

The QzmfCrtMailMsg API has considered all the validation programs configured.It has called those that it should call. Every validate data field exit point programthat is called approved of the information in the list entries that were passed tothem.

QzmfCrtMailMsg can now proceed to create the MSF message as shown in

Figure 68 on page 128 at .

Not shown in this example is what happens when a validate data field exit pointprogram determines that the list entries it was passed are not valid.

In this case, the exit program has to set the return code to 1. QzmfCrtMailMsgdoes not continue creating the message. MSF reports an error to the mailapplication that called the QzmfCrtMailMsg API. The error indicates that therewas a validate data field exit point program that indicates the data was not valid.The create operation fails in this case. QzmfCrtMailMsg returns this validationexit point program name and any information from the program.

Validate Data Field Exit Point and QzmfChgMailMsg ExampleThis example illustrates how the same validate data field exit point can also beused when a message is changed. It assumes the same exit point configurationas was used in the previous example. The validate data field exit point is usedby both the QzmfCrtMailMsg and QzmfChgMailMsg API functions.

Figure 69 on page 130 shows an MSF exit point program usingQzmfChgMailMsg to change an MSF message. The program has decided to

change both the message recipient list and envelope list at .

Chapter 6. Mail Server Framework Exit Points 129

Page 154: AnyMail/400 Mail Server Framework Developer Guide January 1995

Figure 69. QzmfChgMailMsg and Validate Data Field Exit Example

The program makes the changes to the list entries it wants to change and

passes them as parameters on the QzmfChgMailMsg API at in Figure 69.

Figure 69 shows the example contents of the recipient list and the envelope listthat are being passed as parameters on the change API.

As part of the QzmfChgMailMsg API function, MSF looks at every data type inevery list passed and determines if there is a validate data field exit pointprogram that is configured for that MSF data type. If there is an exit pointprogram that validates the list entries with that type, MSF gathers all the listentries that have the data type into a temporary list and calls that program.

130 AnyMail/400 MSF

Page 155: AnyMail/400 Mail Server Framework Developer Guide January 1995

Figure 70. QzmfChgMailMsg Calls Validate Data Field Exit Programs

Figure 70 shows that the MSF QzmfCrtMailMsg first calls exit point program

VALIDAT1 at .

VALIDAT1 is configured so that it is always called whenever any MSF list entrywith a 01A4 data type is passed. The recipient list being passed toQzmfChgMailMsg has two entries with this data type. Both of these entries arepassed to VALIDAT1 when it is called by MSF QzmfChgMailMsg.

VALIDAT1 does its validation on the two recipients of data type 01A4 . In thisexample VALIDAT1 approves the entries it was passed. It returns with a returncode of 0 to tell QzmfChgMailMsg that the entries that were passed are validand the change of the message may proceed.

When VALIDAT1 returns to MSF, Figure 68 on page 128 shows thatQzmfChgMailMsg next determines there is another validate data field exit pointprogram, VALIDAT2, that validates MSF list entries with a 03A1 data type.

Figure 70 shows that QzmfChgMailMsg calls exit point program VALIDAT2 at

.

VALIDAT2 is configured so that it is always called whenever any MSF list entrywith a 03A1 data type is passed. The envelope list being passed toQzmfChgMailMsg has an entry with this data type. This entry is passed toVALIDAT2 when it is called by MSF QzmfChgMailMsg.

VALIDAT2 validates the envelope with data type 03A1 . In this example,VALIDAT2 approves the envelope it was passed. It returns with a return code of

Chapter 6. Mail Server Framework Exit Points 131

Page 156: AnyMail/400 Mail Server Framework Developer Guide January 1995

0 to tell QzmfChgMailMsg that the envelope that was passed is valid and thechange of the message may proceed.

When VALIDAT2 returns to MSF, Figure 68 on page 128 shows thatQzmfChgMailMsg determines there are no other validate data field exit pointprograms that it must call.

In this example, there is only one other program, VALIDAT3. The messageinformation passed in parameters to QzmfChgMailMsg does not have any listentries with the MSF data type that VALIDAT3 validates. Program VALIDAT3 isnot called.

The QzmfChgMailMsg has considered all the validation programs configured. Ithas called those that it should call. Every validate data field exit point programthat was called approved of the information in the list entries that were passedto them.

QzmfChgMailMsg can now proceed to change the MSF message as shown in

Figure 68 on page 128 at .

Not shown in this example is what happens when a validate data field exit pointprogram determines that the list entries it was passed are not valid.

To indicate that data types it validates are not valid, the validation exit pointprogram has to set the return code to 1. QzmfChgMailMsg does not change themessage. It reports an error to the exit point program that called theQzmfChgMailMsg API. The error indicates that there was a validate data fieldexit point program that prevented MSF from making the change.QzmfChgMailMsg returns this validation program name and any informationfrom the program.

132 AnyMail/400 MSF

Page 157: AnyMail/400 Mail Server Framework Developer Guide January 1995

Chapter 7. Summary of the Mail Server Framework APIs

The MSF application programming interfaces (APIs) are grouped into twocategories:

• MSF configuration APIs for managing the MSF configuration.• MSF message APIs for managing specific MSF messages.

Table 15 and Table 16 list the MSF APIs, what each API does, and which chaptercontains a description of each API.

Table 15. MSF Configuration API Descriptions

API Name What the API Does Reference Chapter

QzmfAddMailCfgAdds a type definition to theMSF configuration

Chapter 3, “Mail ServerFramework Configuration” onpage 18

QzmfLstMailCfgLists the defined MSF datatypes

Chapter 3, “Mail ServerFramework Configuration” onpage 18

QzmfRmvMailCfgRemoves an MSF data typedefinition

Chapter 3, “Mail ServerFramework Configuration” onpage 18

Table 16. MSF Message API Descriptions

API Name What It Does Reference Chapter

QzmfChgMailMsg Changes an MSF messageChapter 12, “Changing a MailMessage” on page 172

QzmfCrtCmpMailMsgCompletes creation sequenceof reserved message

Chapter 13, “Other MessageAPIs” on page 178

QzmfCrtMailMsg Creates an MSF messageChapter 10, “Creating a MailMessage” on page 163

QzmfQryMailMsgIdQueries an MSF messageidentifier

Chapter 13, “Other MessageAPIs” on page 178

QzmfRmvRsvMailMsgIdRemoves a reserved MSFmessage identifier

Chapter 13, “Other MessageAPIs” on page 178

QzmfRsvMailMsgIdReserves an MSF messageidentifier

Chapter 13, “Other MessageAPIs” on page 178

QzmfRtvMailMsg Retrieves an MSF messageChapter 11, “Retrieving MailMessage Information” onpage 168

Copyright IBM Corp. 1995 133

Page 158: AnyMail/400 Mail Server Framework Developer Guide January 1995

Configurations APIsFigure 71 shows how the MSF configuration can be accessed by the APIs. TheAdd Mail Server Framework Configuration (QzmfAddMailCfg) API adds a newMSF data type definition to the MSF configuration. The Remove Mail ServerFramework Configuration (QzmfRmvMailCfg) API removes an existing data typedefinition from the MSF configuration. The List Mail Server FrameworkConfiguration (QzmfLstMailCfg) API lists the data type that are currently definedin the MSF configuration.

Figure 71. MSF Configuration APIs Accessing MSF Configuration

Message APIsFigure 72 on page 135 shows an example of an MSF message being createdand flowing through the framework. Although this example shows the APIsbeing used from the address resolution and accounting exit points, the APIs canbe used from other exit points as well. The following steps describe the actionsthat are being taken in the example.

134 AnyMail/400 MSF

Page 159: AnyMail/400 Mail Server Framework Developer Guide January 1995

Figure 72. Programs Using MSF Message APIs to Manage an MSF Message

In step 1, the Create Mail Message (QzmfCrtMailMsg) API creates a single MSFmessage and puts it on the MSF queue. The MSF message, A, is taken from theMSF queue by a QMSF job in step 2. The QMSF job begins processing the MSFmessage by passing its information to the appropriate exit point programs.

In step 3, the MSF message′s information is passed to the appropriate addressresolution exit point program. This exit point program uses the Change MailMessage (QzmfChgMailMsg) API to change MSF message A. This example doesnot specify what was changed in the MSF message. For example, there may

Chapter 7. Summary of the Mail Server Framework APIs 135

Page 160: AnyMail/400 Mail Server Framework Developer Guide January 1995

have been a change in the recipient list. Step 4 shows the resulting MSFmessage being returned to the framework.

MSF continues to process the message, proceeding to pass the message′sinformation to the appropriate exit point programs at each of the MSF exit points.In step 5, the MSF message is given to the appropriate accounting exit pointprogram. This exit point program uses the Retrieve Mail Message(QzmfRtvMailMsg) API to obtain information about the MSF message. Theinformation obtained can then be used for accounting purposes. Step 6 showsthe MSF message returning to the framework to finish processing. Finally, step 7shows the completed MSF message being discarded by MSF.

More detailed information about the MSF application programming interfacescan also be found in System API Reference.

136 AnyMail/400 MSF

Page 161: AnyMail/400 Mail Server Framework Developer Guide January 1995

Chapter 8. Mail Server Framework Configuration APIs

This chapter describes the mail server framework configuration APIs, each of theAPI parameters, and the formats of these APIs.

Add Mail Server Framework Configuration (QzmfAddMailCfg) APIThe Add Mail Server Framework Configuration (QzmfAddMailCfg) API adds adata type definition to the mail server framework configuration.

Parameters

Required Parameter Group:

Service Program: QZMFASRV

1 Type configuration Input Char(*)2 Format name Input Char(8)3 Error code I/O Char(*)

Required Parameter GroupType configuration

INPUT; CHAR(*)A pointer to the structure that contains the information used for the mailserver framework data type that is being defined. This structure uses theADDC0100 format.

Format nameINPUT; CHAR(8)The format name of the structure that is being used for the type configurationparameter. This must be set to ADDC0100.

Error codeI/O; CHAR(*)A pointer to the structure in which error information will be returned. Fordetailed information about this structure, see the System API Reference.

ADDC0100 FormatThe following table shows the layout of the parameter structure for theADDC0100 format. For a detailed description of each field, see “Add MSFConfiguration API Field Descriptions” on page 138.

Table 17 (Page 1 of 2). ADDC0100 Format

Offset

Type FieldDec Hex

0 0 BINARY(4) Length of structure

4 4 CHAR(2) Type group

6 6 CHAR(4) Type value

10 A CHAR(8) Type name

18 12 CHAR(2) Reserved (must be blank)

Copyright IBM Corp. 1995 137

Page 162: AnyMail/400 Mail Server Framework Developer Guide January 1995

Table 17 (Page 2 of 2). ADDC0100 Format

Offset

Type FieldDec Hex

20 14 BINARY(4) Type text coded character set identifier (CCSID)

24 18 CHAR(100) Type text

Add MSF Configuration API Field DescriptionsLength of structure . The length in bytes of the type configuration parameter.This is the length of the ADDC0100 format structure, which is 124 bytes.

Reserved . This field is reserved for future use and must be set to blanks.

Type group . The type group in which the data type definition will reside. “MSFData Types” on page 18 contains information on the allowed values. As manayas 128 different data type definitions can be configured for each type group.

Type name . The name of the data type that is being configured. This is a unique8-character mnemonic representation. “Rules for MSF Data Type Definitions” onpage 19 contains information on the allowed values.

Type text . The description of the data type that is being configured. If this fieldis not used, it is set to blanks. “Rules for MSF Data Type Definitions” onpage 19 contains information on the allowed values.

Type text coded character set identifier (CCSID) . The coded character setidentifier (CCSID) of the type text field. Valid CCSID values for this field are 1through 65533 and 65535. If this field is set to zero, the job CCSID is used.

Type value . The value of the data type that is being configured. This is a unique4-character representaion of the data type. “Rules for MSF Data TypeDefinitions” on page 19 contains information on the allowed values.

Examples for Add Mail Configuration APIThe following sections of code are examples that you can use in your programfor calling the Add MSF Configuration API. A complete program example can befound in Appendix E, “An MSF Application — Example” on page 294. Completeexamples for format structures and program calls can be found in Appendix G,“Qzmfasrv Header File” on page 375.

This is a type definition for the ADDC0100 format.

/*********************************************************************//* Type Definition for the ADDC0100 Format *//*********************************************************************/

typedef _Packed struct Qzmf_ADDC0100{

long int Param_List_Length;Qzmf_Type_Group_t Type_Group;Qzmf_Type_Value_t Type_Value;Qzmf_Type_Name_t Type_Name;char Reserved[2];Qzmf_CCSID_t CCSID;

138 AnyMail/400 MSF

Page 163: AnyMail/400 Mail Server Framework Developer Guide January 1995

char Type_Text[100];} Qzmf_ADDC0100_t;

This is a prototype for calling the Add MSF Configuration API.

/*********************************************************************//* Prototype for calling Add Mail Server Framework Configuration *//* (QzmfAddMailCfg) API *//*********************************************************************/

void QzmfAddMailCfg(void *, /* Type Configuration */char *, /* Format Name */void * /* API Returned Error */

);

Chapter 8. Mail Server Framework Configuration APIs 139

Page 164: AnyMail/400 Mail Server Framework Developer Guide January 1995

Remove Mail Server Framework Configuration (QzmfRmvMailCfg) APIThe Remove Mail Server Framework Configuration (QzmfRmvMailCfg) APIremoves a data type definition from the mail server framework configuration.

Parameters

Required Parameter Group:

Service Program: QZMFASRV

1 Type configuration Input Char(*)2 Format name Input Char(8)3 Error code I/O Char(*)

Required Parameter GroupType configuration

INPUT; CHAR(*)The structure that contains the information used for the mail serverframework data type that is being removed. The structure used is theDLTC0100 format.

Format nameINPUT; CHAR(8)The format name of the structure that is being used for the type configurationparameter. This must be set to DLTC0100.

Error codeI/O; CHAR(*)The structure in which error information will be returned. For detailedinformation about this structure, see the System API Reference.

DLTC0100 FormatThe following table shows the layout of the parameter structure for DLTC0100format. For a detailed description of each field, see the “Remove MSFConfiguration Field Descriptions.”

Table 18. DLTC0100 Format

Offset

Type FieldDec Hex

0 0 BIN(4) Length of structure

4 4 CHAR(2) Type group

6 6 CHAR(4) Type value

10 A CHAR(8) Type name

Remove MSF Configuration Field DescriptionsLength of structure . The length in bytes of the remove mail configurationparameter list. This is the length of the DLTC0100 format which is 18 bytes.

Type group . The type group in which the type definition to be removed resides.“MSF Data Types” on page 18 contains information on the allowed values.

140 AnyMail/400 MSF

Page 165: AnyMail/400 Mail Server Framework Developer Guide January 1995

Type name . The name of the data type that is being removed. This is a unique,8-character mnemonic representation. “Rules for MSF Data Type Definitions” onpage 19 contains information on the allowed values.

Type value . The value of the data type that is being removed. This is a unique,4-character representation of the data type. “Rules for MSF Data TypeDefinitions” on page 19 contains information on the allowed values.

Examples for Remove Mail Configuration APIThe following sections of code are examples that you can use in your programfor calling the Remove MSF Configuration API. A complete program examplecan be found in Appendix E, “An MSF Application — Example” on page 294.Complete examples for format structures and program calls can be found inAppendix G, “Qzmfasrv Header File” on page 375.

This is a type definition for the DLTC0100 format.

/*********************************************************************//* Type Definition for the DLTC0100 Format *//*********************************************************************/

typedef _Packed struct Qzmf_DLTC0100{

long int Param_List_Length;Qzmf_Type_Group_t Type_Group;Qzmf_Type_Value_t Type_Value;Qzmf_Type_Name_t Type_Name;

} Qzmf_DLTC0100_t;

This is a prototype for calling the Remove MSF Configuration API.

/*********************************************************************//* Prototype for calling Remove Mail Server Framework Configuration *//* (QzmfRmvMailCfg) API *//*********************************************************************/

void QzmfRmvMailCfg(void *, /* Type Configuration */char *, /* Format Name */void * /* API Returned Error */

);

Chapter 8. Mail Server Framework Configuration APIs 141

Page 166: AnyMail/400 Mail Server Framework Developer Guide January 1995

List Mail Server Framework Configuration (QzmfLstMailCfg) APIThe List Mail Server Framework Configuration (QzmfLstMailCfg) API creates alist of data type definitions and places the list in a specified user space. You canspecify a group of data type definitions, a single data type definition, or all datatype definitions. The generated list replaces any existing data in the user space.The user space must exist before calling this API. You will need the followingauthorities:

User Space Authority *CHANGELibrary Authority *USEUser Space Lock *EXCLRD

Parameters

Required Parameter Group:

Service Program: QZMFASRV

1 Qualified user space name Input Char(20)2 Format name Input Char(8)3 Type configuration format name Input Char(8)4 Type configuration Input Char(*)5 Error code I/O Char(*)

Required Parameter GroupQualified user space name

INPUT; CHAR(20)The name of the user space where you want data type definition informationto be placed. The first 10 characters contain the user space name, and thesecond 10 characters contain the name of the library where the user spaceis located. You can use these special values for the library name:

*CURLIB The job′s current library*LIBL The library list

Format nameINPUT; CHAR(8)The name of the format in which data will be returned. The name that youuse in this parameter tells the API how to place the data in the user space.This must be set to LSTL0100.

Type configuration format nameINPUT; CHAR(8)The format name of the structure that is used for the type configurationparameter. This must be set to LSTC0100.

Type configurationINPUT; CHAR(*)The structure that contains the information used for the mail serverframework data type definition that is being listed. The structure used is theLSTC0100 format.

Error codeI/O; CHAR(*)The structure in which error information will be returned. For detailedinformation about this structure, see System API Reference.

142 AnyMail/400 MSF

Page 167: AnyMail/400 Mail Server Framework Developer Guide January 1995

LSTL0100 FormatThe list generated by this API consists of the following:

A user areaA generic headerList data section

When you retrieve list entry information from a user space, you must use theentry size that is returned in the generic header. The size of each entry may bepadded at the end. If you do not use the entry size, the result may not be valid.For detailed information on how to process lists in a user space, see System APIReference.

The following table shows the layout of the parameter structure for LSTL0100format. For a detailed description of each field, see “List MSF FieldDescriptions.”

Table 19. LSTL0100 Format

Offset

Type FieldDec Hex

0 0 CHAR(2) Type group

2 2 CHAR(4) Type value

6 6 CHAR(8) Type name

14 E CHAR(2) Reserved

16 10 BINARY(4) Type text coded character set identifier (CCSID)

20 14 CHAR(100) Type text

LSTC0100 FormatThe following table shows the LSTC0100 format that is used to select the datatype definition to be listed. You can use this table to selectively retrieve datatype definitions. If the data that is entered in any of the fields is not valid, errormessage CPFAFB0 is generated. If no matching entries are found, errormessage CPFAFB1 is generated.

Table 20. LSTC0100 Format

Offset

Type FieldDec Hex

0 0 BINARY(4) Length of structure

4 4 CHAR(2) Selection type group

6 6 CHAR(4) Selection type value

10 A CHAR(8) Selection type name

List MSF Field DescriptionsLength of structure . The length in bytes of the list mail configuration selectionlist. This is the length of the LSTC0100 format, which is 18.

Reserved . This field is reserved for future use and must be set to blanks.

Chapter 8. Mail Server Framework Configuration APIs 143

Page 168: AnyMail/400 Mail Server Framework Developer Guide January 1995

Selection type group . This field is the type group that the data type definition tolist belongs to. The following are possible values:

01 Address type02 Message type03 Envelope type04 Attachment reference typeblank List data type definitions that match the other selection criteria without

using the selection type group as a selection criteria. If the type group isblank, the type value and type name cannot be blank.

Selection type name . The name of the data type definition to list. If the typename is set to blank, other selection criteria are used. If this filed is set to blank,the selection type value must also be blank, and the selection type group mustnot be blank. This would list all data type definitions of a specific type group.

Selection type value . The value of the data type definition to list. If the typevalue is set to blank, other selection criteria are used. If this field is set to blank,the selection type name must also be blank, and the selection type group mustnot be blank. This would list all data type definitions of a specific type group.

Type group . This is the type group of the data type definition that matched theselection criteria. “Rules for MSF Data Type Definitions” on page 19 containsinformation on the allowed values.

Type name . The name of the data type definition that matched the selection theselection criteria. “Rules for MSF Data Type Definitions” on page 19 containsinformation on the allowed values.

Type text . The description of the data type definition that matched the selectioncriteria. “Rules for MSF Data Type Definitions” on page 19 contains informationon the allowed values.

Type text coded character set identifier (CCSID) . The coded character setidentifier (CCSID) of the type text for the data type definition that matched theselection criteria.

Type value . The value of the data type definition that matched the selectioncriteria. “Rules for MSF Data Type Definitions” on page 19 contains informationon the allowed values.

Examples for List Mail Configuration APIThe following sections of code are examples that you can use in your programfor calling the List MSF Configuration API. A complete program example can befound in Appendix E, “An MSF Application — Example” on page 294. Completeexamples for format structures and program calls can be found in Appendix G,“Qzmfasrv Header File” on page 375.

This is a type definition for the LSTC0100 format.

/*********************************************************************//* Type Definition for the LSTC0100 Format *//*********************************************************************/

typedef _Packed struct Qzmf_LSTC0100{

long int Sel_List_Length;

144 AnyMail/400 MSF

Page 169: AnyMail/400 Mail Server Framework Developer Guide January 1995

Qzmf_Type_Group_t Type_Group;Qzmf_Type_Value_t Type_Value;Qzmf_Type_Name_t Type_Name;

} Qzmf_LSTC0100_t;

This is a type definition for the LSTL0100 format.

/*********************************************************************//* Type Definition for the LSTL0100 Format *//*********************************************************************/

typedef _Packed struct Qzmf_LSTL0100{

Qzmf_Type_Group_t Type_Group;Qzmf_Type_Value_t Type_Value;Qzmf_Type_Name_t Type_Name;char Reserved[2];Qzmf_CCSID_t CCSID;char Type_Text[100];

} Qzmf_LSTL0100_t;

This is a prototype for calling the List MSF Configuration API.

/*********************************************************************//* Prototype for calling List Mail Server Framework Configuration *//* (QzmfLstMailCfg) API *//*********************************************************************/

void QzmfLstMailCfg(void *, /* User Space Name */char *, /* List Format Name */char *, /* Format Name */void *, /* Type Configuration */void * /* API Returned Error */

);

Chapter 8. Mail Server Framework Configuration APIs 145

Page 170: AnyMail/400 Mail Server Framework Developer Guide January 1995

Chapter 9. Working with Mail Message Lists

This chapter explains how to define and construct a list for an MSF message inILE C/400. An MSF message list is a list of information which is associated witha specific message. Mail applications use lists to create, retrieve and changeinformation contained in a message. An MSF message list is a key structurethat one must understand to successfully work with the mail server framework.This chapter explains MSF message lists, the different types of lists and howthey are used with the mail server framework APIs.

MSF Message List − IntroductionAn MSF message list is a structure that contains information that is associatedwith a specific message. The structure of the MSF message list is made up of aheader followed by the individual list entries.

The header defines the format for the following information that is to be found inthe list:

• The number of entries in the list.

• The size of the space containing the list.

• The offset to the first entry in the list,

It should not be assumed that the header is followed immediately by the firstentry in the list. The offset of the first entry should always be used to get thefirst entry in the list. When the QzmfRtvMailMsg API is used, the messagedescriptor entry also contains the number of bytes of information available for aparticular message list. For further information on the QzmfRtvMailMsg API, seeChapter 11, “Retrieving Mail Message Information” on page 168.

The format of the individual entries in a list is defined in the header of the MSFmessage list. This format not only defines the format of the information but alsodeclares the list being passed. Following is a list of the different formats foreach list:

ORCL0100 Original recipient entryORGL0100 Originator entryENVL0100 Envelope entryRCPL0100 Recipient entryRCHL0100 Recipient history entryROAL0100 Report-on entryRPYL0100 Reply-to entryRTAL0100 Report-to entryATTL0100 Attachment reference entryMSGL0100 Message types in the recipient list entriesEXCH0100 Exit call history entryCRTA0100 Creation attributes entry

Currently only one format is defined for each type of list. In the future, additionalformats may be defined for a particular list. The format name would be used todistinguish one format from another.

All of the individual entries in the list must be in contiguous storage, one rightafter the other. Individual entries contain fields of fixed lengths and fields of

146 Copyright IBM Corp. 1995

Page 171: AnyMail/400 Mail Server Framework Developer Guide January 1995

variable lengths used for individual entries. The variable length fields follow thefixed length fields in the structure. The fields with variable lengths are precededby a field which defines the length of the entry in the list. Applications can usepointers to traverse the entries in the list. The length of each entry can be usedto advance the pointer to the next entry. For additional information about thecontents of a message, see Chapter 5, “Mail Server Framework Message” onpage 44.

When working with lists in an MSF message, there are two structures that youshould understand. They are the message descriptor array and the messagelist.

The relationship between the message descriptor array and the message list isshown in Figure 73 which shows only four commonly used lists.

Figure 73. Message Descriptor Array and Message List. This shows only recipient list expansion. The other listsare not expanded.

The message descriptor array and message list relationship is used in severaldifferent aspects of MSF, including:

• When a message is created using the QzmfCrtMailMsg API.

• When a message is changed using the QzmfChgMailMsg API.

• When message information is passed to an exit point program.

• When message information is retrieved using the QzmfRtvMailMsg API.

Chapter 9. Working with Mail Message Lists 147

Page 172: AnyMail/400 Mail Server Framework Developer Guide January 1995

Each of these uses is described in the topics that follow.

Defining MSF Message Lists in ILE C/400The message list structures that contain variable length data have to be definedin a special way because the length of the variable data is undefined. In definingthe structure in ILE C/400, a maximum length needs to be specified so that thestructure can be defined. The remaining topics in this chapter will demonstratehow an application can use the description of the type structures. These areprovided in the header file H in library QSYSINC member QZMF to define theindividual entry structures for the variable field data.

Defining a Recipient ListThe recipient list structure is defined in QZMF as follows:

/*********************************************************************//* Type Definition for the RCPL0100 Format *//**** ****//* NOTE: The following type definition only defines the fixed *//* portion of the format. Any varying length field will *//* have to be defined by the user. *//*********************************************************************/

typedef _Packed struct Qzmf_RCPL0100{

long int Entry_Length;long int SPIN_Displacement;long int SPIN_Length;long int Recipient_Displacement;long int Addr_Length;Qzmf_Type_Value_t Addr_Type;Qzmf_CCSID_t CCSID;long int Reason_Code;long int Diag_Code;Qzmf_Type_Value_t Msg_Type;long int Status;long int Dist_Type;long int Unique_Id;long int Reserved;

/*char Recipient_Addr[];*/ /* varying length */ /*char SPIN[];*/ /* varying length */ } Qzmf_RCPL0100_t;

/*********************************************************************//* Type Definition for the RCPL0100 Message Descriptor *//**** ****//* NOTE: The following type definition only defines the fixed *//* portion of the format. Any varying length field will *//* have to be defined by the user. *//*********************************************************************/

typedef _Packed struct Qzmf_Rcpt0100_Msg_Desc{

Qzmf_Msg_Desc_Hdr0100_t Msg_Desc_Hdr; /*Qzmf_RCPL0100_t Recipient[];*/ /* varying length */} Qzmf_Rcpt0100_Msg_Desc_t;

148 AnyMail/400 MSF

Page 173: AnyMail/400 Mail Server Framework Developer Guide January 1995

Creating a Recipient ListThe following section of code is an example of how to create a recipient list withone entry (a distribution list entry). Similar procedures can be used to createthe other lists associated with an MSF message. For a complete example, seeAppendix E, “An MSF Application — Example” on page 294.

/**********************************************************************//* Create_Recipient_Descriptor function creates our test Recipient *//* List which contains our test Distribution List; it also places the *//* relevant Recipient-List information in the Message Descriptor *//* Attribute Array. *//**********************************************************************/

static void Create_Recipient_Descriptor(void

){

intRecipient_Length = strlen(TEST_DL)

, Rcpnt_Size = sizeof(Qzmf_Msg_Desc_Hdr0100_t) + /* No SPIN is */sizeof(Qzmf_RCPL0100_t) + /* present */Recipient_Length /* during Msg */

; /* creation */

Qzmf_RCPL0100_t*RcpntP;

/****************************************************************//* Allocate space for the Recipient Descriptor. Note that we *//* are not considering SPIN at this moment of message creation. *//* SPIN can optionally be placed by Snap_Ins in the descriptor *//* elements. However the message creator can also specify SPIN *//* if it is necessary for any particular application after *//* allocating sufficiant space; MSF is flexible enough to allow *//* SPIN during message creation. *//****************************************************************/

WalkP = (char *)malloc( Rcpnt_Size);

if (WalkP == NULL){

printf(″Quitting, malloc error in creating RCPL\n″ ) ;exit(1);

}

/* Fill up the proper Message Descriptor Array element for the *//* Recipient List to be created */(Msg_Desc_Attr_Array + Recipient) -> Msg_Desc_Ptr = (_SPCPTR)(WalkP);(Msg_Desc_Attr_Array + Recipient)-> Msg_Desc_Length = Rcpnt_Size;memcpy( (Msg_Desc_Attr_Array + Recipient) -> Msg_Desc_Format_Name,

QZMF_RECIPIENT_LIST_FMT, QZMF_MSG_DESC_FMT_LENGTH );(Msg_Desc_Attr_Array + Recipient) -> Reserved = 0;

Chapter 9. Working with Mail Message Lists 149

Page 174: AnyMail/400 Mail Server Framework Developer Guide January 1995

/* Next fill up the Header of the Recipient List */List_HdrP = (Qzmf_Msg_Desc_Hdr0100_t *)WalkP;

List_HdrP -> Msg_Desc_Total_Length = Rcpnt_Size;List_HdrP -> Bytes_Available = 0;memcpy( List_HdrP -> Msg_Desc_Format_Name,QZMF_RECIPIENT_LIST_FMT,

QZMF_MSG_DESC_FMT_LENGTH );List_HdrP -> First_Entry_Offset = sizeof(Qzmf_Msg_Desc_Hdr0100_t);List_HdrP -> Total_Num_Of_Entries = 1;List_HdrP -> Reserved = 0;

/* As the final step create the single element Recipient List *//* consisting of a test ″distribution list name″ */RcpntP = (Qzmf_RCPL0100_t *)(List_HdrP + 1);

RcpntP -> Entry_Length = sizeof(Qzmf_RCPL0100_t) +Recipient_Length;

RcpntP -> SPIN_Displacement = 0; /* Since there is no SPIN theDisp, should be set to 0 */

RcpntP -> SPIN_Length = 0;RcpntP -> Recipient_Displacement = sizeof(Qzmf_RCPL0100_t);RcpntP -> Addr_Length = Recipient_Length;memcpy( RcpntP -> Addr_Type, TEST_ADDRESS_TYPE_VALUE,

sizeof(Qzmf_Type_Value_t) );RcpntP -> CCSID = DEFAULT_CCSID;RcpntP -> Reason_Code = 0;RcpntP -> Diag_Code = 0;

/*********************************************************//* During the creation of the message we are setting the *//* ZERO values in the following two fields. In a typical*//* scenario these two fields will be set to *//* proper values by the Exit Point Program in the *//* Address Resolution exit point. *//*********************************************************/memcpy( RcpntP -> Msg_Type, NULL_MSG_TYPE,

sizeof(Qzmf_Type_Value_t) );RcpntP -> Status = NULL_RCPT_STATUS;

RcpntP -> Dist_Type = QZMF_DIST_TYPE_NORMAL; /* Normal Dist. Type *//* assumed */

RcpntP -> Unique_Id = 0;RcpntP -> Reserved = 0;

/* Now set the actual Recipient (Dist-List) name */WalkP = (char *)(RcpntP + 1);memcpy(WalkP, TEST_DL, Recipient_Length);

} /* end of Create_Recipient_Descriptor function */

150 AnyMail/400 MSF

Page 175: AnyMail/400 Mail Server Framework Developer Guide January 1995

Handling Variable Length FieldsIt should be noted that the Recipient_Addr varying length string of data iscommented out in the Qzmf_RCPL0100_t typedef. You can decide how best thisinformation can be defined. Some of the possibilities include the following:

Define a separate typedef for the information: In this case, to access theinformation for a specific recipient, the program has to find the specific entry it islooking for based on the address data type (Addr_Type). Once the programfinds the entry in the list, it can then set a pointer by using the offset field,Recipient_Displacement, and then cast the pointer to the defined typedef.Because the address and spin data can be variable length, the use of thedisplacement fields is the preferred method of addressing the data.

Although this topic describes some alternatives when defining your use of therecipient entry, applying this to other data that is contained in an MSF messageis similar. This includes items such as the envelope data and the attachmentreference data. You can define typedefs that are either part of the entrydefinition or a separate typedef to handle the variable portion of the entrydefinition.

For example, if the recipient address for a particular type is always a fixed size,say 16 bytes, and the SPIN is also fixed size, say 32 bytes, then the followingtypedefs could be used:

typedef _Packed struct{

char Address[16];} Recipient_Address_t;

typedef _Packed struct{

char Spin[32];} Recipient_Spin_t;

For an example of separate typedefs, see the Create_Attachment_Descriptor inAppendix E, “An MSF Application — Example” on page 294.

To get the recipient address and spin information, the following code could beused:

Recipient_Address_t *Rcp_AddrP;Recipient_Spin_t *Rcp_SpinP;

Recipient_Address_t Current_Address;Recipient_Spin_t Current_Spin;

WalkP = ((char *)RcpntP) + Recipient_Displacement;Rcp_AddrP = (Recipient_Address_t*)WalkP;memcpy(Current_Address.Address,Rcp_AddrP->Address,16);

WalkP = ((char *)RcpntP) + SPIN_Displacement;Rcp_SpinP = (Recipient_Spin_t*)WalkP;memcpy(Current_Spin.Spin,Rcp_SpinP->Spin,32);

Chapter 9. Working with Mail Message Lists 151

Page 176: AnyMail/400 Mail Server Framework Developer Guide January 1995

Define combined typedefs: For a slightly different way of defining a recipiententry, again assuming fixed sizes for the address and spin, a new typedef couldbe used. For example:

typedef _Packed struct{

Qzmf_RCPL0100_t Recipient_entry;char Recipient_Address[16];char Recipient_Spin[32];

} Recipient_t;

To get the recipient address and spin information, the following code could beused:

Recipient_t *Rcp_EntryP;

Recipient_Address_t Current_Address;Recipient_Spin_t Current_Spin;

Rcp_EntryP = (Recipient_t*)WalkP;memcpy(Some_Local_Address,Rcp_EntryP->Recipient_Address,16);memcpy(Some_Local_Spin,Rcp_SpinP->Recipient_Spin,32);

In addition to defining separate or combined type definitions, there can beadditional ways of defining the structures you use. You should consider howyour mail applications use this information. Consider if the data is fixed lengthor variable length and whether your application processes multiple types of data.

Building MSF Message Descriptor Arrays in ILE C/400When MSF message list structures are used to pass information between themail server framework and an application, a pointer to an array of messagedescriptors and the number of message descriptors in the array is passed. Amessage descriptor array element, as shown in Figure 73 on page 147, containsa pointer to a message list, the length of the list, and the name of the list format.The type definition for a message descriptor array element is given below. Itcan be found in the Qzmf header file, see Appendix F, “Qzmf Header File” onpage 356 for more information.

typedef _Packed struct Qzmf_Msg_Desc_Attrbt_Entity{

_SPCPTR Msg_Desc_Ptr;long int Msg_Desc_Length;Qzmf_Format_Name_t Msg_Desc_Format_Name;long int Reserved;

} Qzmf_Msg_Desc_Attrbt_Entity_t;

Msg_Desc_Ptr A space pointer to the message descriptor that contains dataassociated with the message.

Msg_Desc_Length The length, in bytes, of the message descriptor that is pointedto by the Msg_Desc_Ptr field. The value of this field must match thelength field in the header of the message list.

152 AnyMail/400 MSF

Page 177: AnyMail/400 Mail Server Framework Developer Guide January 1995

Msg_Desc_Format_Name The format name associated with the data in themessage list. The value of this field must match the value of theformat name field in the message list header. A format name mayappear only once in a message descriptor array.

Reserved This variable must be set to zero.

Building a Message Descriptor ArrayThe following section of code is an example of how to build a messagedescriptor array that is used with the Create Mail Message API.

static Qzmf_Msg_Desc_Attrbt_Entity_tMsg_Desc_Attr_Array[NUM_CRT_ATTRBT];

.

.

.

/* Fill the proper message descriptor array element for the */ /* originator list to be created */ (Msg_Desc_Attr_Array + Originator) -> Msg_Desc_Ptr =

(_SPCPTR)(WalkP); (Msg_Desc_Attr_Array + Originator) -> Msg_Desc_Length = Org_Size; memcpy( (Msg_Desc_Attr_Array + Originator) -> Msg_Desc_Format_Name,

QZMF_ORIGINATOR_LIST_FMT, QZMF_MSG_DESC_FMT_LENGTH ); (Msg_Desc_Attr_Array + Originator) -> Reserved = 0;

.

.

.

/* Fill the proper message descriptor array element for the */ /* envelope list to be created */ (Msg_Desc_Attr_Array + Envelope) -> Msg_Desc_Ptr = (_SPCPTR)(WalkP); (Msg_Desc_Attr_Array + Envelope) -> Msg_Desc_Length = Env_Size; memcpy( (Msg_Desc_Attr_Array + Envelope) -> Msg_Desc_Format_Name,

QZMF_ENVELOPE_LIST_FMT, QZMF_MSG_DESC_FMT_LENGTH ); (Msg_Desc_Attr_Array + Envelope) -> Reserved = 0;

Note that each list has a message descriptor built into the array of messagedescriptors that is to be passed to the QzmfCrtMailMsg API. A pointer to themessage descriptor array is then passed to the API. In this example, themessage descriptor array is used when creating an MSF message. This canalso be applied when a message is given to an exit point program to process orwhen message information is retrieved using the QzmfRtvMailMsg API.

Using MSF Message Lists to Create a MessageWhen a message is created, the Create Mail Message API is passed messagelists that make up the message. The following lists can be passed to the CreateMail Message API.

ORCL0100 Original recipient listORGL0100 Originator list

Chapter 9. Working with Mail Message Lists 153

Page 178: AnyMail/400 Mail Server Framework Developer Guide January 1995

ENVL0100 Envelope listRCPL0100 Recipient listROAL0100 Report-on listRPYL0100 Reply-to listRTAL0100 Report-to listATTL0100 Attachment reference list

The originator list, the recipient list, and the envelope list are required for amessage to be created. The other lists are optional.

It is suggested that the original recipient list be passed because it is assumed tocarry the recipient list that was used when the message was originally created.This may be different from the recipient list in cases where the message isfanned out to different systems. Some recipients are delivered locally on asystem while others are forwarded to a remote system. In this case, therecipient list that the remote system receives contains only the names that theremote system is going to handle, whereas the original recipient list contains thecomplete list of recipients.

An example of where this may be useful is when the E-mail message is shown toa user. The user may want to determine all of the recipients that received theE-mail message. This list could then be used to create a reply that the usercould send to all of the recipients that received the original E-mail message.

Once the message lists have been created as described in “Defining MSFMessage Lists in ILE C/400” on page 148 and they have been identified in themessage descriptor array as shown in “Building MSF Message DescriptorArrays in ILE C/400” on page 152, we can call the QzmfCrtMailMsg API asshown in the following code:

/*********************************************************************//* Now Create the Message *//*********************************************************************/

QzmfCrtMailMsg((void *)(Mail_Msg_Id), (void *)(R_Msg_Id), Crt_Msg_Type, (void *)Msg_Desc_Array, &Num_Msg_Desc_Attr, Crt_Format_Name, (void *)(&Crt_Error_Code)

);...

For additional information on the QzmfCrtMailMsg API and a description of theparameters, see Chapter 10, “Creating a Mail Message” on page 163.

154 AnyMail/400 MSF

Page 179: AnyMail/400 Mail Server Framework Developer Guide January 1995

Working with MSF Message Lists Passed to Exit Point ProgramsWhen an exit point program is called, it is passed a number of message lists.These lists contain information that the exit point program may need to use. Thelists passed to specific exit point programs are listed in the following table.

Exit Point Name Message Lists Passed

QIBM_QZMFMSF_LST_EXP RCPL0100 - Recipient ListENVL0100 - Envelope List

QIBM_QZMFMSF_ADR_RSL RCPL0100 - Recipient ListENVL0100 - Envelope ListORGL0100 - Originator ListRTAL0100 - Report-to ListROAL0100 - Report-on ListRPYL0100 - Reply-to ListORCL0100 - Original Recipient List

QIBM_QZMFMSF_ENL_PSS MSGL0100 - Message Type ListRCPL0100 - Recipient ListROAL0100 - Report-on ListENVL0100 - Envelope ListATTL0100 - Attachment Reference ListRTAL0100 - Report-to ListRPYL0100 - Reply-to ListORCL0100 - Original Recipient ListORGL0100 - Originator List

QIBM_QZMFMSF_ATT_CNV MSGL0100 - Message Type ListRCPL0100 - Recipient ListATTL0100 - Attachment Reference ListENVL0100 - Envelope List

QIBM_QZMFMSF_SEC_AUT RCPL0100 - Recipient ListATTL0100 - Attachment Reference ListORGL0100 - Originator List

QIBM_QZMFMSF_LCL_DEL RCPL0100 - Recipient ListENVL0100 - Envelope ListATTL0100 - Attachment Reference ListORGL0100 - Originator ListROAL0100 - Report-on ListRTAL0100 - Report-to ListRPYL0100 - Reply-to ListORCL0100 - Original Recipient ListCRTA0100 - Creation Attributes

QIBM_QZMFMSF_MSG_FWD RCPL0100 - Recipient ListENVL0100 - Envelope ListATTL0100 - Attachment Reference ListORGL0100 - Originator ListROAL0100 - Report-on ListRTAL0100 - Report-to ListRPYL0100 - Reply-to ListORCL0100 - Original Recipient ListCRTA0100 - Creation Attributes

QIBM_QZMFMSF_NON_DEL RCPL0100 - Recipient ListENVL0100 - Envelope ListATTL0100 - Attachment Reference ListORGL0100 - Originator ListRTAL0100 - Report-to List

Chapter 9. Working with Mail Message Lists 155

Page 180: AnyMail/400 Mail Server Framework Developer Guide January 1995

One of the differences between the lists that are passed when the message iscreated and those that are passed to the exit point programs, or retrieved usingthe QzmfRtvMailMsg API, is that a unique identifier has been assigned to eachentry in each list. This unique identifier can be used when changing a specificentry in a list. It can also be used when one entry is to reference another entryusing the reference unique identifier field. For example, when two attachmentreferences represent the same information in two different formats, one entrycan reference the other entry using the reference identifier.

To process the information that is passed to your exit point programs, you mustfirst determine what information is to be processed, and then you must locatethat information. To do this, you loop through the message descriptor array andlook for the list that you are to process. For example, if your exit point programis called from the address resolution exit point and the information that you arelooking for is the recipient list, look for the element that contains the formatname of RCPL0100. This element also contains a pointer to the recipient listheader. You can then loop through each entry in the recipient list and processthe recipients.

For example, the following section of code shows how to process a recipient list:

void main(int argc, char *argv[]){

/*******************************************************************//* argv vector contains all the information passed by the main MSF *//* job to the exit point program. *//* *//*******************************************************************/

Qzmf_Msg_Desc_Hdr0100_t*List_HdrP;

Qzmf_RCPL0100_t

Exit Point Name Message Lists Passed

QIBM_QZMFMSF_ATT_MGT RCPL0100 - Recipient ListATTL0100 - Attachment Reference List

QIBM_QZMFMSF_ACT RCPL0100 - Recipient ListENVL0100 - Envelope ListATTL0100 - Attachment Reference ListORGL0100 - Originator ListRTAL0100 - Report-to ListRPYL0100 - Reply-to ListORCL0100 - Original Recipient ListCRTA0100 - Creation Attributes

QIBM_QZMFMSF_TRK_CHG No message lists are passed

QIBM_QZMFMSF_VLD_TYP RCPL0100 - Recipient ListENVL0100 - Envelope ListATTL0100 - Attachment Reference ListORGL0100 - Originator ListROAL0100 - Report-on ListRTAL0100 - Report-to ListRPYL0100 - Reply-to ListORCL0100 - Original Recipient List

156 AnyMail/400 MSF

Page 181: AnyMail/400 Mail Server Framework Developer Guide January 1995

*RcpntP;

long int*Return_Code = (long int *)(*(argv + 6))

, Passed_Num_Attrbts = *(long int *)(*(argv + 4)), Num_Of_Changed_Attributes = NUM_CHNGD_ATTRBT;

short intDesc_Indx = 0

, Elem_Indx = 1;

/* Set a pointer to the passed message descriptor attribute array */Qzmf_Msg_Desc_Attrbt_Entity_t

*Passed_Msg_Desc_AttrP =(Qzmf_Msg_Desc_Attrbt_Entity_t *)(*(argv + 3))

;

/* Set the default return code to MSF */*Return_Code = QZMF_END_MSG_PROCESSING;

/* Specify exceptions should be signalled from the API *//* rather than using return codes. */Chg_Error_Code.Error.Bytes_Provided = 0;

/* Locate the message descriptor corresponding to the *//* recipient list. */while ( Desc_Indx < Passed_Num_Attrbts ){

if ( !memcmp( (Passed_Msg_Desc_AttrP + Desc_Indx) ->Msg_Desc_Format_Name,

QZMF_RECIPIENT_LIST_FMT,QZMF_MSG_DESC_FMT_LENGTH ) )

{/* Set the recipient list header pointer */List_HdrP = (Qzmf_Msg_Desc_Hdr0100_t *)

( (Passed_Msg_Desc_AttrP + Desc_Indx) -> Msg_Desc_Ptr );break;

}++Desc_Indx;

} /* end of while loop over the passed message descriptor array */

if (Desc_Indx == Passed_Num_Attrbts){

printf(″Failed to locate the Recipient List; quitting\n″ ) ;exit(1);

}

.

.

.

/* Continue with processing the recipient list entries. */

Once the message list that is to be processed is found, the code can look for aspecific entry or process all the entries in the list. For example, the recipient list

Chapter 9. Working with Mail Message Lists 157

Page 182: AnyMail/400 Mail Server Framework Developer Guide January 1995

entries might be looked up in a directory to determine if the user is local orneeds to be forwarded to another system. The following section of code showsan example of how to loop through the recipient list entries:

/* Set up recipient list header pointer */List_HdrP = (Qzmf_Msg_Desc_Hdr0100_t *)

( (Passed_Msg_Desc_AttrP + Desc_Indx) -> Msg_Desc_Ptr );

/* Set up the pointer to the first recipient list entry */RcpntP = (Qzmf_RCPL0100_t *)

((char *)List_HdrP + List_HdrP -> First_Entry_Offset);

/*******************************************************************//* Now change the intended fields in all the recipient list entries*//*******************************************************************/

Temp_Num_Entries = List_HdrP -> Total_Num_Of_Entries;while ( Elem_Indx <= Temp_Num_Entries ){

/**************************************************************//* At this point a typical MSF application may have to *//* consult the system distribution directory to extract the *//* values of message type and status corresponding to *//* this particular recipient. *//* Just for example, the status fields of the first two *//* recipients are set for local delivery. The last *//* recipient is destined for a remote system. *//**************************************************************/memcpy( (RcpntP -> Msg_Type), TEST_MESSAGE_TYPE_VALUE,

sizeof(Qzmf_Type_Value_t) );if (Elem_Indx < 3)

RcpntP -> Status = QZMF_STATUS_LOCAL;else

RcpntP -> Status = QZMF_STATUS_FORWARDED;

/* Advance the recipient list entry pointer */RcpntP = (Qzmf_RCPL0100_t *)

( (char *)RcpntP + (RcpntP -> Entry_Length) );++Elem_Indx;

} /* end of while loop (over all the recipient entries) */

Through this example of locating the recipient list and then processing eachentry in the list, we have shown how an exit point program can processinformation that is passed to it by MSF. These same principles can be applied toall of the other lists that are passed to an exit point program.

When processing information that is passed to your exit point program, considerthe following:

• The information required by the exit point program may not be passed. Thisis either because it was not defined to be passed for the current exit pointthat is processing the message or the information is not present in themessage. For example, if you are coding an attachment conversion exitpoint program and you need the original recipient list, you can retrieve theinformation by using the QzmfRtvMailMsg API because the list is not passed.

Also, because some of the lists are optional, the creator of the list may nothave provided that information when the message was created. For

158 AnyMail/400 MSF

Page 183: AnyMail/400 Mail Server Framework Developer Guide January 1995

example, the reply-to list is optional. If it was specified on theQzmfCrtMailMsg API, then it will be passed to the address resolution. If it isnot present, it will not be passed to any address resolution exit pointprogram.

• For the recipient list, only the entries that have the data type for which yourexit point program is configured are passed. If you need to have thecomplete list, then you can use the QzmfRtvMailMsg API to retrieve thecomplete list. For additional information on the parameters that are passedto the exit point parameters, see Chapter 6, “Mail Server Framework ExitPoints” on page 80.

• There are other lists that are defined as part of the message that are neverpassed to exit point programs. These include the exit point program callhistory and the recipient history list. These lists can also be retrieved usingthe QzmfRtvMailMsg API. For additional information on this, see Chapter 5,“Mail Server Framework Message” on page 44.

For additional information on the parameters that are passed to the exit pointprograms, see Chapter 15, “Snap-In Call Exit Point Interface” on page 197.

Using Message Descriptors to Retrieve InformationWhen an exit point program is not passed information that is needed to processa message, the information can be retrieved by using the QzmfRtvMailMsg API.To identify the information that is to be retrieved, the message descriptor arrayis used. The message descriptor array is used in the same manner as when itis used to create a message except that each element points to where theinformation is to be retrieved rather than where information is to be used tocreate a message. For the QzmfCrtMailMsg API, each message descriptorelement points to the information that is to be contained in the message once itis created. For the QzmfRtvMailMsg API, the element should point to a workarea such as a user space. The area will contain the information that isretrieved once the API returns to the exit point program.

In the case of the QzmfRtvMailMsg API, the information in each messagedescriptor element indicates what information is to be retrieved (identified by theformat name like ATTL0100). The array element also indicates how much area isavailable for the information and a pointer to the area.

Multiple lists can be retrieved by using one call to the QzmfRtvMailMsg API. Thenumber of elements in the message descriptor array indicated in the number ofdescriptors parameters indicates how many lists are to be retrieved.

Once the QzmfRtvMailMsg API has completed, the header contains the numberof bytes of information that is available. If this number is less than the amount ofspace, not all of the information available was returned. In this case, only theamount of data that could fit in the space was returned. Note that the space maycontain partial records in this case. To make the QzmfRtvMailMsg API easier touse, automatically extendable spaces may be specified. If an applicationprovides such a space then the length of the space should be set to negativeone (-1). The mail server framework will return all of the information in thespace provided in this case setting the length of the space provided as well asthe number of bytes available.

Chapter 9. Working with Mail Message Lists 159

Page 184: AnyMail/400 Mail Server Framework Developer Guide January 1995

All of the formats, except for MSGL0100, can be retrieved from any exit pointprogram or from the Track Mail Changes exit point. The message type list canonly be retrieved after address resolution has completed.

The following section of code shows how the message descriptor array can beset such that the recipient history list and the message type list are retrieved:

/* Set up the local message descriptor array to be passed to API */

/* The first array element is for recipient history */Msg_Desc_Attr_Array -> Msg_Desc_Ptr = Create_A_Work_Space();Msg_Desc_Attr_Array -> Msg_Desc_Length = AUTO_EXTEND_INDCTR;memcpy( (Msg_Desc_Attr_Array -> Msg_Desc_Format_Name),

QZMF_RECIPIENT_HIST_FMT, QZMF_MSG_DESC_FMT_LENGTH );

/* The second array element is for Recepient_Message_Type */if (

( (Msg_Desc_Attr_Array + 1) -> Msg_Desc_Ptr =(_SPCPTR)malloc(HEAP_SPACE_SIZE) ) == NULL

){

printf(″malloc problem while creating space for MSGL; ″″quitting\n″ ) ;

exit(1);}

(Msg_Desc_Attr_Array + 1) -> Msg_Desc_Length = HEAP_SPACE_SIZE;memcpy( (Msg_Desc_Attr_Array + 1) -> Msg_Desc_Format_Name,

QZMF_MSG_TYPE_LIST_FMT, QZMF_MSG_DESC_FMT_LENGTH );

/* We have completed the creation of the message descriptor. *//* Invoke the Retrieve Message API. */

#pragma exception_handler(Quit_Execution, 0, 0, _C2_MH_ESCAPE)

QzmfRtvMailMsg((void *)(*(argv + 2))

, (void *)Msg_Desc_Attr_Array, &Num_Of_Retrieved_Attributes, QZMF_RTV_MAIL_MSG_FORMAT, (void *)(&Rtv_Error_Code)

);

#pragma disable_handler

For a complete example of retrieving message information, see “Retrieval ExitPoint Program — Example” on page 335. For additional information on theQzmfRtvMailMsg API, see Chapter 11, “Retrieving Mail Message Information” onpage 168.

160 AnyMail/400 MSF

Page 185: AnyMail/400 Mail Server Framework Developer Guide January 1995

Using MSF Message Lists to Change a MessageWhen messages are processed by the framework and its associated exit pointprograms, changes will need to take place. For example, a list expansion exitpoint program may want to expand a list, or an address resolution needs toindicate if a recipient is local, remote or non-deliverable.

To make changes, an MSF message list is used. The list is then passed to thechange API using the message descriptor array described previously. The MSFmessage lists that are passed to the change API contain entries that have thechanges specified. The changes are specified in the message lists the same asthey are specified when the message is created except that the unique identifieris used to indicate which entry in the list is to be changed.

The following section of code shows how an exit point program can change theinformation in an MSF message list and pass that list to the change API:

/* Set up recipient list header pointer */List_HdrP = (Qzmf_Msg_Desc_Hdr0100_t *)

( (Passed_Msg_Desc_AttrP + Desc_Indx) -> Msg_Desc_Ptr );

/* Set up the pointer to the first recipient list entry */RcpntP = (Qzmf_RCPL0100_t *)

((char *)List_HdrP + List_HdrP -> First_Entry_Offset);

/*******************************************************************//* Now change the intended fields in all the recipient list entries*//*******************************************************************/

Temp_Num_Entries = List_HdrP -> Total_Num_Of_Entries;while ( Elem_Indx <= Temp_Num_Entries ){

/**************************************************************//* At this point a typical MSF application may have to *//* consult the system distribution directory to extract the *//* values of message type and status corresponding to *//* this particular recipient. *//* Just for example, the status fields of the first two *//* recipients are set for local delivery. The last *//* recipient is destined for a remote system. *//**************************************************************/memcpy( (RcpntP -> Msg_Type), TEST_MESSAGE_TYPE_VALUE,

sizeof(Qzmf_Type_Value_t) );if (Elem_Indx < 3)

RcpntP -> Status = QZMF_STATUS_LOCAL;else

RcpntP -> Status = QZMF_STATUS_FORWARDED;

/* Advance the recipient list entry pointer */RcpntP = (Qzmf_RCPL0100_t *)

( (char *)RcpntP + (RcpntP -> Entry_Length) );++Elem_Indx;

} /* end of while loop (over all the recipient entries) */

/*****************************************************************//* We have now finished changing the recipient list of the MSF *//* message. Now call the Change Mail Message API to */

Chapter 9. Working with Mail Message Lists 161

Page 186: AnyMail/400 Mail Server Framework Developer Guide January 1995

/* change the MSF message. *//*****************************************************************/

#pragma exception_handler(Quit_Execution, 0, 0, _C2_MH_ESCAPE)

QzmfChgMailMsg((void *)(*(argv + 2))

, (void *)(Passed_Msg_Desc_AttrP + Desc_Indx), &Num_Of_Changed_Attributes, QZMF_CHG_MAIL_MSG_FORMAT, (void *)(&Chg_Error_Code)

);

#pragma disable_handler

For additional information on using the change API, see Chapter 12, “Changinga Mail Message” on page 172.

162 AnyMail/400 MSF

Page 187: AnyMail/400 Mail Server Framework Developer Guide January 1995

Create Mail Message

Chapter 10. Creating a Mail Message

The creation of an E-mail message is the most fundamental task of a mailapplication. The Create Mail Message (QzmfCrtMailMsg) API provides thefunction of creating MSF messages that represent E-mail messages. The MSFmessage conveys information about an E-mail message to the framework andthe exit point programs.

To use the Create Mail Message API, you must understand the following:

• What the MSF message contains (see Chapter 5, “Mail Server FrameworkMessage” on page 44).

• How to work with message lists (see Chapter 9, “Working with Mail MessageLists” on page 146).

This chapter explains how to use the Create Mail Message (QzmfCrtMailMsg)API once the message lists have been created.

Create Mail Message (QzmfCrtMailMsg) API Syntax

#include <qzmfasrv.h>void QzmfCrtMailMsg(

void *Msg_ID, /* MSF message ID */void *Rsvrd_Msg_ID, /* Reserved MSF Msg ID */char *Type_Value, /* Creation Msg. Type */void *Msg_Desc, /* Msg Desc Attr List */long int *Num_of_Desc, /* Num Msg Desc Attrbts*/char *Fmt_Name, /* Format Name */void *Error_Str /* API Returned Error */

);

The Create Mail Message (QzmfCrtMailMsg) API is the interface that is used tocreate an MSF message in the mail server framework.

ParametersThe following parameters must be passed to the Create Mail Message(QzmfCrtMailMsg) API:

Msg_IDA pointer to a field that contains a unique identifier that is associated withthe created MSF message. This unique identifier is returned by the API. TheMsg_ID field is composed of characters A through Z and 0 through 9 only.The Qzmf_Msg_ID_t structure in the Qzmf header file defines this field. Formore information on this field, see Appendix F, “Qzmf Header File” onpage 356. If an error occurs, Msg_ID is set to zeros (hexadecimal 0), and anotification of the error is made in the Error_Str field.

A reserved message ID can be specified in the Rsvrd_Msg_ID field. If a validmessage ID is specified in the Rsvrd_Msg_ID field, that message ID isassociated with the MSF message that is created by this API. The messageID is returned in the Msg_ID field. If the Rsvrd_Msg_ID field is blanks orzeros (hexadecimal 0), MSF assigns unique ID to the MSF message and

Copyright IBM Corp. 1995 163

Page 188: AnyMail/400 Mail Server Framework Developer Guide January 1995

Create Mail Message

returns the ID in the Msg_ID field. For information on reserving messageidentifiers, see “Reserve Mail Message Identifier (QzmfRsvMailMsgId) API”on page 179.

Rsvrd_Msg_IDA pointer to a field that contains the MSF message identifier (previouslyreserved) to be associated with the created MSF message. TheQzmf_Msg_Id_Type structure in the Qzmf header file defines this field. Formore information, see Appendix F, “Qzmf Header File” on page 356. Themessage identifier must have been previously reserved by using the ReserveMail Message Identifier (QzmfRsvMailMsgId) API.

If this Rsvrd_Msg_ID field contains a valid MSF message ID, this ID isassociated with the MSF message and is returned in the Msg_ID field. If thisRsvrd_Msg_ID field is set to blanks or zeros (hexadecimal 0), MSF assigns aunique identifier to the MSF message and returns the identifier in the Msg_IDfield. For information on reserving MSF message identifiers, see “ReserveMail Message Identifier (QzmfRsvMailMsgId) API” on page 179.

If the value of the Rsvrd_Msg_ID field is not a valid reserved MSF messageidentifier, error message CPFAF8B is generated.

Type_ValueA pointer to the message type that the originator intended to create. Thisfield is used to indicate the message data type that is associated with theMSF message. Qzmf_Type_Value in the Qzmf header file defines this field.For more information, see Appendix F, “Qzmf Header File” on page 356.

Msg_DescA pointer to an array that contains message descriptor attribute elements.Qzmf_Msg_Desc_Attrbt_Entity_t in the Qzmf header file defines this field. Formore information, see Appendix F, “Qzmf Header File” on page 356. Anelement in the message descriptor attribute array is required for each of thefollowing message lists:

Originator listEnvelope listRecipient list

A message descriptor attribute element is optional for each of the followingmessage lists:

Attachment reference listOriginal recipient listReply-to listReport-to listReport-on list

For information on working with message descriptor attribute array, see“Using MSF Message Lists to Create a Message” on page 153.

Num_of_DescA pointer to the number of elements in the array of message descriptorattributes. A minimum of three message descriptor attribute elements isrequired (originator list, envelope list, and recipient list). This number mustexactly match the number of elements in the array of message descriptorattributes.

164 AnyMail/400 MSF

Page 189: AnyMail/400 Mail Server Framework Developer Guide January 1995

Create Mail Message

Fmt_NameA pointer to the format name of the parameter list that is passed to this API.This field must be set to CRTM0100. The Qzmf_Format_Name structure inthe Qzmf header file defines this field. For more information on this field,see Appendix F, “Qzmf Header File” on page 356.

Error_StrA pointer to the error structure. To determine if the API returned an error,you can check the value of the Bytes_Available field in the error structure. Avalue of zero means that an error was not encountered. If an error wasencountered, this field contains the length of the data that was returned.

This error structure will not return errors if the caller requests to haveexceptions signalled. The caller requests exceptions to be signalled bysetting the Bytes_Provided field of the error structure to zero when the API iscalled. The Bytes_Provided field is defined in the Qus_EC_t structure(included in member qusec of file H).

This error structure is the common error structure used by system APIs. Formore information on this common error structure, see the System APIReference.

Return ValueThe Bytes_Available field in the error structure indicates the status of the APIcall:

0 QzmfCrtMailMsg was successful.

> 0 QzmfCrtMailMsg was not successful. The Error_Str error structure includesthe error information.

Error ConditionsIf the QzmfCrtMailMsg API is not successful, the Exception_Id field of theError_Str error structure usually indicates one of the following errors. Dataassociated with the error can be found in the Exception_Data field of the errorstructure.

The following errors may be signalled (rather than returned in the Error_Str errorstructure) if the caller of the API requested to have exceptions signalled.

See the message descriptions in file QCPFMSG of library QSYS for a descriptionof the error′s associated data. The descriptions can be seen using the DisplayMessage Description (DSPMSGD) command.

CPF24B4 ESevere error while addressing the parameter list. The API encountered anerror while attempting to access a parameter.

CPF9872 EProgram or service program &1 in library &2 ended. Reason code &3. Thespecified program or service program was ended due to the reason codespecified.

CPFAF80 ESyntax error on a call to the MSF API. Reason code &1. A parametersyntax error occurred on the call to the API. The reason code gives specificinformation about the cause of the error.

Chapter 10. Creating a Mail Message 165

Page 190: AnyMail/400 Mail Server Framework Developer Guide January 1995

Create Mail Message

CPFAF81 EParameter value error on a call to the MSF API. Reason code &1. Aparameter value error occurred on the call to the API. The reason codegives specific information about the cause of the error. For example, reasoncode 47 indicates that the message creation type parameter is not aconfigured message type.

CPFAF82 EError occurred during the running of the MSF API. The reason code is &1.The reason code gives specific information about the cause of the error. Forexample, reason code 02 indicates that the MSF queue was not found.

CPFAF83 EParameter error on a call to the MSF API. Reason code &1. A parameterpassing error occurred while trying to call the API. The reason code givesspecific information about the cause of the error. For example, reason code10 indicates that an incorrect number of parameters were specified.

CPFAF87 EAn error occurred in the MSF Validate Data Field exit point program. TheAPI called a Validate Data Field exit point program, and that programindicated that an error occurred.

CPFAF88 EError occurred on a call to an MSF exit point program. The API tried to callan exit point program, but an error occurred on the call. The reason code is&1. The reason code gives specific information about the cause of the error.For example, reason code 80 indicates that the exit point program was notfound.

CPFAF8B EReserved mail message identifier is not valid. The API was called withreserved message identifier &1. However, the reserved mail messageidentifier could not be found.

CPFAF8D EReserve mail message identifier already used. The API was called withreserved message identifier &1. However, the reserved mail messageidentifier had already been used to create an MSF message.

Related Information• The qzmfasrv.h file is shown in Appendix G, “Qzmfasrv Header File” on

page 375.• The common error structure is described in the System API Reference.

ExampleThe following example is a section of a code that calls the Create Mail Message(QzmfCrtMailMsg) API. For a complete example of the code that can be used tocreate the message lists, build the parameters (including the descriptor array),and call the API to create the MSF message, see “Module and Program toCreate MSF Messages — Example” on page 308.

.

.

./**********************************************************************//* Create_A_Message function creates an MSF message that has four *//* different lists. Use the test definitions of the TESTMSG */

166 AnyMail/400 MSF

Page 191: AnyMail/400 Mail Server Framework Developer Guide January 1995

Create Mail Message

/* header file to create the MSF message. *//**********************************************************************/

void Create_A_Message( Qzmf_Msg_Id_t Msg_Id ){

Qzmf_Msg_Id_t Dummy_Rsvrd_Msg_Id;long int Num_Of_Msg_Descs = NUM_CRT_ATTRBT;short int Desc_Indx = Originator;

/* Create four message lists and the corresponding *//* message descriptor array. */Create_Originator_Descriptor();Create_Envelope_Descriptor();Create_Recipient_Descriptor();Create_Attachment_Descriptor();

/* Set the Dummy Reserved Message Id to Null-Value = ′ ′ *//* because we have not reserved a message ID. */memset(Dummy_Rsvrd_Msg_Id, ′ ′ , sizeof(Qzmf_Msg_Id_t));

/* Specify exceptions should be signalled from the API *//* rather than using return codes. */Crt_Error_Code.Error.Bytes_Provided = 0;

#pragma exception_handler(Quit_Execution, 0, 0, _C2_MH_ESCAPE)

/* No initialization is needed for Dummy_Msg_Id, Create_Msg *//* API will ignore its first parameter if there is any *//* valid Msg ID in its second parameter */QzmfCrtMailMsg(

(void *)Msg_Id, (void *)Dummy_Rsvrd_Msg_Id, TEST_MESSAGE_TYPE_VALUE, (void *)Msg_Desc_Attr_Array, &Num_Of_Msg_Descs, QZMF_CRT_MAIL_MSG_FORMAT, (void *)(&Crt_Error_Code)

);

#pragma disable_handler

} /* end of Create_A_Message function */

.

.

.

Chapter 10. Creating a Mail Message 167

Page 192: AnyMail/400 Mail Server Framework Developer Guide January 1995

Retrieve Mail Message

Chapter 11. Retrieving Mail Message Information

In some cases, an exit point program will not be passed the information that itmay need. To obtain this information, the exit point program can use theRetrieve Mail Message (QzmfRtvMailMsg) API. This API can be called only froman exit point program (see Chapter 6, “Mail Server Framework Exit Points” onpage 80 for more information) or from the Track Mail Changes exit point (seeChapter 6, “Mail Server Framework Exit Points” on page 80). Information canbe retrieved only about the MSF message being processed.

To use the Retrieve Mail Message API, you must understand the following:

• What the MSF message contains (see Chapter 5, “Mail Server FrameworkMessage” on page 44).

• How to work with message lists (see Chapter 9, “Working with Mail MessageLists” on page 146).

This chapter explains how to use the Retrieve Mail Message (QzmfRtvMailMsg)API and how it can be called by an ILE C/400 program.

Information Returned by the Retrieve Mail Message APIThe retrieve API is different from the other MSF APIs in that the message listsare returned to the exit point program from MSF. The spaces where themessage lists are returned must be provided by the caller. The messagedescriptor has a field that specifies the length of this space. This length must beeither -1 or a positive number. If the space is smaller than the number of bytesavailable, then the framework returns only the data that fits in the space andsets the number of bytes available field in the header.

When the Retrieve Mail Message API completes, an exit point program cancheck to see that the length of the message descriptor is greater than thenumber of bytes available to see if all of the information is returned. If all of theinformation is not returned, then the exit point program can get a space largeenough for the data being retrieved and try again.

If the length of the space is specified to be -1, MSF assumes the space isautomatically extendable. In this case, the Retrieve Mail Message API returnsall of the information by extending the space if necessary.

Retrieve Mail Message (QzmfRtvMailMsg) API Syntax

#include <qzmfasrv.h>void QzmfRtvMailMsg(

void *Msg_ID, /* MSF message ID */void *Msg_Desc, /* Msg Desc Attr List */long int *Num_of_Desc, /* Num Msg Desc Attrbts*/char *Fmt_Name, /* Format Name */void *Error_Str /* API Returned Error */

);

168 Copyright IBM Corp. 1995

Page 193: AnyMail/400 Mail Server Framework Developer Guide January 1995

Retrieve Mail Message

The Retrieve Mail Message (QzmfRtvMailMsg) API is the interface that is used toretrieve information about an MSF message.

ParametersThe following parameters must be passed to the Retrieve Mail Message(QzmfRtvMailMsg) API:

Msg_IDA pointer to a field that contains an MSF message identifier. This identifierspecifies the MSF message for which information is to be retrieved. Only theidentifier of the MSF message that is being processed can be specified. TheQzmf_Msg_ID_t structure in the Qzmf header file defines the contents of thisfield. For more information on this field, see Appendix F, “Qzmf HeaderFile” on page 356. The MSF message identifier is composed of characters Athrough Z and 0 through 9 only.

Msg_DescA pointer to an array that contains the message descriptor attributes for thedata that is to be retrieved. The Qzmf_Msg_Desc_Attrbt_Entity_t structure inthe Qzmf header file defines the contents of this field. For more informationon this field, see Appendix F, “Qzmf Header File” on page 356. For moreinformation on a message descriptor attribute array entry, see “UsingMessage Descriptors to Retrieve Information” on page 159.

Num_of_DescA pointer to the number of elements in the array of message descriptorattributes. At least one array element must be specified on a call to this API.

Fmt_NameA pointer to the format name of the parameter list that is returned from thisAPI. This field must be set to RTVM0100. The Qzmf_Format_Name_tstructure in the Qzmf header file defines the contents of this field. For moreinformation on this field, see Appendix F, “Qzmf Header File” on page 356.

Error_StrA pointer to the error structure. To determine if the API returned an error,you can check the value of the Bytes_Available field in the error structure. Avalue of zero means that an error was not encountered. If an error wasencountered, this field contains the length of the data that was returned.

This error structure will not return errors if the caller requests to haveexceptions signalled. The caller requests exceptions to be signalled bysetting the Bytes_Provided field of the error structure to zero when the API iscalled. The Bytes_Provided field is defined in the Qus_EC_t structure(included in member qusec of file H).

This error structure is the common error structure used by system APIs. Formore information on this common error structure, see the System APIReference.

Return ValueThe Bytes_Available field in the error structure indicates the status of the APIcall:

0 QzmfRtvMailMsg was successful.

> 0 QzmfRtvMailMsg was not successful. The Error_Str error structureincludes the error information.

Chapter 11. Retrieving Mail Message Information 169

Page 194: AnyMail/400 Mail Server Framework Developer Guide January 1995

Retrieve Mail Message

Error ConditionsIf QzmfRtvMailMsg is not successful, the Exception_Id field of the Error_Str errorstructure usually indicates one of the following errors. Data associated with theerror can be found in the Exception_Data field of the error structure.

The following errors may be signalled (rather than returned in the Error_Str errorstructure) if the caller of the API requested to have exceptions signalled.

See the message descriptions in file QCPFMSG of library QSYS for a descriptionof the error′s associated data. The descriptions can be seen using the DisplayMessage Description (DSPMSGD) command.

CPF24B4 ESevere error while addressing parameter list. The API encountered an errorwhile attempting to access a parameter.

CPF9872 EProgram or service program &1 in library &2 ended. Reason code &3. Thespecified program or service program was ended due to the reason codespecified.

CPFAF80 ESyntax error on a call to the MSF API. Reason code &1. A parametersyntax error occurred on the call to the API. The reason code gives specificinformation about the cause of the error.

CPFAF82 EError occurred during the running of the MSF API. The reason code is &1.The reason code gives specific information about the cause of the error. Forexample, reason code 02 indicates that the MSF queue was not found.

CPFAF83 EParameter error on a call to the MSF API. Reason code &1. A parameterpassing error occurred while trying to call the API. The reason code givesspecific information about the cause of the error. For example, reason code10 indicates that an incorrect number of parameters were specified.

CPFAF84 EMSF API failed. MSF message identifier not found. The API was called withMSF message identifier &3. However, the message identifier could not befound. The most common reasons for this error are:

The message ID in the Msg_ID field was specified incorrectly

The Create Mail Message (QzmfCrtMailMsg) API did not create an MSFmessage with this ID

The MSF message with this ID has already been processed by MSF

CPFAF85 EMSF API failed. Request not allowed. The requested operation is notallowed when the API is called from this exit point.

Related Information• The qzmfasrv.h file is shown in Appendix G, “Qzmfasrv Header File” on

page 375.• The common error structure is described in the System API Reference.

170 AnyMail/400 MSF

Page 195: AnyMail/400 Mail Server Framework Developer Guide January 1995

Retrieve Mail Message

ExampleThe following example is a section of a code that retrieves information about anMSF message by using the Retrieve Mail Message API. For a completeexample, see “Retrieval Exit Point Program — Example” on page 335.

.

.

.

/* Set up the local message descriptor array to be passed to API */

/* The first array element is for recipient history */Msg_Desc_Attr_Array -> Msg_Desc_Ptr = Create_A_Work_Space();Msg_Desc_Attr_Array -> Msg_Desc_Length = AUTO_EXTEND_INDCTR;memcpy( (Msg_Desc_Attr_Array -> Msg_Desc_Format_Name),

QZMF_RECIPIENT_HIST_FMT, QZMF_MSG_DESC_FMT_LENGTH );

/* The second array element is for Recepient_Message_Type */if (

( (Msg_Desc_Attr_Array + 1) -> Msg_Desc_Ptr =(_SPCPTR)malloc(HEAP_SPACE_SIZE) ) == NULL

){

printf(″malloc problem while creating space for MSGL; ″″quitting\n″ ) ;

exit(1);}

(Msg_Desc_Attr_Array + 1) -> Msg_Desc_Length = HEAP_SPACE_SIZE;memcpy( (Msg_Desc_Attr_Array + 1) -> Msg_Desc_Format_Name,

QZMF_MSG_TYPE_LIST_FMT, QZMF_MSG_DESC_FMT_LENGTH );

/* We have completed the creation of the message descriptor. *//* Invoke the Retrieve Message API. */

#pragma exception_handler(Quit_Execution, 0, 0, _C2_MH_ESCAPE)

QzmfRtvMailMsg((void *)(*(argv + 2))

, (void *)Msg_Desc_Attr_Array, &Num_Of_Retrieved_Attributes, QZMF_RTV_MAIL_MSG_FORMAT, (void *)(&Rtv_Error_Code)

);

.

.

.

Chapter 11. Retrieving Mail Message Information 171

Page 196: AnyMail/400 Mail Server Framework Developer Guide January 1995

Change Mail Message

Chapter 12. Changing a Mail Message

All mail applications that use MSF will need to change an MSF message. Tochange an MSF message, a mail application must use the Change Mail Message(QzmfChgMailMsg) API. This API can be called only from an exit point program(see Chapter 6, “Mail Server Framework Exit Points” on page 80 for moreinformation).

To use the Change Mail Message API, you must understand the following:

• What the MSF message contains (see Chapter 5, “Mail Server FrameworkMessage” on page 44).

• How to work with message lists (see Chapter 9, “Working with Mail MessageLists” on page 146).

This chapter explains how to use the Change Mail Message API and how it canbe called by an ILE C/400 program.

The unique identifier and the referenced unique identifier are fields thatrepresent specific entries in a message list. The unique identifier field isassigned by the mail server framework and uniquely identifies an entry in anMSF message list. This unique identifier is used by the Change Mail MessageAPI to specify which specific entry should be changed. In some cases entriescannot be changed, but changes to the list can be made by adding new entriesto the list. For more information on unique identifiers, see “List Entry IDs” onpage 52.

The referenced unique identifier field is used to establish a relationship betweenthe current entry and another entry. For more information on referenceidentifiers, see “List Entry Reference IDs” on page 53.

Change Mail Message (QzmfChgMailMsg) API Syntax

#include <qzmfasrv.h>

void QzmfChgMailMsg(void *Msg_ID, /* MSF message ID */void *Msg_Desc, /* Msg Desc Attr List */long int *Num_of_Desc, /* Num Msg Desc Attrbts*/char *Fmt_Name, /* Format Name */void *Error_Str /* API Returned Error */

);

The Change Mail Message (QzmfChgMailMsg) API is the interface that is used tochange an MSF message in the mail server framework.

172 Copyright IBM Corp. 1995

Page 197: AnyMail/400 Mail Server Framework Developer Guide January 1995

Change Mail Message

ParametersThe following parameters must be passed to the Change Mail Message(QzmfChgMailMsg) API:

Msg_IDA pointer to a field that contains a message identifier that is associated withthe MSF message to be changed. The MSF message identifier is composedof characters A through Z and 0 through 9 only. The Qzmf_Msg_Id_tstructure in the Qzmf header file defines the contents of this field. For moreinformation, see Appendix F, “Qzmf Header File” on page 356.

Msg_DescA pointer to an array that contains the message descriptor attributes. Thedescriptor array contains lengths of these message descriptor attributes,along with the format name of the provided data and a pointer to a messagelist. The format variable within this parameter list indicates the type of list towhich the pointer refers. Qzmf_Msg_Desc_Attrbt_Entity_t in the Qzmf headerfile specifies the contents of this field. For more information on this field, seeAppendix F, “Qzmf Header File” on page 356.

Num_of_DescA pointer to the number of elements in the array of message descriptorattributes. At least one message descriptor attribute must be specified on acall to this API.

Fmt_NameA pointer to the format name of the parameter list that that is being passed.This field must be set to CHGM0100. Qzmf_Format_Name_t in the Qzmfheader file defines the contents of this field. For more information, seeAppendix F, “Qzmf Header File” on page 356.

Error_StrA pointer to the error structure. To determine if the API returned an error,you can check the value of the Bytes_Available field in the error structure. Avalue of zero means that an error was not encountered. If an error wasencountered, this field contains the length of the data that was returned.

This error structure will not return errors if the caller requests to haveexceptions signalled. The caller requests exceptions to be signalled bysetting the Bytes_Provided field of the error structure to zero when the API iscalled. The Bytes_Provided field is defined in the Qus_EC_t structure(included in member qusec of file H).

This error structure is the common error structure used by system APIs. Formore information on this common error structure, see the System APIReference.

Return ValueThe Bytes_Available field in the error structure indicates the status of the APIcall:

0 QzmfChgMailMsg was successful.

> 0 QzmfChgMailMsg was not successful. The Error_Str structure includes theerror information.

Chapter 12. Changing a Mail Message 173

Page 198: AnyMail/400 Mail Server Framework Developer Guide January 1995

Change Mail Message

Error ConditionsIf QzmfChgMailMsg is not successful, the Exception_Id field of the Error_Str errorstructure usually indicates one of the following errors. Data associated with theerror can be found in the Exception_Data field of the error structure.

The following errors may be signalled (rather than returned in the Error_Str errorstructure) if the caller of the API requested to have exceptions signalled.

See the message descriptions in file QCPFMSG of library QSYS for a descriptionof the error′s associated data. The descriptions can be seen using the DisplayMessage Description (DSPMSGD) command.

CPF24B4 ESevere error while addressing parameter list. The API encountered an errorwhile attempting to access a parameter.

CPF9872 EProgram or service program &1 in library &2 ended. Reason code &3. Thespecified program or service program was ended due to the reason codespecified.

CPFAF80 ESyntax error on a call to the MSF API. Reason code &1. A parametersyntax error occurred on the call to the API. The reason code gives specificinformation about the cause of the error.

CPFAF81 EParameter value error on a call to the MSF API. Reason code &1. Aparameter value error occurred on the call to the API. The reason codegives specific information about the cause of the error. For example, reasoncode 47 indicates that the message creation type parameter is not aconfigured message type.

CPFAF82 EError occurred during the running of the MSF API. The reason code is &1.The reason code gives specific information about the cause of the error. Forexample, reason code 02 indicates that the MSF queue was not found.

CPFAF83 EParameter error on a call to the MSF API. Reason code &1. A parameterpassing error occurred while trying to call the API. The reason code givesspecific information about the cause of the error. For example, reason code10 indicates that an incorrect number of parameters were specified.

CPFAF84 EMSF API failed. MSF message identifier not found. The API was called withMSF message identifier &3. However, the message identifier could not befound. The most common reasons for this error are:

The message ID in the Msg_ID field was specified incorrectly

The Create Mail Message (QzmfCrtMailMsg) API did not create an MSFmessage with this ID

The MSF message with this ID has already been processed by MSF

CPFAF85 EMSF API failed. Request not allowed. The requested operation is notallowed when the API is called from this exit point.

174 AnyMail/400 MSF

Page 199: AnyMail/400 Mail Server Framework Developer Guide January 1995

Change Mail Message

CPFAF86 EMSF API failed. Parameter values are not valid for exit point. The API wascalled with a parameter value not allowed for the exit point. The reasoncode is &1, and it gives specific information about the cause of the error.

CPFAF87 EAn error occurred in the MSF Validate Data Field exit point program. TheAPI called a Validate Data Field exit point program, and that programindicated an error occurred.

CPFAF88 EError occurred on call to MSF exit point program. The API tried to call anexit point program, but an error occurred on the call. The reason code is&1. The reason code gives specific information about the cause of the error.For example, reason code 80 indicates that the exit point program was notfound.

Related Information• The qzmfasrv.h file is shown in Appendix G, “Qzmfasrv Header File” on

page 375.• The common error structure is described in the System API Reference.

ExampleThe following example is a section of a code that changes information in an MSFmessage by using the Change Mail Message API. For a complete example, see“Address Resolution Exit Point Program — Example” on page 331.

.

.

.

void main(int argc, char *argv[]){

/*******************************************************************//* The argv vector contains all the information that is passed *//* by MSF to the exit point program. *//* *//* For simplicity, we are assuming that the present program will *//* get triggered by MSF due to the message created in the earlier *//* example. Recall that the address types of all the relevant *//* message list entries are TEST_ADDRESS_TYPE. A particular *//* message identifier can be checked by using argv 2 -- the *//* passed message ID. *//*******************************************************************/

Qzmf_Msg_Desc_Hdr0100_t *List_HdrP;

Qzmf_RCPL0100_t *RcpntP;

long int*Return_Code = (long int *)(*(argv + 6))

, Passed_Num_Attrbts = *(long int *)(*(argv + 4)), Num_Of_Changed_Attributes = NUM_CHNGD_ATTRBT;

short intDesc_Indx = 0

Chapter 12. Changing a Mail Message 175

Page 200: AnyMail/400 Mail Server Framework Developer Guide January 1995

Change Mail Message

, Elem_Indx = 1;

/* Set a pointer to the passed Message Descriptor Attribute Vector */Qzmf_Msg_Desc_Attrbt_Entity_t

*Passed_Msg_Desc_AttrP =(Qzmf_Msg_Desc_Attrbt_Entity_t *)(*(argv + 3));

/* Specify exceptions should be signalled from the API *//* rather than using return codes. */Chg_Error_Code.Error.Bytes_Provided = 0;

/* Locate the message descriptor that corresponds to *//* the recipient list. */while ( Desc_Indx < Passed_Num_Attrbts ){

if ( !memcmp( (Passed_Msg_Desc_AttrP + Desc_Indx) ->Msg_Desc_Format_Name,

QZMF_RECIPIENT_LIST_FMT,QZMF_MSG_DESC_FMT_LENGTH ) )

{/* Set the recipient list header pointer */List_HdrP = (Qzmf_Msg_Desc_Hdr0100_t *)

( (Passed_Msg_Desc_AttrP + Desc_Indx) -> Msg_Desc_Ptr);break;

}++Desc_Indx;

} /* end of while loop over the passed message descriptor array */

if (Desc_Indx == Passed_Num_Attrbts){

printf(″Failed to locate the Recipient List; quitting\n″ ) ;exit(1);

}

/*******************************************************************//* Now set the message type and status fields of all the *//* individual entries in the recipient list. In a typical *//* application, this task will be performed by a system *//* distribution directory search. We are not planning to use *//* any SPIN in this sample program. Therefore, the size of the *//* changed recipient list will be same as that of the old one. *//* *//* Because no extra space is needed we will not create a separate *//* message descriptor array. Pass the existing descriptor *//* (Passed_Msg_Desc_AttrP + Desc_Indx) to the Change Mail *//* Message API. *//*******************************************************************/

/* Set up recipient list header pointer */List_HdrP = (Qzmf_Msg_Desc_Hdr0100_t *)

( (Passed_Msg_Desc_AttrP + Desc_Indx) -> Msg_Desc_Ptr );

/* Set up the pointer to the first recipient list entry */RcpntP = (Qzmf_RCPL0100_t *)(List_HdrP + 1);

/*******************************************************************//* Now change the intended fields in all the recipient list entries*//*******************************************************************/

176 AnyMail/400 MSF

Page 201: AnyMail/400 Mail Server Framework Developer Guide January 1995

Change Mail Message

while ( Elem_Indx <= (List_HdrP -> Total_Num_Of_Entries) ){

/**************************************************************//* At this point, a typical MSF application may have to *//* consult the system distribution directory to extract the *//* values of message type and status that correspond to *//* this particular recipient. *//* Just for example, the status fields of the first two *//* recipients are set for local delivery. The last *//* recipient is destined for a remote system. *//**************************************************************/memcpy( (RcpntP -> Msg_Type), TEST_MESSAGE_TYPE_VALUE,

sizeof(Qzmf_Type_Value_t) );if (Elem_Indx < 3)

RcpntP -> Status = QZMF_STATUS_LOCAL;else

RcpntP -> Status = QZMF_STATUS_FORWARDED;

/* Advance the recipient list entry pointer */RcpntP = (Qzmf_RCPL0100_t *)

( (char *)RcpntP + (RcpntP -> Entry_Length) );++Elem_Indx;

} /* end of while loop over all the recipient entries */

/*****************************************************************//* We have now finished changing the recipient list of the MSF *//* message. Now call the Change Mail Message API to *//* change the MSF message. *//*****************************************************************/

QzmfChgMailMsg((void *)(*(argv + 2))

, (void *)(Passed_Msg_Desc_AttrP + Desc_Indx), &Num_Of_Changed_Attributes, QZMF_CHG_MAIL_MSG_FORMAT, (void *)(&Chg_Error_Code)

);

.

.

} /* end of main */...

Chapter 12. Changing a Mail Message 177

Page 202: AnyMail/400 Mail Server Framework Developer Guide January 1995

Chapter 13. Other Message APIs

This chapter describes the MSF APIs that are provided primarily to allow a mailapplication a method of tracking the progress of an MSF message through themail server framework. These MSF APIs are the following:

• Reserve Mail Message Identifier (QzmfRsvMailMsgId).

• Remove Reserved Mail Message Identifier (QzmfRmvRsvMailMsgId).

• Query Mail Message Identifier (QzmfQryMailMsgId).

• Complete Creation Sequence (QzmfCrtCmpMailMsg).

A mail application can use the Reserve Mail Message Identifier API to obtain anMSF message identifier that can be used to track a specific MSF message. Thisreserved identifier can be used with the Create Mail Message API to create anMSF message that will be assigned this reserved identifier.

Once an MSF message that has been created with the reserved identifier haspassed through the framework, the mail application can use the CompleteCreation Sequence API to remove the MSF message from reserved status. Amail application can also use the Remove Reserved Mail Message Identifier APIto remove an MSF message from reserved status at any time.

The Query Mail Message Identifier API is used to check the status of the MSFmessage in the mail server framework. This API also can be used to check theprogress of any MSF message.

How to Use These MSF APIsThe following steps show how a mail application could use this set of APIs toprovide a more robust solution to the distribution of E-mail.

1. Reserve a message identifier using the QzmfRsvMailMsgID API.

2. Create an attachment object and associate the message identifier that wasreserved in the previous step. You can use a file server object API toperform the association. See Appendix B, “SNADS File Server APIs” onpage 244 for information on using file server objects.

Now that an attachment reference has been created, if your application failsor the system fails (for example, a loss of power occurs), there is anassociation between a message identifier that has not been used to create amessage and an attachment that needs to be deleted. TheQzmfQryMailMsgID API could be used to determine if any attachments existthat were in the process of being used to create messages but the creationdid not complete. If this is the case, the attachment could then be deleted aspart of cleanup for the application.

3. Create the message using the QzmfCrtMailMsg API and specify the messageID that was reserved previously.

4. Once the message has been successfully created, you can indicate that thereserved message identifier is no longer needed by using theQzmfCrtCmpMailMsg API.

If your application fails to reach the point where you indicate that themessage identifier is complete, you could use the QzmfQryMailMsgID API to

178 Copyright IBM Corp. 1995

Page 203: AnyMail/400 Mail Server Framework Developer Guide January 1995

Reserve Mail Message Identifier

determine the status of the message identifier. If the status indicates themessage ID was used to create a message, then your application couldsimply complete its use by using the QzmfCrtCmpMailMsg API. If the statusindicates that the message ID has not been used to create a message, yourapplication could simply delete the attachment as part of its cleanup.

5. If the Create Mail Message API does not complete successfully, yourapplication could immediately delete the attachment object and use theQzmfRmvRsvMailMsgId API to remove reserved message identifier.

The steps outlined above are an example of how this set of APIs can be used byyour mail application. Some of these techniques are used by SNADS as part ofits distribution capabilities to ensure that objects that are not being used are notleft on the system. These APIs, along with the file server object APIs, can beused to provide additional capabilities within your application.

Reserve Mail Message Identifier (QzmfRsvMailMsgId) API Syntax

#include <qzmfasrv.h>void QzmfRsvMailMsgId(

void *Msg_ID, /* MSF message ID */char *Fmt_Name, /* Format Name */void *Error_Str /* API Returned Error */

);

The Reserve Mail Message Identifier (QzmfRsvMailMsgId) API reserves an MSFmessage identifier for use later.

ParametersThe following parameters must be passed to the Reserve Mail MessageIdentifier (QzmfRsvMailMsgId) API:

Msg_IDA pointer to a field that contains a message identifier. This messageidentifier is returned by the API. This identifier can be used later by theCreate Mail Message (QzmfCrtMailMsg) API to pass information that definesthe message. The message identifier is composed of characters A through Zand 0 through 9 only. If an error occurs during processing, a messageidentifier is not generated. The Qzmf_Msg_Id_t structure in the Qzmf headerfile defines the contents of this field. For more information, see Appendix F,“Qzmf Header File” on page 356.

Fmt_NameA pointer to the format name of the parameter list that is being passed. Thisfield must be set to RSVF0100. The Qzmf_Format_Name_t structure in theQzmf header file defines the contents of this field. For more information, seeAppendix F, “Qzmf Header File” on page 356.

Error_StrA pointer to the error structure. To determine if the API returned an error,you can check the value of the Bytes_Available field in the error structure. Avalue of zero means that an error was not encountered. If an error wasencountered, this field contains the length of the data that was returned.

Chapter 13. Other Message APIs 179

Page 204: AnyMail/400 Mail Server Framework Developer Guide January 1995

Reserve Mail Message Identifier

This error structure will not return errors if the caller requests to haveexceptions signalled. The caller requests exceptions to be signalled bysetting the Bytes_Provided field of the error structure to zero when the API iscalled. The Bytes_Provided field is defined in the Qus_EC_t structure(included in member qusec of file H).

This error structure is the common error structure used by system APIs. Formore information on this common error structure, see the System APIReference.

Return ValueThe Bytes_Available field in the error structure indicates the status of the APIcall:

0 QzmfRsvMailMsgId was successful.

> 0 QzmfRsvMailMsgId was not successful. The Error_Str error structureincludes the error information.

Error ConditionsIf QzmfRsvMailMsgId is not successful, the Exception_Id field of the Error_Strerror structure usually indicates one of the following errors. Data associatedwith the error can be found in the Exception_Data field of the error structure.

The following errors may be signalled (rather than returned in the Error_Str errorstructure) if the caller of the API requested to have exceptions signalled.

See the message descriptions in file QCPFMSG of library QSYS for a descriptionof the error′s associated data. The descriptions can be seen using the DisplayMessage Description (DSPMSGD) command.

CPF24B4 ESevere error while addressing parameter list. The API encountered an errorwhile attempting to access a parameter.

CPF9872 EProgram or service program &1 in library &2 ended. Reason code &3. Thespecified program or service program was ended due to the reason codespecified.

CPFAF82 EError occurred during the running of the MSF API. The reason code is &1.The reason code gives specific information about the cause of the error. Forexample, reason code 02 indicates that the MSF queue was not found.

CPFAF83 EParameter error on a call to the MSF API. Reason code &1. A parameterpassing error occurred while trying to call the API. The reason code givesspecific information about the cause of the error. For example, reason code10 indicates that an incorrect number of parameters were specified.

Related Information• The qzmfasrv.h file is shown in Appendix G, “Qzmfasrv Header File” on

page 375.• The common error structure is described in the System API Reference.

180 AnyMail/400 MSF

Page 205: AnyMail/400 Mail Server Framework Developer Guide January 1995

Reserve Mail Message Identifier

ExampleThe following example is a section of code that calls the Reserve Mail MessageIdentifier API to reserve two MSF message identifiers. For the completeexample, see “Program to Reserve and Query Message — Example” onpage 350.

.

.

.

void main(void){

Qzmf_Msg_Id_t Msg_Id, Msg_Id_To_Remove;

Qzmf_Msg_Id_Qry_Status_t Msg_Qry_Status, Msg_Qry_Status1;

Error_Code_t Reserve_Error_Code;

/* Specify that exceptions should be signalled from the *//* API rather than using return codes. */Reserve_Error_Code.Error.Bytes_Provided = 0;

/* Reserve two MSF message identifiers */#pragma exception_handler(Quit_Execution, 0, 0, _C2_MH_ESCAPE)

QzmfRsvMailMsgId((void*)Msg_Id

, QZMF_RSV_MAIL_MSG_FORMAT, (void *)(&Reserve_Error_Code) );

QzmfRsvMailMsgId((void*)Msg_Id_To_Remove

, QZMF_RSV_MAIL_MSG_FORMAT, (void *)(&Reserve_Error_Code) );

#pragma disable_handler

/* Print the reserved message IDs */printf(″The First Reserved Msg Id: %.32s\n″ , Msg_Id);printf(″The Second Reserved Msg Id: %.32s\n″ , Msg_Id_To_Remove);

/* Create an MSF message with ″Msg_Id″ as its ID */ Create_A_Reserved_Message( Msg_Id );

.

.

.

Chapter 13. Other Message APIs 181

Page 206: AnyMail/400 Mail Server Framework Developer Guide January 1995

Remove Reserved Mail Message Identifier

Remove Reserved Mail Message Identifier (QzmfRmvRsvMailMsgId) API Syntax

#include <qzmfasrv.h>void QzmfRmvRsvMailMsgId(

void *Rsvrd_Msg_ID, /* Reserved MSF Msg ID */char *Fmt_Name, /* Format Name */void *Error_Str /* API Returned Error */

);

The Remove Reserved Mail Message Identifier (QzmfRmvRsvMailMsgId) APIremoves a reserved MSF message identifier that was reserved earlier.

ParametersMsg_ID

A pointer to a field that contains a unique message identifier that is to beremoved from reserved status. After a reserved message identifier has beenremoved, the message identifier can no longer be used with the Create MailMessage (QzmfCrtMailMsg) API. The reserved message identifier iscomposed of characters A through Z and 0 through 9 only. TheQzmf_Msg_ID_t structure in the Qzmf header file defines this field. For moreinformation on field, see Appendix F, “Qzmf Header File” on page 356.

Fmt_NameA pointer to the format name of the parameter list that is being passed. Thisfield must be set to RMVF0100. The Qzmf_Format_Name_t structure in theQzmf header file defines the contents of this field. For more information, seeAppendix F, “Qzmf Header File” on page 356.

Error_StrA pointer to the error structure. To determine if the API returned an error,you can check the value of the Bytes_Available field in the error structure. Avalue of zero means that an error was not encountered. If an error wasencountered, this field contains the length of the data that was returned.

This error structure will not return errors if the caller requests to haveexceptions signalled. The caller requests exceptions to be signalled bysetting the Bytes_Provided field of the error structure to zero when the API iscalled. The Bytes_Provided field is defined in the Qus_EC_t structure(included in member qusec of file H).

This error structure is the common error structure used by system APIs. Formore information on this common error structure, see the System APIReference.

Return ValueThe Bytes_Available field in the error structure indicates the status of the APIcall:

0 QzmfRmvRsvMailMsgId was successful.

> 0 QzmfRmvRsvMailMsgId was not successful. The Error_Str error structureincludes the error information.

182 AnyMail/400 MSF

Page 207: AnyMail/400 Mail Server Framework Developer Guide January 1995

Remove Reserved Mail Message Identifier

Error ConditionsIf QzmfRmvRsvMailMsgId is not successful, the Exception_Id field of the Error_Strerror structure usually indicates one of the following errors. Data associatedwith the error can be found in the Exception_Data field of the error structure.

The following errors may be signalled (rather than returned in the Error_Str errorstructure) if the caller of the API requested to have exceptions signalled.

See the message descriptions in file QCPFMSG of library QSYS for a descriptionof the error′s associated data. The descriptions can be seen using the DisplayMessage Description (DSPMSGD) command.

CPF24B4 ESevere error while addressing parameter list. The API encountered an errorwhile attempting to access a parameter.

CPF9872 EProgram or service program &1 in library &2 ended. Reason code &3. Thespecified program or service program was ended due to the reason codespecified.

CPFAF82 EError occurred during the running of the MSF API. The reason code is &1.The reason code gives specific information about the cause of the error. Forexample, reason code 02 indicates that the MSF queue was not found.

CPFAF83 EParameter error on a call to the MSF API. Reason code &1. A parameterpassing error occurred while trying to call the API. The reason code givesspecific information about the cause of the error. For example, reason code10 indicates that an incorrect number of parameters were specified.

CPFAF8B EReserved mail message identifier is not valid. The API was called withreserved message identifier &1. However, the reserved mail messageidentifier could not be found.

CPFAF8D EReserve mail message identifier already used. The API was called withreserved message identifier &1. However, the reserved mail messageidentifier had already been used to create an MSF message.

Related Information• The qzmfasrv.h file is shown in Appendix G, “Qzmfasrv Header File” on

page 375.• The common error structure is described in the System API Reference.

ExampleThe following example is a section of code that calls the Remove Reserved MailMessage Identifier API to remove a reserved MSF message identifier. For thecomplete example, see “Program to Reserve and Query Message — Example”on page 350.

Chapter 13. Other Message APIs 183

Page 208: AnyMail/400 Mail Server Framework Developer Guide January 1995

Complete Creation Sequence

.

.

.

/****************************************************************//* invoke the QzmfRsvMailMsgId API to reserve an MSF message ID *//****************************************************************/

#pragma exception_handler(Quit_Execution, 0, 0, _C2_MH_ESCAPE)

QzmfRsvMailMsgId((void*)Msg_Id_To_Remove

, QZMF_RSV_MAIL_MSG_FORMAT, (void *)(&Reserve_Error_Code) );

#pragma disable_handler

.

.

.

/****************************************************************//* Now we are ready to remove the reserved message IDs from MSF.*//****************************************************************/

#pragma exception_handler(Quit_Execution, 0, 0, _C2_MH_ESCAPE)

QzmfRmvRsvMailMsgId((void *)Msg_Id_To_Remove

, QZMF_RMV_RSV_MAIL_MSG_FORMAT, (void *)(&Reserve_Error_Code) );

#pragma disable_handler

.

.

.

Complete Creation Sequence (QzmfCrtCmpMailMsg) API Syntax

#include <qzmfasrv.h> void QzmfCrtCmpMailMsg(

void *Rsvrd_Msg_ID, /* Reserved MSF Msg ID */char *Fmt_Name, /* Format Name */void *Error_Str /* API Returned Error */

);

The Complete Creation Sequence (QzmfCrtCmpMailMsg) API removes areserved MSF message identifier from MSF′s list of reserved mail identifiers.

184 AnyMail/400 MSF

Page 209: AnyMail/400 Mail Server Framework Developer Guide January 1995

Complete Creation Sequence

ParametersMsg_ID

A pointer to a field that contains the unique message identifier beingcompleted. The message identifier is composed of characters A through Zand 0 through 9 only. The Qzmf_Msg_ID_t structure in the Qzmf header filespecifies this field. For more information on this field, see Appendix F,“Qzmf Header File” on page 356.

Fmt_NameA pointer to the format name of the parameter list that is being passed to theAPI. This field must be set to CCMP0100. The Qzmf_Format_Name_tstructure in the Qzmf header file defines the contents of this field. For moreinformation, see Appendix F, “Qzmf Header File” on page 356.

Error_StrA pointer to the error structure. To determine if the API returned an error,you can check the value of the Bytes_Available field in the error structure. Avalue of zero means that an error was not encountered. If an error wasencountered, this field contains the length of the data that was returned.

This error structure will not return errors if the caller requests to haveexceptions signalled. The caller requests exceptions to be signalled bysetting the Bytes_Provided field of the error structure to zero when the API iscalled. The Bytes_Provided field is defined in the Qus_EC_t structure(included in member qusec of file H).

This error structure is the common error structure used by system APIs. Formore information on this common error structure, see the System APIReference.

Return ValueThe Bytes_Available field in the error structure indicates the status of the APIcall:

0 QzmfCrtCmpMailMsg was successful.

> 0 QzmfCrtCmpMailMsg was not successful. The Error_Str error structureincludes the error information.

Error ConditionsIf QzmfCrtCmpMailMsg is not successful, Exception_Id field of the Error_Str errorstructure usually indicates one of the following errors. Data associated with theerror can be found in the Exception_Data field of the error structure.

The following errors may be signalled (rather than returned in the Error_Str errorstructure) if the caller of the API requested to have exceptions signalled.

See the message descriptions in file QCPFMSG of library QSYS for a descriptionof the error′s associated data. The descriptions can be seen using the DisplayMessage Description (DSPMSGD) command.

CPF24B4 ESevere error while addressing parameter list. The API encountered an errorwhile attempting to access a parameter.

Chapter 13. Other Message APIs 185

Page 210: AnyMail/400 Mail Server Framework Developer Guide January 1995

Complete Creation Sequence

CPF9872 EProgram or service program &1 in library &2 ended. Reason code &3. Thespecified program or service program was ended due to the reason codespecified.

CPFAF82 EError occurred during the running of the MSF API. The reason code is &1.The reason code gives specific information about the cause of the error. Forexample, reason code 02 indicates that the MSF queue was not found.

CPFAF83 EParameter error on a call to the MSF API. Reason code &1. A parameterpassing error occurred while trying to call the API. The reason code givesspecific information about the cause of the error. For example, reason code10 indicates that an incorrect number of parameters were specified.

CPFAF8B EReserved mail message identifier is not valid. The API was called withreserved message identifier &1. However, the reserved mail messageidentifier could not be found.

CPFAF8CReserved mail message identifier not used. The API was called withreserved message identifier &1. However, the reserved message identifierhas not been used in a call to the Create Mail Message (QzmfCrtMailMsg)API.

Related Information• The qzmfasrv.h file is shown in Appendix G, “Qzmfasrv Header File” on

page 375.• The common error structure is described in the System API Reference.

ExampleThe following example is a section of a code that calls the Complete CreationSequence API to remove a reserved MSF message identifier. For the completeexample, see “Program to Reserve and Query Message — Example” onpage 350.

.

.

./****************************************************************//* invoke the QzmfRsvMailMsgId API to reserve an MSF message ID *//****************************************************************/

#pragma exception_handler(Quit_Execution, 0, 0, _C2_MH_ESCAPE)

QzmfRsvMailMsgId((void*)Msg_Id

, QZMF_RSV_MAIL_MSG_FORMAT, (void *)(&Reserve_Error_Code) );

#pragma disable_handler

/* Create an MSF message with Msg_Id as its ID */

186 AnyMail/400 MSF

Page 211: AnyMail/400 Mail Server Framework Developer Guide January 1995

Query Mail Message Identifier

Create_A_Reserved_Message( Msg_Id );

.

.

.

/****************************************************************//* Now we are ready to remove the reserved message IDs from MSF.*//****************************************************************/

#pragma exception_handler(Quit_Execution, 0, 0, _C2_MH_ESCAPE)

QzmfCrtCmpMailMsg((void *)Msg_Id

, QZMF_CRT_CMP_MAIL_MSG_FORMAT, (void *)(&Reserve_Error_Code) );

#pragma disable_handler

.

.

.

Query Mail Message Identifier (QzmfQryMailMsgId) API Syntax

#include <qzmfasrv.h>void QzmfQryMailMsgId(

void *Msg_ID, /* MSF message ID */char *Fmt_Name, /* Format Name */char *Qry_Status, /* Status of the Msg */void *Error_Str /* API Returned Error */

);

The Query Mail Message Identifier (QzmfQryMailMsgId) API is used to determineif an MSF message identifier is known to MSF.

ParametersThe following parameters must be passed to the Query Mail Message Identifier(QzmfQryMailMsgId) API:

Msg_IDA pointer to a field that contains a unique message identifier that is beingqueried as to whether it is known by the mail server framework. The Msg_IDfield is composed of characters A through Z and 0 through 9 only. TheQzmf_Msg_ID_t structure in the Qzmf header file defines this field. For moreinformation on this field, see Appendix F, “Qzmf Header File” on page 356.

Fmt_NameA pointer to the format name of the parameter list that is being passed to theAPI. This field must be set to QRYF0100. The Qzmf_Format_Name_tstructure in the Qzmf header file specifies the contents of this field. Formore information, see Appendix F, “Qzmf Header File” on page 356.

Chapter 13. Other Message APIs 187

Page 212: AnyMail/400 Mail Server Framework Developer Guide January 1995

Query Mail Message Identifier

Qry_StatusA pointer to a character field that indicates whether MSF knows of the MSFmessage. This field contains one of the following:

0 The MSF message identifier is not known by the mail serverframework. The MSF message associated with this identifier mayhave already been processed.

1 The MSF message identifier is known by the mail serverframework. This status indicates that the MSF message wascreated by using the Create Mail Message (QzmfCrtMailMsg) API.The MSF message either is being processed or is waiting to beprocessed by the framework.

2 The MSF message identifier was reserved by using the ReserveMail Message Identifier (QzmfRsvMailMsgId) API. The MSFmessage was also created by using the Create Mail Message(QzmfCrtMailMsg) API. The MSF message either is beingprocessed or is waiting to be processed by the framework.

3 The MSF message identifier was reserved by using the ReserveMail Message Identifier (QzmfRsvMailMsgId) API. The MSFmessage was also created by using the Create Mail Message(QzmfCrtMailMsg) API. The MSF message no longer exists in themail server framework. The MSF message associated with thismail server identifier has already been processed by theframework. However, the Complete Creation Sequence(QzmfCrtCmpMailMsg) API has not been called to remove themessage identifier from the framework.

4 The MSF message identifier was reserved by using the ReserveMail Message Identifier (QzmfRsvMailMsgId) API. However, theCreate Mail Message (QzmfCrtMailMsg) API has not been used tocreate an MSF message using this message identifier.

The Qzmf_Msg_Id_Qry_Status_t structure in the Qzmf header file specifiesthis field. For more information, see Appendix F, “Qzmf Header File” onpage 356.

Error_StrA pointer to the error structure. To determine if the API returned an error,you can check the value of the Bytes_Available field in the error structure. Avalue of zero means that an error was not encountered. If an error wasencountered, this field contains the length of the data that was returned.

This error structure will not return errors if the caller requests to haveexceptions signalled. The caller requests exceptions to be signalled bysetting the Bytes_Provided field of the error structure to zero when the API iscalled. The Bytes_Provided field is defined in the Qus_EC_t structure(included in member qusec of file H).

This error structure is the common error structure used by system APIs. Formore information on this common error structure, see the System APIReference.

188 AnyMail/400 MSF

Page 213: AnyMail/400 Mail Server Framework Developer Guide January 1995

Query Mail Message Identifier

Return ValueThe Bytes_Available field in the error structure indicates the status of the APIcall:

0 QzmfQryMailMsgId was successful.

> 0 QzmfQryMailMsgId was not successful. The Error_Str error structureincludes the error information.

Error ConditionsIf QzmfQryMailMsgId is not successful, Exception_Id field of the Error_Str errorstructure usually indicates one of the following errors. Data associated with theerror can be found in the Exception_Data field of the error structure.

The following errors may be signalled (rather than returned in the Error_Str errorstructure) if the caller of the API requested to have exceptions signalled.

See the message descriptions in file QCPFMSG of library QSYS for a descriptionof the error′s associated data. The descriptions can be seen using the DisplayMessage Description (DSPMSGD) command.

CPF24B4 ESevere error while addressing parameter list. The API encountered an errorwhile attempting to access a parameter.

CPF9872 EProgram or service program &1 in library &2 ended. Reason code &3. Thespecified program or service program was ended due to the reason codespecified.

CPFAF82 EError occurred during the running of the MSF API. The reason code is &1.The reason code gives specific information about the cause of the error. Forexample, reason code 02 indicates that the MSF queue was not found.

CPFAF83 EParameter error on a call to the MSF API. Reason code &1. A parameterpassing error occurred while trying to call the API. The reason code givesspecific information about the cause of the error. For example, reason code10 indicates that an incorrect number of parameters were specified.

CPFAF84 EMSF API failed. MSF message identifier not found. The API was called withMSF message identifier &3. However, the message identifier could not befound. The most common reasons for this error are:

The message ID in the Msg_ID field was specified incorrectly

The Create Mail Message (QzmfCrtMailMsg) API did not create an MSFmessage with this ID

The MSF message with this ID has already been processed by MSF

Chapter 13. Other Message APIs 189

Page 214: AnyMail/400 Mail Server Framework Developer Guide January 1995

Query Mail Message Identifier

Related Information• The qzmfasrv.h file is shown in Appendix G, “Qzmfasrv Header File” on

page 375.• The common error structure is described in the System API Reference.

ExampleThe following example is a section of a code that calls the Query Mail MessageIdentifier API to query the status of an MSF message. For a complete example,see “Program to Reserve and Query Message — Example” on page 350.

.

.

.

/**********************************************************************//* The Print_Qry_Status function prints the result of an MSF message *//* query in a readable form. *//**********************************************************************/

static void Print_Qry_Status(Qzmf_Msg_Id_Qry_Status_t Msg_Qry_Status

){

switch (Msg_Qry_Status){

case QZMF_MSG_ID_UNKNOWN:printf(″Message ID is unknown to MSF.\n″ ) ;break;

case QZMF_MSG_ID_CREATED:printf(″Message ID has been created by MSF.\n″ ) ;break;

case QZMF_MSG_ID_RSVRD_AND_CREATED:printf(″Message ID has been reserved and created.\n″ ) ;break;

case QZMF_MSG_ID_RSVRD_AND_PROCSSD:printf(″Message ID has been created, and″

″processed by MSF, but not yet removed.\n″ ) ;break;

case QZMF_MSG_ID_RESERVED:printf(″Message ID has been reserved but not yet created.\n″ ) ;break;

default:printf(″Unknown Status passed: %c; quitting″ , Msg_Qry_Status);exit(1);

} /* end of switch (on different Query statuses) */

} /* end of Print_Qry_Status function */

void main(void){

.

190 AnyMail/400 MSF

Page 215: AnyMail/400 Mail Server Framework Developer Guide January 1995

Query Mail Message Identifier

.

.

/* Create an MSF message with Msg_Id as its ID */ Create_A_Reserved_Message( Msg_Id );

#pragma exception_handler(Quit_Execution, 0, 0, _C2_MH_ESCAPE)

/* Inquire about the reserved message′ s status in MSF */QzmfQryMailMsgId(

(void *)Msg_Id, QZMF_QRY_MAIL_MSG_FORMAT, &Msg_Qry_Status, (void *)(&Reserve_Error_Code) );

#pragma disable_handler

Print_Qry_Status( Msg_Qry_Status );

.

.

.

} /* end of main */

Chapter 13. Other Message APIs 191

Page 216: AnyMail/400 Mail Server Framework Developer Guide January 1995

Validate Data Field Exit Point

Chapter 14. Additional Exit Point Interfaces

This chapter describes two additional exit point interfaces that are supported bythe mail server framework. These two exit points allow you to provide exit pointprograms that can supply additional function. Programs registered in thevalidate data field exit point can verify that data is of a specific type. Programsregistered in the track mail changes exit point can track changes to an MSFmessage as it moves through the mail server framework.

This chapter describes the data that is passed to the exit point programsregistered in these exit points. For more information on exit points, seeChapter 6, “Mail Server Framework Exit Points” on page 80. For information onconfiguring types of data that can be used by the validate data field exit point,see Chapter 3, “Mail Server Framework Configuration” on page 18.

Validate Data Field Exit PointThe mail server framework provides the validate data field exit point(QIBM_QZMFMSF_VLD_TYP) where you can register exit point programs foradditional data checking.

The exit point programs are called when MSF messages are created or changedby using the Create Mail Message (QzmfCrtMailMsg) or Change Mail Message(QzmfChgMailMsg) APIs, and the MSF message contains a data type for which avalidate data field exit point program is configured. The exit point programs canbe registered to be called when a message having a specific data type (or a datatype belonging to a particular data type group) is created or changed. Onlymessage list entries that have a matching data type are passed to the exit pointprograms. The program is called whenever any information that matches theconfigured selection data is added to the message.

When the validate data field exit point program completes, it must return itsstatus in the return code parameter. If the return code from the exit pointprogram is zero, the changed data is assumed to be valid and accepted. If thereturn code is not zero, the data is assumed to be not valid and the create orchange is rejected.

Parameters of the Validate Data Field Exit Point Program

1 Mail message identif ier Input Char(32)2 Message descriptor attributes Input Array of

Char(*)3 Number of message descriptor attributes Input Binary(4)4 Format name Input Char(8)5 Return code Output Binary(4)

ParametersParameters are passed to ILE C/400 programs in the argc and argv variables.The argc integer variable specifies the number of parameters in the argvvariable. The argv variable is an array of character pointers (char *argv [ ]) thatpoint to the parameters. For more information, see the ILE C/400 Programmer’sGuide.

192 Copyright IBM Corp. 1995

Page 217: AnyMail/400 Mail Server Framework Developer Guide January 1995

Validate Data Field Exit Point

The following parameters are passed by MSF to the validate data field exit pointprogram in the argv variable:

Msg_ID (argv [1])A pointer to a field that contains a message identifier associated with theMSF message that is being created or changed. The mail message identifieris composed of characters A through Z and 0 through 9 only.

Msg_Desc (argv [2])A pointer to an array of message descriptor attributes for the data that is tobe validated. Structure Qzmf_Msg_Desc_Attribt_Entity_t in the Qzmf headerfile specifies the contents of this field. For more information on this field, seeAppendix F, “Qzmf Header File” on page 356.

Num_of_Desc (argv [3])A pointer to the number of elements in the array of message descriptorattributes.

Fmt_Name (argv [4])A pointer to the format name of the parameter list in which information isbeing passed. This field is set to VDFF0100 by MSF.

Return_code (argv [5])A pointer to the field that contains the return code. This is a long integerfield. The possible values are:

0 Data was valid.

1 Data was not valid.

2 Severe error encountered

Error ConditionsIf the validate data field exit point program is not successful, the program mustset the Return_code field to indicate the error.

Related InformationThe qzmf.h header file is shown in Appendix F, “Qzmf Header File” onpage 356.

ExampleThe following example is a section of code for a program that could be calledfrom the validate data field exit point.

#include <qzmf.h>

int main( int argc, char *argv[] ) {

long int num_of_parms, *Return_Code, *Num_of_Desc;

Qzmf_Msg_Desc_Attrbt_Entity_t *Msg_Desc;char *Fmt_Name;char *Msg_ID;

Chapter 14. Additional Exit Point Interfaces 193

Page 218: AnyMail/400 Mail Server Framework Developer Guide January 1995

Track Mail Message Changes Exit Point

/* Get the number of parameters passed */num_of_parms = argc;

/* Get the message identifier */Msg_ID = argv[1];

/* Set up pointer to message descriptor array */Msg_Desc = (Qzmf_Msg_Desc_Attrbt_Entity_t *) argv[2];

/* Get the number of message descriptors */Num_of_Desc = (long int *) argv[3];

/* Get the format name */Fmt_Name = argv[4];

/* Get the pointer to the return code area */Return_Code = (long int *)(argv[5]);

.

./*************************************************************//* This is where your code validates the data. You *//* need to use the message descriptor attributes array to *//* access the data in the created or changed message. *//*************************************************************/

.

./* set the return code according to the result of validating *//* the data. Here it is set to indicate success. */*Return_Code = 0;

Track Mail Message Changes Exit PointParameters of the Track Mail Message Changes Exit Point Program

The track mail message changes exit point (QIBM_QZMFMSF_TRK_CHG) helpstrack changes to an MSF message as it passes through the mail serverframework. Both, the exit point name and the name of an exit point programthat changed the MSF message, are passed to the track mail message changesexit point program.

The exit point program that is configured for this exit point is allowed to read allof the parts of a message to track the message. This track mail messagechanges exit point program, however, can only track the message and cannotaffect the processing of the message. The return code that is set by the exitpoint program is used by MSF for tracking purposes only, but does not affect theprocessing of the message.

1 Mail message identif ier Input Char(32)2 Exit point name Input Char(20)3 Qualified exit point program name Input Char(20)4 Format name Input Char(8)5 Return code Output Binary(4)

194 AnyMail/400 MSF

Page 219: AnyMail/400 Mail Server Framework Developer Guide January 1995

Track Mail Message Changes Exit Point

ParametersParameters are passed to ILE C/400 programs in the argc and argv variables.The argc integer variable specifies the number of parameters in the argvvariable. The argv variable is an array of character pointers (char *argv [ ]) thatpoint to the parameters. For more information, see the ILE C/400 Programmer’sGuide.

The following parameters are passed to the track mail changes exit pointprogram:

Msg_IDA pointer to a field that contains a message identifier. The message ID isassociated with the MSF message that was changed. The mail messageidentifier is composed of characters A through Z and 0 through 9 only.

Exit_PointA pointer to a field that contains the name of the MSF exit point where theMSF message was changed. A list of exit point names can be found in“IBM-Supplied Exit Points for the MSF” on page 22.

Exit_Pt_PgmA pointer to a field that contains the qualified name of the exit point programthat made the changes to the MSF message. The qualified name consists ofthe name of the library that contains the program followed by the name ofthe program.

Fmt_NameA pointer to the format name of the parameter list in which the track mailmessage changes exit point program is passed information. This field is setto TCMM0100 by MSF.

Return_codeA pointer to the field that contains the return code. This is a long integerfield. The possible values are:

0 Everything was OK.

1 Data was not valid.

2 Severe error encountered.

Note: This return code is added to the exit point call history for trackingpurposes and does not affect the processing of the message.

Error ConditionsIf the track mail message changes exit point program is not successful, theprogram must set the Return_code field to indicate the error.

Related InformationThe qzmf.h header file is shown in Appendix F, “Qzmf Header File” onpage 356.

Chapter 14. Additional Exit Point Interfaces 195

Page 220: AnyMail/400 Mail Server Framework Developer Guide January 1995

Track Mail Message Changes Exit Point

ExampleThe following example is a section of code for a program that could be calledfrom the track mail message changes exit point.

#include <qzmf.h>

int main( int argc, char *argv[] ) {

long int num_of_parms = argc /* number of parameters passed */, *Return_Code;

char *Msg_ID = argv[1]; /* message identifier */char *Exit_Point;char *Exit_Pt_Pgm;char *Fmt_Name = argv[4]; /* format name */

/* Set up pointer to the exit point name */Exit_Point = (Qzmf_Exit_Point *) argv[2];

/* Set up pointer to qualified exit point program name */Exit_Pt_Pgm = (Qzmf_Exit_Pgm_Lib_Name_t *) argv[3];

/* Get the pointer to the return code area */Return_code = (long int *)(argv[5]);

.

./*************************************************************//* This is where your code tracks the changes. You *//* need to use the message descriptor attributes array to *//* access the data. *//* *//* For example, you can use the Retrieve Mail Message API *//* to get the desired information. This can be done by *//* setting the appropriate data in the message descriptor *//* array. When the retrieve API returns, you can locate *//* the appropriate message list to get the desired *//* information. *//*************************************************************/

.

./* set the return code according to the result of this *//* program. Here it is set to indicate success. */*Return_code = 0;

196 AnyMail/400 MSF

Page 221: AnyMail/400 Mail Server Framework Developer Guide January 1995

Snap-In Call Exit Point

Chapter 15. Snap-In Call Exit Point Interface

This chapter describes the Snap-in Call exit point interface supported by the mailserver framework.

This chapter describes the data that is passed to the exit point programsconfigured for the snap-in call exit point. For more information on exit points,see Chapter 6, “Mail Server Framework Exit Points” on page 80.

Snap-In Call Exit PointThe snap-in call programming interface is used to pass information about anE-mail message to registered exit point programs. When the exit point programhas completed processing the message, it returns its status in the return codeparameter.

Parameters of the Snap-In Call Exit Point Program

1 Exit point name Input Char(20)2 Mail message identif ier Input Char(32)3 Message descriptor attributes Input Array of

Char(*)4 Number of message descriptor attributes Input Binary(4)5 Format name Input Char(8)6 Return code Output Binary(4)

ParametersParameters are passed to ILE C/400 programs in the argc and argv variables.The argc integer variable specifies the number of parameters in the argvvariable. The argv variable is an array of character pointers (char *argv [ ]) thatpoint to the parameters. For more information, see the ILE C/400 Programmer’sGuide.

The following parameters are passed to the snap-in call exit point program:

Exit_PointA pointer to a field that contains the name of the MSF exit point where theexit point program is being called.

Msg_IDA pointer to the field that contains a message identifier. the ID is associatedwith the MSF message that the snap-in call exit point program is to process.The mail message identifier is composed of characters A through Z and 0through 9 only.

Msg_DescA pointer to an array of message descriptor attributes for the data that isbeing passed. Structure Qzmf_Msg_Desc_Attribt_Entity_t in the Qzmf headerfile defines the contents of this field. For more information on this field, seeAppendix F, “Qzmf Header File” on page 356.

Num_of_DescA pointer to the number of elements in the array of message descriptorattributes.

Copyright IBM Corp. 1995 197

Page 222: AnyMail/400 Mail Server Framework Developer Guide January 1995

Snap-In Call Exit Point

Fmt_NameA pointer to the format name of the parameter list in which information isbeing passed. This field is set to SPCL0100 by MSF.

Return_codeA pointer to the field that contains the return code. This is a long integerfield. The possible values are:

0 MSF should commit all changes made by this exit point programand continue processing the message

1 MSF should undo any changes made, but continue processing themessage

2 End the mail server framework job

3 End the processing of this message

For the symbolic names representing the above values, see the qzmf.hheader file is shown in Appendix F, “Qzmf Header File” on page 356.

Error ConditionsIf the snap-in call exit point program is not successful, the program must set theReturn_code field to indicate the error.

Related InformationThe qzmf.h header file is shown in Appendix F, “Qzmf Header File” onpage 356.

ExampleFor an example, refer to the TLSTEXPN file shown in “List Expansion Exit PointProgram — Example” on page 322.

198 AnyMail/400 MSF

Page 223: AnyMail/400 Mail Server Framework Developer Guide January 1995

Chapter 16. Creating an MSF Program in ILE C/400

This chapter describes how to create an MSF program. An MSF program is anyprogram that either uses the MSF APIs or is registered for one of the MSF exitpoints.

MSF Application ProgramsYou should follow the recommended two-step process described in the ILE C/400Programmer’s Reference to create an MSF program. The entire process ofcreating ILE C/400 modules and programs is explained in the following topics bymeans of an example. All the source code for this example is in Appendix E,“An MSF Application — Example” on page 294. For more information about theIntegrated Language Environment and ILE C/400, see Integrated LanguageEnvironment Concepts, ILE C/400 Reference Summary, and the ILE C/400Programmer’s Guide.

Creating a Module and Program in ILE C/400 — ExampleAssume the source code of Appendix E, “An MSF Application — Example” onpage 294 is in file QZMFSAMPLE/QZMFSAMPLE as member TCRTMOD. First,create the corresponding C module by invoking the ILE C/400 compiler. Tocreate the ILE C/400 module, use the Create ILE C/400 Module (CRTCMOD)command as follows:

CRTCMOD MODULE(QZMFSAMPLE/TCRTMOD)SRCFILE(QZMFSAMPLE/QZMFSAMPLE)SRCMBR(TCRTMOD)TEXT(′ Create MSF Test Message Module′ )

You can specify additional parameters such as OUTPUT, OPTIMIZE, andDBGVIEW with appropriate values.

You can create other ILE C/400 modules in a similar way. Now assume that youhave another module, TCRTMSG, in library QZMFSAMPLE. After creating all therequired modules, use the Create Program (CRTPGM) command to bind them alltogether to produce the executable file (program).

CRTPGM PGM(QZMFSAMPLE/TCRTMSG)MODULE(QZMFSAMPLE/TCRTMSG QZMFSAMPLE/TCRTMOD)TEXT(′ Create MSF TEST Message Program′ )USRPRF(*OWNER)

This example demonstrates the creation of a simple MSF program. Otherparameters of the CRTPGM command can be specified.

Special Considerations for MSF Exit Point ProgramsWhen you create MSF exit point programs, remember the following:

• You must register exit point programs by using the Work with RegistrationInformation (WRKREGINF) command. If an exit point program is notregistered, it cannot be called by MSF. For more information, see Chapter 3,“Mail Server Framework Configuration” on page 18.

• MSF stores pointers to the exit point programs. If you re-create an exit pointprogram, you must restart MSF (by using the ENDMSF and STRMSF

Copyright IBM Corp. 1995 199

Page 224: AnyMail/400 Mail Server Framework Developer Guide January 1995

commands) to have MSF recognize your new exit point program. Otherwise,MSF continues to call the old exit point program because a CRTPGMcommand does not delete an existing object, but merely copies it to theQRPLOBJ library.

The following steps describe a method that you can use to re-create exitpoint programs without having to restart MSF:

1. Make sure that your exit point program to be replaced (for example,MYLIB/MYSNAP) is not going to get called until the entire creationprocess completes.

2. Use the Delete Program (DLTPGM) command to delete the existing exitpoint program.

3. Use Create Program (CRTPGM) command to create the new version ofthe exit point program.

Now MSF is able to call the new version of the program without having torestart MSF (because the previous version of the program was deletedrather than copied to the QRPLOBJ library). However, any attempt to callthe program by MSF between the time that the original program is deletedand the time that the new program is created causes the QMSF job to end(because the program does not exist).

• Exit point programs must have the correct authority to the correspondingOS/400 objects that they use. Exit point programs are called by QMSF jobsthat use the QMSF user profile. However, the QMSF user profile does nothave authority to use any objects (including the MSF APIs). Therefore, if anexit point program uses the QMSF user profile, all the MSF API calls will failwith the “authority violation” exception.

Also, granting the QMSF profile authority to the required objectscompromises the system′s security (because unauthorized exit pointprograms can access OS/400 objects).

Therefore, it is recommended that all exit point programs use the userprofile provided with the application, not the QMSF profile. You shouldauthorize the application′s profile to the required objects and create the exitpoint programs such that they adopt authority of the application′s profile.This is described in the following steps:

1. Do not modify the shipped version of the QMSF user profile.

2. Create a user profile that wil l be the owner of the programs. Assumethat MAILAP is the created profile for this example (see Appendix E, “AnMSF Application — Example” on page 294).

3. Sign-on to the AS/400 using the MAILAP profile.

4. Create the exit point program, MYLIB/MYSNAP for example, by using theCRTPGM command in “Creating a Module and Program in ILE C/400 —Example” on page 199. Because MAILAP is the current profile, MAILAPnow owns program MYSNAP. Also, because USRPRF(*OWNER) isspecified, the MYSNAP program adopts MAILAP′s authority.

5. Use the Grant Object Authority (GRTOBJAUT) command to grant theMAILAP profile authority to all the MSF APIs that the exit point programuses. This command must be done either by the security officer or by auser profile having all object (*ALLOBJ) authority. For example, assumeyour exit point program MYLIB/MYSNAP uses the QZMFACRT API. The

200 AnyMail/400 MSF

Page 225: AnyMail/400 Mail Server Framework Developer Guide January 1995

following GRTOBJAUT command grants profile MAILAP authority to usethe QZMFACRT program:

GRTOBJAUT OBJ(QSYS/QZMFACRT) OBJTYPE(*PGM) USER(MAILAP) AUT(*USE).

See Table 21 on page 206 for a list of program names corresponding tothe MSF APIs.

• In addition to the APIs, the owning profile must also have proper authoritiesto all the other objects that the exit point programs require (like libraries andfiles).

• When creating exit point programs, sign on to the system with the profile thatshould own the program. Then, when using the CRTPGM command, specifyUSRPRF(*OWNER) (see “Creating a Module and Program in ILE C/400 —Example” on page 199). This creates the exit point program with the currentprofile as the owner.

By specifying USRPRF(*OWNER) on the CRTPGM command, the programadopts the owning profile′s authority. This ensures that the exit pointprogram uses the owning profile (MAILAP in the example) for authoritychecking, even though it gets called by the QMSF job that runs with theQMSF profile. Because the owning profile has been granted all the requiredauthorities, the exit point program should be able to use the required MSFAPIs and other required objects.

Specific ILE C/400 Features and MSF Application ProgramsThis topic describes certain subtle ILE C/400 features that may provide someassistance when you develop MSF application program. This topic assumes youare familiar with ILE C/400. For information on ILE C/400, see IntegratedLanguage Environment Concepts.

Selection of the Best Activation Group: In creating this sample program under“Creating a Module and Program in ILE C/400 — Example” on page 199, weused the system default option, *NEW, for the ACTGRP parameter. Therefore,the created program runs in a system-numbered, unique activation group. Theadvantages of selecting a proper activation group for an exit point program aredescribed in the following paragraphs.

If you create an exit point program by specifying value *CALLER for the ACTGRPparameter of the CRTPGM command, the program runs in the default activationgroup, *DFTACTGRP. This reduces the startup time of the program to someextent because no new activation group needs to be created (*DFTACTGRPalready exists). The *DFTACTGRP activation group stays alive until the QMSFjob ends. The exit point program can use the activation group by storing andusing the values of global variables, of temporary data management resourceslike ODPs, and of local SQL cursors across program calls.

Some ANSI C features, however, may not work in the default activation group.For example, no program normal termination function can be registered throughthe atexit function if the program runs in *DFTACTGRP. However, choosing*NEW as the activation group will consume a constant amount of startup timeevery time the exit point program gets called. Before passing control to the exitpoint program ′s main function, OS/400 creates a system-numbered activationgroup for the program.

Chapter 16. Creating an MSF Program in ILE C/400 201

Page 226: AnyMail/400 Mail Server Framework Developer Guide January 1995

A compromise can be attained in some cases if you use a user-named activationgroup for the program and do not use the exit function inside the program undernormal circumstances. The exit function destroys the user-named activationgroup. By using a user-named activation group, the activation group creationtime is added to the program startup only at the first time it is called. After that,the program can continue to use the user-named activation group withoutincurring any overhead.

Similar to the *DFTACTGRP default activation group, a user-named activationgroup can also be used by an MSF application program to preserve the values ofglobal resources across subsequent calls. Programming for a user-namedactivation group or the *DFTACTGRP activation group requires extra care inhandling the initialization of static variables. The static variables are initializedby OS/400 only for the first call. Also note that ANSI C semantics is guaranteedto work only in a *NEW activation group.

How Character Arrays are Interpreted: Perhaps the most important differencebetween the underlying semantics of MSF internal data structures and ANSI C isthe way that the character arrays get interpreted. In ANSI C, a character arrayis usually ended by a ′ \0′ (null) character, and to store a string of n characters,a character array of (n+1) elements is needed.

MSF APIs, similar to other OS/400 APIs, do not expect this null character. For alltheir data structures, MSF APIs expect an n-character array for an n-bytecharacter string. Hence, in copying strings to and from MSF API-definedcharacter arrays, you should use the popular ANSI C functions of string.h withcaution. Functions like strcpy and strcmp, which depend on the presence of the′ \0′ (null) character, should not be used when you use MSF API characterarrays. You should use character array manipulation functions such as memcpyand memcmp. The mem functions are usually more efficient than theircorresponding str counterparts.

Signal Handling Mechanism for Abnormal End: Another subtle difference of ILEC/400 from standard ANSI C can be found in the signal handling mechanism. Ona job cancellation request, OS/400 does not raise a SIGTERM signal. SIGTERMcan be raised only by an explicit use of the raise function. You cannot use aSIGTERM signal handler to perform any cleanup activity associated with a jobending abnormally. Use either the cancel_handler #pragma directive or theatiexit function. For more information, see the ILE C/400 Programmer’s Guideand ILE C/400 Programmer’s Reference.

Interactive Testing and Debugging of an MSF ApplicationYou can use the source level ILE C/400 debugger for interactive testing anddebugging of any MSF application program. When you use the ILE C/400debugger, you must create modules with a non-default value for the DBGVIEWparameter. Specify the *ALL value for the DBGVIEW parameter. Remember touse the CRTPGM command after creating all the required modules.

To ensure a smooth interactive testing and debugging session in a test ordevelopment environment, the following steps are suggested. (A test ordevelopment environment is one in which MSF can be controlled.)

202 AnyMail/400 MSF

Page 227: AnyMail/400 Mail Server Framework Developer Guide January 1995

1. Start only one QMSF job in the QSYSWRK subsystem and clear MSF of allunwanted messages. This can be achieved with the following STRMSFcommand:

STRMSF MSGOPT(*CLEAR) NBRMSFJOB(1)

Warning: You delete all existing MSF messages when you use theMSGOPT(*CLEAR) option on the STRMSF command. Make sure none of theexisting MSF messages are needed before using this option.

Alternatively, you can bring up the usual number of QMSF jobs and hold allbut one.

This allows for greater control in generating specific MSF messages and inencountering the desired breakpoints in the debugger session. When youhave only one active QMSF job, this ensures that all MSF messages areprocessed by that job. When you clear all existing MSF messages, thisensures that there will not be other messages interfering with the test.

2. Use the WRKACTJOB command to locate the one active QMSF job in theQSYSWRK subsystem.

3. Use the Start Service Job (STRSRVJOB) command to service the activeQMSF job from another AS/400 session. Use the job number, job user, andjob name to specify the QMSF job.

4. Use the Start Debug (STRDBG) command, with the name of your applicationprogram specified, to start the debugger.

5. Set the appropriate breakpoints.

6. Create test MSF messages with appropriate MSF data types and contents sothat your MSF application program gets called and processing stops at thebreakpoints.

7. Step through the breakpoints to test and debug your application.

8. Upon completion of the test, use the End Debug Mode (ENDDBG) commandto end debugging. Then, use the End Service Job (ENDSRVJOB) commandto end the servicing of the QMSF job.

For more information on the ILE C/400 debugger, see the ILE C/400Programmer’s Guide.

Packaging an MSF Mail ApplicationYou may want to provide an installation program with your mail application. Aninstallation program can make the task of distributing your mail applications toother systems easier.

Your installation program can perform the tasks required for your mailapplication to function. These tasks include the following:

• Restore the objects shipped with your application (including the application′sprofile).

• Grant the application′s profile authority to the MSF APIs.

• Register the application′s exit point programs by using theQusAddExitProgram API.

• Add MSF data types needed by your application to the MSF configuration.This can be done using the MSF configuration APIs.

Chapter 16. Creating an MSF Program in ILE C/400 203

Page 228: AnyMail/400 Mail Server Framework Developer Guide January 1995

Your installation program needs to use the appropriate commands (such asRestore Object (RSTOBJ), Grant Object Authority (GRTOBJAUT), and Work withRegistration Information (WRKREGINF)) and be called by a profile that has*ALLOBJ authority.

204 AnyMail/400 MSF

Page 229: AnyMail/400 Mail Server Framework Developer Guide January 1995

Chapter 17. Security and Authority

This chapter describes security and authority on AS/400 business computingsystems and how they relate to MSF.

AS/400 Program AuthorityThis topic gives the reader a brief overview of the security and authority aspectsof OS/400 that pertain to MSF. More detailed information on OS/400 security andauthority can be found in Security - Basic and Security - Reference.

Object AuthorityObject authority describes how a user can access an object. For every user,there is a corresponding user profile. Every object in the system (these includedatabase files and programs) is owned by a profile. The ability for non-ownerprofiles to access an object in the system depends on the profile′s authority tothe object. Different types of authorities exist for accessing an object. Theseinclude read authority (*USE), update authority (*CHANGE), administrativeauthority (*ALL), and no authority (*EXCLUDE). Typically, the system′s securityadministrator, security officer, or the object′s owner specifies what objectauthorities are given to profiles.

An object′s authorities can be seen using the Display Object Authority(DSPOBJAUT) command. Users with profiles that have administrative authorityfor an object can change the object′s authorities. You can use the Grant ObjectAuthority (GRTOBJAUT) command, Revoke Object Authority (RVKOBJAUT)command, or Edit Object Authority (EDTOBJAUT) command to change anobject′s authorities.

Adopting Authority: Occasionally, a profile needs another authority to an objectunder different circumstances or situations. For instance, a user may berestricted to only view a file (*USE authority) in one situation, but may be allowedto update the same file (*CHANGE authority) by using an application program orcommand in another situation. This ability to update is provided when theprogram adopts the program owner′s authority. When the application programadopts the owner′s authority, the program allows the user with limited authorityto update the file. Programs (*PGM), service programs (*SRVPGM), and SQLpackages (*SQLPKG) can adopt owner authority. You can request that aprogram adopt authority by specifying the user profile (USRPRF) parameter onthe CRTPGM command or Change Program (CHGPGM) command.

It is recommended that applications using MSF have their programs adopt theauthority of a user profile supplied with the application (more on this in “MailApplications That Use MSF” on page 207). However, because adopting authorityallows a user to have more authority to objects than the user normally has, itshould be used with care. More information on adopting authorities can befound in Security - Reference.

Group profiles and authorization lists can also be used for authorizing objects.

Copyright IBM Corp. 1995 205

Page 230: AnyMail/400 Mail Server Framework Developer Guide January 1995

MSF Program AuthorityMSF is shipped as a collection of many objects, including programs, files, andqueues. Many of the objects can be used internally only by MSF. The systemallows users access to MSF (and its internal objects) through the use of the MSFcommands and APIs.

MSF Command AuthorityThe MSF commands are shipped with object authority of *PUBLIC *EXCLUDE.Therefore, users must be explicitly authorized to use the STRMSF and ENDMSFcommands. The security officer of the system must use the Grant ObjectAuthority (GRTOBJAUT) command or Edit Object Authority (EDTOBJAUT)command to authorize specific users to the commands. For example, thefollowing GRTOBJAUT command authorizes user JDOE to use the STRMSFcommand. However, JDOE is still not allowed to delete or modify the command.

GRTOBJAUT OBJ(QSYS/STRMSF) OBJTYPE(*CMD) USER(JDOE) AUT(*USE)

MSF API AuthorityThe MSF API programs are also shipped with object authority of *PUBLIC*EXCLUDE to restrict access to the APIs. Like the MSF commands, the securityofficer needs to explicitly authorize access to the API programs. For moreinformation on authorizing the use of the MSF APIs, see “Special Considerationsfor MSF Exit Point Programs” on page 199.

The following table lists the program names of the individual MSF APIs.

Table 21. MSF API Programs

API Name API Program Name API Description

QzmfAddMailCfg QSYS/QZMFADDC Add an MSF configuration

QzmfLstMailCfg QSYS/QZMFLSTC List MSF configuration

QzmfRmvMailCfg QSYS/QZMFDLTC Remove an MSF configuration

QzmfCrtMailMsg QSYS/QZMFACRT Create an MSF message

QzmfChgMailMsg QSYS/QZMFACHG Change an MSF message

QzmfRtvMailMsg QSYS/QZMFARTVRetrieve MSF messageinformation

QzmfCrtCmpMailMsg QSYS/QZMFASQC Complete creation sequence

QzmfQryMailMsgId QSYS/QZMFAQRY Query MSF message ID

QzmfRsvMailMsgId QSYS/QZMFARSV Reserve an MSF message ID

QzmfRmvRsvMailMsgId QSYS/QZMFASCRRemove a reserved MSFmessage ID

206 AnyMail/400 MSF

Page 231: AnyMail/400 Mail Server Framework Developer Guide January 1995

MSF File AuthorityThe MSF files are also shipped with object authority of *PUBLIC *EXCLUDE torestrict access. Users cannot directly access the files, but they can access theinformation in the files by using the MSF APIs. For example, you can see theconfigured MSF data types in the files by using the List Mail Server FrameworkConfiguration (QzmfLstMailCfg) API.

Mail Applications That Use MSFAll applications that use MSF should provide an owning user profile. This userprofile should own all objects provided with the application. In addition to beingowned by the profile, the application′s programs should also adopt the profile′sauthority. This is done by specifying value *OWNER for the user profile(USRPRF) parameter on the CRTPGM command.

For example, assume an electronic mail application has an owning user profile.If application program TRTVMSG is created for the local delivery exit point, thecommand to create the program with the adopted authority of the owning profilemight look like the following:

CRTPGM PGM(QZMFSAMPLE/TRTVMSG)MODULE(QZMFSAMPLE/TRTVMSG)TEXT(′ Local Delivery Program′ )USRPRF(*OWNER)

Also, make sure program TRTVMSG is owned by the application′s profile. Aprofile becomes the owner of a program by having that profile create theprogram or by using the Change Object Owner (CHGOBJOWN) command.

Installing Mail ApplicationsIf you are creating a mail application that uses MSF, you are probably eithermaking it specific to your own requirements or making it for general use (suchas a product to sell). In either situation, you need an easy method to install yourapplication.

You will need either detailed instructions on how to grant the requiredauthorities to your objects, or an installation program. Your installation programcan grant the application′s profile the required authority to use the MSF APIsand the WRKREGINF command. The program can also register the application′sexit point programs.

The installation program needs to use the appropriate commands and be calledby a profile having All Object (*ALLOBJ) authority.

Chapter 17. Security and Authority 207

Page 232: AnyMail/400 Mail Server Framework Developer Guide January 1995

Chapter 18. Error Handling in the Mail Server Framework

This chapter describes some of the methods that can be used to debug MSFapplications.

Because MSF uses exit points to integrate mail applications into the framework,it is possible for mail applications to affect MSF processing. Therefore, MSF hasthe ability to issue error messages if a mail application causes an error in MSFprocessing.

Note: The use of the term message in this chapter is different than in the otherchapters. In the other chapters, message means an MSF message or anE-mail message. In this chapter, message means an exception or errormessage that gives information about error. This chapter uses MSFmessage explicitly to refer to MSF messages.

Where to Look for Error InformationWhen mail applications that use MSF are not functioning properly, there are anumber of locations where information can be found. The location of the mostuseful information depends on the mail application that gives the information.Because mail applications may put their error information in different locations,refer to the specific mail applications to determine where to find errorinformation for that application. Also, the amount of error information providedvaries between mail applications. Some mail applications provide quite a bit oferror information, while other mail applications do not.

Because MSF uses exit points to integrate mail applications into the framework,it is possible for MSF to detect errors in the mail applications. When MSFdetermines that an error has occurred while processing an MSF message (eitherin a mail application or in MSF itself), it gives error information.

QSYSOPR Message QueueThe QSYSOPR message queue contains all severe error messages and alsomessages that pertain to the state of MSF. For example, a problem that causesa QMSF job to end will result in an error message being put on the QSYSOPRmessage queue. Similarly, when the processing for an MSF message isabnormally ended, MSF puts an error message on the QSYSOPR messagequeue. Also, whenever MSF is started or ended, there is a correspondingmessage on the QSYSOPR queue.

This message queue is targeted for system operators and also contains manymessages other than those messages pertaining to MSF.

QMSF JoblogThe QMSF job can be located by using the Work with Job (WRKJOB) command.You can use the command as follows:

WRKJOB JOB(QMSF)

This finds both active and ended QMSF jobs. The QMSF jobs differ by their jobnumber. Once you find the appropriate QMSF job, the joblog can be inspectedby using option 10 (Display job log, if active) or option 4 (Work with spooledfiles).

208 Copyright IBM Corp. 1995

Page 233: AnyMail/400 Mail Server Framework Developer Guide January 1995

The QMSF joblog is an appropriate place for exit point programs to put errorinformation.

User JoblogThe user′s joblog may also contain useful information. For example, if a personissues the STRMSF command or ENDMSF command, error messages may bereceived directly by the person′s job. Also, if a program encounters a problemwhile attempting to create an MSF message by using the Create Mail Message(QzmfCrtMailMsg) API, that program′s job receives an error message.

The user′s joblog is another appropriate place for application programs to puterror information.

MSF JournalMSF logs information in the QZMF journal. The QZMF journal contains botherror entries and informational entries. Exit point programs are not able to loginformation in the QZMF journal.

For more information about the QZMF journal, see “MSF Journal” on page 213.

Other PlacesIf MSF does not seem to be processing any MSF messages, determine if thereare any QMSF jobs active in the QSYSWRK subsystem. You can do this by usingthe Work with Active Jobs (WRKACTJOB) command as follows:

WRKACTJOB SBS(QSYSWRK)

If there are no QMSF jobs in QSYSWRK, use the Start Mail Server Framework(STRMSF) command to start MSF again (see “Starting MSF” on page 29). If theQMSF jobs ended abnormally, there are error messages within the QMSF job′sjoblog that describe why the job ended.

In summary, the following places can be used to look for error information:

• The QSYSOPR message queue.

• The QMSF job log.

• The user′s job log.

• The MSF journal.

Error Messages

Communicating Errors to MSFWhile MSF messages are processed by the mail server framework, exit pointprograms may encounter errors performing their respective functions. Whenerrors occur, they should be communicated to MSF so that the appropriateaction can be taken.

An exit point program configured for each exit point can communicate errors toMSF in two ways. They can set return codes or signal exceptions.

Chapter 18. Error Handling in the Mail Server Framework 209

Page 234: AnyMail/400 Mail Server Framework Developer Guide January 1995

Setting Return CodesWhen MSF calls an exit point program, there is a return code parameter that isto be returned to MSF that can be set by the exit point program. The exit pointprogram can then return to the mail server framework with this return code setto indicate if any errors occurred during its processing. The following returncodes are defined,

• (0) No error occurred. Continue processing the MSF message.

The exit point program communicates that all went well with the processingthat it was doing and the MSF message can continue to be processed by theremainder of the framework. Any changes that are made by the exit pointprogram are committed at this point.

• (1) Back out any changes but continue processing the MSF message.

When an exit point program has made changes but, for some reason wantsto roll back those changes, it can set this return code and return to theframework. All changes that were made during that call to the exit pointprogram are not made (they are rolled back and not applied). However,processing of the MSF message continues.

• (2) End this job immediately.

If an error condition is detected by an exit point program and the error issevere enough that it is unlikely that the program can perform its function forany MSF message that might be processed, then it can set this return codewhich ends this job. The MSF message still exists and processing will berestarted for this MSF message the next time the STRMSF command is used.Any changes that were made to the MSF message by the exit point programthat reports the error are rolled back and not applied. An example of acondition that might cause this could be the storage allocated for theapplication has been exhausted. Most likely, an operator would either haveto perform some action to assign additional storage or free up storage so theapplication can then perform its function.

• (3) End processing this MSF message but continue to process additional MSFmessages in this framework job.

If an error condition is detected by an exit point program and the errorconcerns only the MSF message being processed, this return code can beset. This return code indicates to the framework that the processing of thisMSF message should be ended. The MSF message still exists andprocessing will be restarted for this MSF message the next time that theSTRMSF command is used. Any changes that were made to the MSFmessage by the exit point program that reports the error are rolled back andnot applied. An example of a condition that might cause this could be thatthe storage allocated for a particular user′s electronic mail has beenexhausted. In this case, the condition is specific to that user. However, MSFmessages for other recipients could still be processed.

• Any other return code

If a return code is returned to the framework that is not one of the onespreviously listed, the mail server framework job ends abnormally, issuesCPFAF96 to the QMSF job log and signals CPFAF95 to the QSYSOPRmessage queue. Any changes that were made to the MSF message by theexit point program that reports the error are rolled back and not applied.

210 AnyMail/400 MSF

Page 235: AnyMail/400 Mail Server Framework Developer Guide January 1995

Signalling ExceptionsWhen MSF calls an exit point program, certain exceptions can be signalled bythe exit point program to indicate if any errors occurred during its processing.The following messages that the framework monitors are defined:

• CPFAF90 End mail server framework (MSF) job.

This condition is the same as setting a return code of 2. See above forfurther explanation.

• CPFAF91 End processing MSF message.

This condition is the same as setting a return code of 3. See above forfurther explanation.

• CPF9999 Function check.

When the exit point program ends abnormally by function checking, afunction check is returned to the framework. In this case, the mail serverframework job ends abnormally.

• Any other message

If any other message is signalled directly to the framework, the mail serverframework job ends abnormally.

Regardless of how an error is communicated to the framework while processingan MSF message, if an MSF message is postponed or the mail server frameworkjob ends, an alertable message is put on the QSYSOPR message queue and inthe job log of the QMSF job.

Errors Signalled by the Mail Server FrameworkSeveral messages can be signalled by the mail server framework:

• CPFAF95 - MSF &4/&3/&2 job ended. Reason &1.

Anytime that one of the mail server framework jobs ends for any reason, thismessage is put on the QSYSOPR message queue. The following reasoncodes are used:

− 00 - The MSF job ended normally. A job log may not exist.

This reason code is used when the ENDMSF command was used to endthe mail server framework. This is considered normal. However, anerror message is still put on the QSYSOPR message queue to indicatethat the mail server framework was ended.

− 01 - An internal object was not found that is needed by the MSF job.

There are internal queues and indexes that are used by the mail serverframework to track MSF messages that either are being processed orare waiting to be processed. If one of these objects becomes damagedor destroyed, this reason code is set and the framework jobs endabnormally. In this case, use the STRMSF command to restart theframework jobs to ensure that internal objects are re-created.

− 02 - An internal object could not be allocated by the MSF job.

If one of the internal objects that is used to track MSF messages is inuse by another process, the reason code is set and the framework jobsend abnormally. In this case, use the ENDMSF command to ensure alljobs are ended. Then use the STRMSF command to restart theframework jobs.

Chapter 18. Error Handling in the Mail Server Framework 211

Page 236: AnyMail/400 Mail Server Framework Developer Guide January 1995

− 03 - An internal system error was detected by the MSF job.

If the mail server framework job detects unknown conditions, this errormessage is signalled. Conditions that cause this could be systemobjects that are damaged or function checks that occur within theframework job. Additional messages should be logged in the QMSF joblog that should indicate what caused the abnormal condition and the mailserver framework to fail.

− 04 - Exit point program &5 in library &6 for exit point &7 failed in the MSFjob.

If an exit point program signals either a function check or another errormessage other than those previously defined, this reason code is used.There should be additional error messages in the QMSF job log thatindicate the errors that caused the exit point program to fail.

− 05 - Exit point program &5 in library &6 for exit point &7 indicated theMSF job is to be ended.

In the case that an exit point program either signals CPFAF90 or sets areturn code of 2, this error message indicates that the QMSF job shouldbe ended. Reason code 05 is used to indicate this condition.

• CPFAF96 Exit point program returned with return code not defined.

If an exit point program sets a return code other than those defined above,this error message is signalled and the mail server framework job is endedabnormally. Modify the exit point program to ensure it sets return codes thatare defined by the framework. For a complete list of the valid return codes,see “Setting Return Codes” on page 210.

• CPFAF98 Job &6/&5/&4 stopped processing MSF message.

If an exit point program signals CPFAF91 or sets a return code of 3, this errormessage is put on the QSYSOPR message queue. The QMSF job does notend, but instead starts processing the next MSF message available. Thiserror message is used to alert the operator that an MSF message has beenpostponed because of some error condition. By using the ENDMSF and thenthe STRMSF command, processing can then continue for that MSF messageonce the condition has been corrected.

• CPFAF92 Incorrect arguments for exit point program.

When an exit point program is not coded correctly with respect to theparameters that are passed by the mail server framework, this errormessage is issued. Change the exit point program code to accept theparameters as defined by the framework. For information on how to code anexit point program, see Chapter 6, “Mail Server Framework Exit Points” onpage 80. Once the program has been corrected, the MSF message can thenbe processed.

• CPF9801 Object in library not found.

When an exit point program is configured for one of the MSF exit points, it isnot required that the program exists at that time. However, if the mail serverframework processes an MSF message that includes the calling of aprogram that has been configured but does not exist, this error message issignalled and the QMSF job ends abnormally.

• CPF9804 Object in library damaged.

212 AnyMail/400 MSF

Page 237: AnyMail/400 Mail Server Framework Developer Guide January 1995

When an exit point program is damaged and the mail server framework isattempting to call the program, this error message is signalled and theQMSF job ends abnormally. The exit point program must be re-created orrestored from backup. Then the STRMSF command should be issued torestart the mail server framework to recover. The newly recreated orrestored version of the module is then called the next time that the MSFmessage is processed.

• CPF9805 Object in library destroyed.

If an exit point program has been used by the framework but hassubsequently been deleted, the mail server framework will issue this errormessage and the QMSF job will end abnormally to indicate that one of theexit point programs no longer exists. The program should either bere-created or removed from the exit point configuration. Use theWRKREGINF command to remove the program from the exit point.

Whenever an error occurs that causes the MSF job to end, the MSF messagethat was being processed still exists and processing is resumed the next timethe STRMSF command is used.

In general, error recovery steps should be performed in the following order:

1. Locate the error messages that pertain to MSF in the QSYSOPR messagequeue. Error message CPFAF95 indicates the job has ended and errormessage CPFAF98 indicates that processing for a specific MSF message hasended. These error messages contain the job name, the user, and thenumber of the failing job.

2. Use the WRKJOB command, option 4 (work with spool files) or option 10(display job log), to view the job log.

3. Locate the error messages that indicate the error.

4. Follow the recovery of the specific error messages that identify the problem.This may include using the Analyze Problem (ANZPRB) command to isolatethe problem.

5. Once the problem has been isolated and fixed, issue the ENDMSF commandto ensure that all the MSF jobs are ended. Then issue the STRMSFcommand to restart the MSF jobs.

MSF JournalThis section describes the MSF journal and how it is used by the mail serverframework.

Description of the QZMF JournalThe mail server framework uses OS/400 journal support to track MSFconfiguration changes, starting and ending MSF, and MSF message processingthat is performed on the local system.

A journal (QZMF) is shipped with security officer authority in the QUSRSYSlibrary. This is the journal used by the mail server framework. QZMF uses ajournal code of S. Code S denotes a distributed mail service, which in this caseis the mail server framework.

Four types of MSF journal entries can be found in the QZMF journal:

Chapter 18. Error Handling in the Mail Server Framework 213

Page 238: AnyMail/400 Mail Server Framework Developer Guide January 1995

LG An informational log entry about an MSF message. A normal function,such as creating or completing an MSF message, was successfullyperformed.

ER An error entry for a specific MSF message in the mail server framework.The MSF message could not be completed because of a framework orexit point program error.

SY An MSF system entry. An MSF system event, such as STRMSFcommand issued, occurred.

CF An MSF configuration entry. A change was made to the mail serverframework configuration.

The journal provides an output file for each type of entry that shows the data foreach entry. This file enables you to copy the information to an output file byusing the Display Journal (DSPJRN) command. Specify *TYPE1 for the outfileformat (OUTFILFMT) parameter.

When the QZMF journal receiver gets full, you can use the Change Journal(CHGJRN) command to change to a new journal receiver.

Displaying the QZMF JournalYou can view the MSF journal entries by using the Display Journal (DSPJRN)command. Type DSPJRN on the command line and press F4. You are promptedfor the information that you want to see. Either you can enter specificparameters and options or take the default values for each of the promptedparameters.

The following displays show the result of using the following DSPJRN command(followed by F4=Prompt):

DSPJRN JRN(QZMF) FROMTIME(′05/16/94′ ′08:00:00′) TOTIME(′05/17/94′)JRNCDE((S))

214 AnyMail/400 MSF

Page 239: AnyMail/400 Mail Server Framework Developer Guide January 1995

� �Display Journal (DSPJRN)

Type choices, press Enter.

Journal . . . . . . . . . . . . QZMF Name, *INTSYSJRNLibrary . . . . . . . . . . . *LIBL Name, *LIBL, *CURLIB

Journaled physical file:File . . . . . . . . . . . . . *ALLFILE Name, *ALLFILE, *ALLLibrary . . . . . . . . . . Name, *LIBL, *CURLIB

Member . . . . . . . . . . . . Name, *FIRST, *ALL+ for more values

Range of journal receivers:Starting journal receiver . . *CURRENT Name, *CURRENT, *CURCHAINLibrary . . . . . . . . . . Name, *LIBL, *CURLIB

Ending journal receiver . . . Name, *CURRENTLibrary . . . . . . . . . . Name, *LIBL, *CURLIB

Starting sequence number . . . . *FIRST Number, *FIRST Starting date and time:

Starting date . . . . . . . . 05/16/94 DateStarting time . . . . . . . . 08:00:00 Time

More...F3=Exit F4=Prompt F5=Refresh F12=Cancel F13=How to use this display F24=More keys

� �Figure 74. Display Journal (First Display)

� �Display Journal (DSPJRN)

Type choices, press Enter.

Ending sequence number . . . . . *LAST Number, *LAST Ending date and time:

Ending date . . . . . . . . . 05/17/94 DateEnding time . . . . . . . . . Time

Number of journal entries . . . *ALL Number, *ALL Journal codes:

Journal code value . . . . . . S *ALL, *CTL, A, C, F, J, L...Journal code selection . . . . *ALLSLT, *IGNFILSLT

+ for more values Journal entry types . . . . . . *ALL Character value, *ALL, *RCD

+ for more values Job name . . . . . . . . . . . . *ALL Name, *ALL

User . . . . . . . . . . . . . NameNumber . . . . . . . . . . . . 000000-999999

Program . . . . . . . . . . . . *ALL Name, *ALL User profile . . . . . . . . . . *ALL Name, *ALL

More...F3=Exit F4=Prompt F5=Refresh F12=Cancel F13=How to use this display F24=More keys

� �Figure 75. Display Journal (Second Display)

Chapter 18. Error Handling in the Mail Server Framework 215

Page 240: AnyMail/400 Mail Server Framework Developer Guide January 1995

� �Display Journal (DSPJRN)

Type choices, press Enter.

Commit cycle identifier . . . . *ALL Number, *ALL Dependent entries . . . . . . . *ALL *ALL, *NONE Output format . . . . . . . . . *CHAR *CHAR, *HEX Output . . . . . . . . . . . . . * *, *PRINT, *OUTFILE

BottomF3=Exit F4=Prompt F5=Refresh F12=Cancel F13=How to use this display F24=More keys

� �Figure 76. Display Journal (Third Display)

The following fields specify the parameters and the options available for MSFentries.

• Range of journal receivers : Specifies the starting (first) and ending (last)journal receivers that contain the journal entries being converted for output.

• Starting sequence number : Specifies the first journal entry to be consideredfor conversion for output. You can specify *FIRST to display the entirejournal receiver range or you can specify a specific sequence number to beconverted.

• Starting date and time : Specifies the date and time of the first journal entry.

− Starting date: The format for the date is defined by the job attributesDATFMT and, if separators are used, DATSEP (for example, 05/14/94).

− Starting time: The time is specified in 24-hour format and can bespecified with or without a time separator (for example, 08:00:00).

These fields are very useful because they segment the QMSF journal entriesinto specific ranges of interest. For example, if you want to display allentries that occurred on 05/24/95, starting at 11:00 a.m., specify the startingdate of 05/24/95 and the starting time of 11:00:00, and then press the Enterkey.

• Ending sequence number : Specifies the last journal entry to be consideredfor conversion. Either you can specify *LAST to display the final journalreceiver that is converted, or you can specify a specific sequence number tobe converted.

• Ending date and time : Specifies the date and time of the last journal entry.

− Ending date: The format for the date is defined by the job attributesDATFMT and, if separators are used, DATSEP (for example, 05/30/95).

216 AnyMail/400 MSF

Page 241: AnyMail/400 Mail Server Framework Developer Guide January 1995

− Ending time: The time is specified in 24-hour format and can bespecified with or without a time separator (for example, 08:00:00).

• Journal codes : For the mail server framework entries, this code is always S.No other codes are used by MSF.

• Journal entry types : For the mail server framework, the following entries areused:

LG: MSF message log entriesER: MSF message error entriesSY: MSF system entriesCF: MSF configuration entries

You can specify any combination of codes. For example, you can specifythat you want to see only the LG and ER entries. The default displays allentries.

• Job name : Specify QMSF or the user job name (for example, QPADEV0007)to show the jobs that run for the mail server framework.

Displaying the Journal EntriesFrom the Display Journal display, press the Enter key to see the Display JournalEntries display. The information contained on this display depends on theparameters and values that you specified (including default values taken). Theentries are always displayed in chronological order. Figure 77 is an example ofthe display:

� �Display Journal Entries

Journal . . . . . . : QZMF Library . . . . . . : QUSRSYS

Type options, press Enter.5=Display entire entry

Opt Sequence Code Type Object Library Job Time17981 S LG QDIALOCAL 10:31:3817982 S ER QMSF 10:31:3917983 S SY QPADEV0011 10:32:1317984 S SY QPADEV0011 10:32:1617985 S SY QPADEV0011 10:32:1617986 S LG QMSF 10:32:2317987 S LG QDIALOCAL 10:34:0317988 S LG QMSF 10:34:2417989 S LG QPADEV0011 10:37:5117990 S LG QMSF 10:38:0317991 S LG QMSF 10:38:19

F3=Exit F12=Cancel

� �Figure 77. Display Journal Entries Display

This example display is shown with default values specified for all of theparameters. As a result, different codes, different entry types, and different jobsare listed.

If the data in the record does not fit on one display, use the page keys either toadvance to subsequent displays or to return to a previous display in the series.

Chapter 18. Error Handling in the Mail Server Framework 217

Page 242: AnyMail/400 Mail Server Framework Developer Guide January 1995

A plus sign (+) in the lower right corner of the display indicates that there aremore displays in the series.

Note: If there are no entries in the journal receiver that match the values on theentered parameters, the following message appears on the display: (Nolog entries).

This condition can occur when the log entries are sent to the journal receiverduring a time when the system clock is set to an incorrect date or time. Youwould be unable to find entries for a specified range when you use a rangesearch to search the affected journal receiver. Use the Change Journal(CHGJRN) command to create a new journal receiver. If you create a newjournal receiver (once the system clock has been set to the correct time), thecurrent journal receiver entries will have the correct time. This command hasno effect on old journal receivers.

Fields of a QZMF Journal Entry: From the Display Journal Entries display, youcan type a 5 (Display entire entry) in the Opt field to see the detail for eachentry. Figure 78 shows a portion of the detail display of an LG entry.

Figure 78. Detail Display of a Journal Entry — Example

The information available in the detail display is different for each entry type, sothe detail has a unique display based on the entry type. The entry datadisplayed in Figure 78 shows the values that can be mapped to any QZMFjournal entry.

Each of the QZMF journal entry types are described in following sections. Thesections also give examples of the detail displays.

218 AnyMail/400 MSF

Page 243: AnyMail/400 Mail Server Framework Developer Guide January 1995

Journal Entry Type LGA LG entry is made when an MSF message is created, reset, or completed.

Figure 79 is an example of a display that is shown when you type a 5 (Displayentire entry) on the Display Journal Entries display next to an entry that hasfunction type LG (logging). “Format for MSF Message Logging (LG) Entry” onpage 220 provides detailed information about the contents of this display.

� �Display Journal Entry

Object . . . . . . . : Library . . . . . . : Member . . . . . . . : Sequence . . . . . . : 3380 Code . . . . . . . . : S - Distributed mail services Type . . . . . . . . : LG - Mail logging table information

Entry specific dataColumn *...+....1....+....2....+....3....+....4....+....500001 ′ QMSF QMSF 006000QZMFBIGE2ID 100003394051′00051 ′52158420000000009 000010000100000′

Bottom Press Enter to continue.

F3=Exit F6=Display only entry specific data F10=Display only entry details F12=Cancel F24=More keys

� �Figure 79. Display Journal Entry (Type LG)

Chapter 18. Error Handling in the Mail Server Framework 219

Page 244: AnyMail/400 Mail Server Framework Developer Guide January 1995

Format for MSF Message Logging (LG) EntryThe LG entry is mapped by the database file record, QAZMFLG, that representsthe MSF message log information that is entered. This record is defined by thephysical file, QAZMFLG, which is shipped in the QSYS library. The LG-typejournal entry contains the following information:

Table 22. Type LG Journal Entries for MSF Messages

Field Format Description

Entry length Zoned(5,0) Total length of the journal entry, including the entry length field.

Sequence number Zoned(10,0) Applied to each journal entry. Initially set to 1 for each new orrestored journal. Reset when a new receiver is attached.

Journal code Char(1) Always S for MSF entries.

Entry type Char(2) Always LG for MSF message entries.

Date stamp Char(6) The system date that the entry was made.

Time stamp Zoned(6,0) The system time that the entry was made.

(Reserved area) Char(95)

Job name Char(10) The name of the job that caused the entry to occur.

User name Char(10) The user profile name associated with the job.

Job number Zoned(6,0) The job number.

Program name Char(8) The name of the MSF program that made the journal entry.

Function identif ier Char(1) Function that was being performed when the entry was made. Thepossible values are:

1 MSF message created log entry2 MSF message ended normally3 MSF message reset by STRMSF command: STRMSF

MSGOPT(*RESET)4 MSF message removed by STRMSF command: STRMSF

MSGOPT(*CLEAR)5 MSF message acted on by address switcher

MSF message ID Char(32) The MSF message ID logged.

Length of entry data Zoned(5,0) The length of the logged data.

Logged data Char(256) The data logged by MSF when the function identifier is:

2 Data is three Zoned(5,0) numbers. The first number is thenumber of entries in the recipient list when the message wascreated. The second number is the number of entries in therecipient list when processing was completed for themessage. The third number is the number of recipients thathad a non-deliverable status when processing was completedfor the message.

5 Data is two Zoned(5,0) numbers. The first number is thenumber of recipients that had their address switched byprogram QZMFSNPA. The second number is the totalnumber of recipients that were in the recipient list of the MSFmessage processed by QZMFSNPA.

Figure 79 on page 219 is an example LG journal entry you might see when youuse option 5 on the Display Journal Entries display to display the entire entry.

220 AnyMail/400 MSF

Page 245: AnyMail/400 Mail Server Framework Developer Guide January 1995

Journal Entry Type ERAn ER entry is made when an MSF message could not be completed because ofa framework or exit point program error.

Figure 80 is an example of a display that is shown when you type a 5 (Displayentire entry) on the Display Journal Entries display next to an entry that hasfunction type ER (error). “Format for MSF Message Errors (ER)” on page 222provides detailed information about the contents of this display.

� �Display Journal Entry

Object . . . . . . . : Library . . . . . . : Member . . . . . . . : Sequence . . . . . . : 3395 Code . . . . . . . . : S - Distributed mail services Type . . . . . . . . : ER - Mail error information

Entry specific dataColumn *...+....1....+....2....+....3....+....4....+....500001 ′ QMSF QMSF 006000QZMFBIGE2ID 100003394051′00051 ′61305090000000015 CAPITST DEBPGM ′

Bottom Press Enter to continue.

F3=Exit F6=Display only entry specific data F10=Display only entry details F12=Cancel F24=More keys

� �Figure 80. Display Journal Entry (Type ER)

Chapter 18. Error Handling in the Mail Server Framework 221

Page 246: AnyMail/400 Mail Server Framework Developer Guide January 1995

Format for MSF Message Errors (ER)The entry for MSF message errors is mapped by the database file record,QAZMFER, that represents the error information that is entered. This record isdefined by the physical file, QAZMFER, which is shipped in the QSYS library.The ER type journal entry contains the following information:

Table 23. Type ER Journal Entries for MSF Message Errors

Field Format Description

Entry length Zoned(5,0) Total length of the journal entry, including the entry length field.

Sequence number Zoned(10,0) Applied to each journal entry. Initially set to 1 for each new orrestored journal. Reset when a new receiver is attached.

Journal code Char(1) Always S for MSF entries.

Entry type Char(2) Always ER for MSF message error entries.

Date stamp Char(6) The system date that the entry was made.

Time stamp Zoned(6,0) The system time that the entry was made.

(Reserved area) Char(95)

Job name Char(10) The name of the job that caused the entry to occur.

User name Char(10) The user profile name associated with the job.

Job number Zoned(6,0) The job number.

Program name Char(8) The name of the MSF program that made the journal entry.

Error ID Char(1) The MSF error ID. The possible values are:

2 MSF message ended by an exit point program3 QMSF job ended by an exit point program4 An exit point program returned data that was not valid5 An exit point program failed

MSF message ID Char(32) The MSF message ID logged.

Data length Char(5) The length of the logged data.

Logged data Char(256) The data logged by MSF when the error ID is:

2 Exit point program name char(10) and library char(10)3 Exit point program name char(10) and library char(10)4 Exit point program name char(10) and library char(10)5 Exit point program name char(10) and library char(10)

Figure 78 on page 218 shows an example of how the fields that are defined forQZMF journal entries are mapped to the displayed data.

222 AnyMail/400 MSF

Page 247: AnyMail/400 Mail Server Framework Developer Guide January 1995

Journal Entry Type SYA SY entry is made when an MSF system event occurs (for example, STRMSFcommand issued).

Figure 81 is an example of a display that is shown when you type a 5 (Displayentire entry) on the Display Journal Entries display next to an entry that hasfunction type SY (system). “Format for MSF System Level Events Table (SY)” onpage 224 provides detailed information about the contents of this display.

� �Display Journal Entry

Object . . . . . . . : Library . . . . . . : Member . . . . . . . : Sequence . . . . . . : 3715 Code . . . . . . . . : S - Distributed mail services Type . . . . . . . . : SY - Mail system information

Entry specific dataColumn *...+....1....+....2....+....3....+....4....+....5 00001 ′ QZMFECOX QMSF 006163QZMFESTR1 ′

Bottom Press Enter to continue.

F3=Exit F6=Display only entry specific data F10=Display only entry details F12=Cancel F24=More keys

� �Figure 81. Display Journal Entry (Type SY)

Chapter 18. Error Handling in the Mail Server Framework 223

Page 248: AnyMail/400 Mail Server Framework Developer Guide January 1995

Format for MSF System Level Events Table (SY)The entry for system-level change is shown by the database file record,QAZMFSY, that represents MSF system entries. This record is defined by thephysical file, QAZMFSY, which is shipped in the QSYS library. Various mailserver framework functions cause entries to be made in the MSF journal. TheSY-type journal entry contains the following information:

Table 24. Type SY Journal Entries for the MSF System Level Events Table Changes

Field Format Description

Entry length Zoned(5,0) Total length of the journal entry, including the entry length field.

Sequence number Zoned(10,0) Applied to each journal entry. Initially set to 1 for each new orrestored journal. Reset when a new receiver is attached.

Journal code Char(1) Always S for MSF entries.

Entry type Char(2) Always SY for MSF system level events entries.

Date stamp Char(6) The system date that the entry was made.

Time stamp Zoned(6,0) The system time that the entry was made.

(Reserved area) Char(95)

Job name Char(10) The name of the job that caused the entry to occur.

User name Char(10) The user-profile name associated with the job.

Job number Zoned(6,0) The job number.

Program name Char(8) The name of the MSF program that made the journal entry.

Function identif ier Char(1) Function that was being performed when the entry was made. Thepossible values are:

1 STRMSF command issued (QMSF jobs)2 Internal tables initialized (part of STRMSF command function)3 Internal queues initialized (part of STRMSF command

function)4 Space pool index created and initialized5 ENDMSF command issued (ended QMSF jobs)6 Damaged or destroyed internal space found7 Message destroyed by using DATAAREA QZMFKQ value8 Abnormal IPL destroyed internal MSF space index9 MSF cleanup functions (part of Reclaim Storage (RCLSTG)

command) startedA MSF cleanup functions startedB MSF cleanup functions completedC MSF reclaim storage function ended

Data length Zoned(5,0) The length of the logged data.

Logged data Char(256) The data logged by MSF when the function identifier is:

6 32-character MSF message ID7 32-character MSF message ID followed by total number of

internal entries destroyed

Figure 78 on page 218 shows an example of how the fields that are defined forQZMF journal entries are mapped to the displayed data.

224 AnyMail/400 MSF

Page 249: AnyMail/400 Mail Server Framework Developer Guide January 1995

Journal Entry Type CFA CF entry is made when the MSF configuration has been changed.

Figure 82 is an example of a display that is shown when you type a 5 (Displayentire entry) on the Display Journal Entries display next to an entry that has theentry type CF (configuration). “Format for MSF Configuration Changes (CF)” onpage 226 provides detailed information about the contents of this display.

� �Display Journal Entry

Object . . . . . . . : Library . . . . . . : Member . . . . . . . : Sequence . . . . . . : 3690 Code . . . . . . . . : S - Distributed mail services Type . . . . . . . . : CF - Mail configuration information

Entry specific dataColumn *...+....1....+....2....+....3....+....4....+....5 00001 ′ QPADEV0007BANER 006163QZMFDLTC4 0101TT01T′ 00051 ′ TNAME′

Bottom Press Enter to continue.

F3=Exit F6=Display only entry specific data F10=Display only entry details F12=Cancel F24=More keys

� �Figure 82. Display Journal Entry (Type CF)

Chapter 18. Error Handling in the Mail Server Framework 225

Page 250: AnyMail/400 Mail Server Framework Developer Guide January 1995

Format for MSF Configuration Changes (CF)The entry for MSF configuration change is mapped by the database file record,ZMFXCFFT, that represents the change made. This record is defined by physicalfile, QAZMFCF, which is shipped in the QSYS library. The CF-type journal entrycontains the following information:

Table 25. Type CF Journal Entries for MSF Configuration Changes

Field Format Description

Entry length Zoned(5,0) Total length of the journal entry, including the entry length field.

Sequence number Zoned(10,0) Applied to each journal entry. Initially set to 1 for each new orrestored journal. Reset when a new receiver is attached.

Journal code Char(1) Always S for MSF entries.

Entry type Char(2) Always CF for MSF configuration change entries.

Date stamp Char(6) The system date that the entry was made.

Time stamp Zoned(6,0) The system time that the entry was made.

(Reserved area) Char(95)

Job name Char(10) The name of the job that caused the entry to occur.

User name Char(10) The user profile name associated with the job.

Job number Zoned(6,0) The job number.

Program name Char(8) The name of the MSF program that made the journal entry.

Function identif ier Char(1) Function that was being performed when the entry was made. Thepossible values are:

1 MSF data type definition added to configuration by theQZMFCOPN program. MSF type tables initialized withshipped type definitions.

2 Reserved.3 Added type definition to the configuration. New MSF data

type defined by using the QzmfAddMailCfg API.4 Type definition removed from the configuration. MSF data

type removed by using the QzmfRmvMailCfg API.5 Exit point program removed from MSF exit point.6 Exit point program added to MSF exit point, except

QIBM_QZMFMSF_VLD_TYP and QIBM_QZMFMSF_TRK_CHG.7 Exit point program added to QIBM_QZMFMSF_VLD_TYP or

QIBM_QZMFMSF_TRK_CHG.

Data length Zoned(5,0) The length of the logged data.

Logged data Char(256) The data logged by MSF when the function identifier is the following:

1 The record for the MSF data type that was added.3 The record for the MSF data type that was added.4 The record for the MSF data type that was removed.5 The information about the exit point program that was

removed.6 The information about the exit point program that was added.7 The information about the exit point program that was added.

Figure 78 on page 218 shows an example of how the fields that are defined forQZMF journal entries are mapped to the displayed data.

226 AnyMail/400 MSF

Page 251: AnyMail/400 Mail Server Framework Developer Guide January 1995

Common Problems Encountered When Using MSFThe following is a list of common problems that may be encountered.

MSF did not start.

Look at the error message that is returned from the STRMSF command. Reasoncodes within the extended help of the CPFAFAA message help describe theproblem. The most common problem is that errors are encountered in the MSFconfiguration. If the STRMSF command resulted in a successful completionmessage (CPFAFAF), verify that the QMSF jobs are active in the QSYSWRKsubsystem. It is possible that the jobs were submitted successfully, but have notstarted yet (due to problems with the QSYSNOMAX job queue, for example).

The MSF configuration was changed by using the MSF configurationAPIs, but MSF does not seem to recognize the new configuration.

Make sure that MSF is ended and then restarted after changing theconfiguration. The new MSF configuration does not take effect until the STRMSFcommand has completed successfully.

The MSF message is being processed by the wrong exit point program.

Determine the type of the MSF message (check both the address data type andmessage data type). Then, verify if MSF is configured such that the correct exitpoint program will process the MSF message before the incorrect exit pointprogram. You can verify this by checking the program number when using theWork with Registration Information (WRKREGINF) command. If no problems arefound in the configuration, you may need to start MSF again (by using STRMSF)to make sure the configuration is in effect.

Another possibility is that the correct exit point program was replaced with adifferent version without restarting MSF. If this was done, the previous versionmay still be called rather than the correct version. This can be solved byrestarting MSF.

The created MSF message is not being processed (it seemed to disappear).

This is most likely due to a configuration problem. The best place to start is atthe MSF journal. Look for journal entries corresponding to the message ID ofthe created MSF message. From the journal entries, you can determine if theMSF message either ended in error or was marked as non-deliverable. If theMSF message has non-deliverable recipients, the QMSF job makes a log in theQZMF journal that gives the number of non-deliverable recipients. Use theWRKREGINF command to verify that MSF is configured to process MSFmessages of the type corresponding to the created MSF message.

Chapter 18. Error Handling in the Mail Server Framework 227

Page 252: AnyMail/400 Mail Server Framework Developer Guide January 1995

Appendix A. Generic Envelope Type (GET)

To make it easier to share information among different types of mailapplications, the mail server framework defines a generic envelope, referred toas the GET envelope. In general, mail applications provide similar functions thatinclude the specification of attributes about a particular MSF message. Theseattributes might include the following:

• Reference to items such as previous E-mail or a phone conversation.

• The priority (urgent, normal or non-urgent).

• The sensitivity (personal, private or company confidential).

• The date and time the E-mail message was created.

• If a confirmation of delivery is requested.

It is within an envelope that this information is contained. MSF expects thatapplications that are written for the mail server framework will all have theirparticular format for keeping this type of attributes. In general, envelopes arespecific to a mail application. As an E-mail message is transported from oneuser to another within the same mail application, the mail application specificenvelope would be used to communicate all of the information about themessage. In this simple example, there would be no need for a genericenvelope because all of the information can be found in the mail applicationspecific envelope.

However, when multiple mail applications are installed in the mail serverframework, a generic format is useful. If each mail application takes informationfrom its specific envelope and provides it in the generic envelope, then theenvelope can be shared by other mail applications. Also, to further develop thesharing of information between mail applications, it is recommended that eachmail application document their specific envelopes so that if one mail applicationwants to provide a direct mapping of E-mail attributes between its mailapplication and another mail application, the specific envelopes can be used.

Programmers should consider the following with respect to the mail serverframework and envelopes:

• Use the generic envelope to enhance the sharing of information betweenmail applications.

• Consider providing specific envelopes.

• Document its format such that other mail applications can provide directmappings from one mail application to another.

• Attributes within the generic envelope normally should only be specifiedonce; however, they are allowed to be specified multiple times. Each mailapplication needs to determine the meaning of the attribute when it isspecified more than once.

As additional mail applications are added to the mail server framework, thegeneric envelope becomes the basis for sharing information between them.

228 Copyright IBM Corp. 1995

Page 253: AnyMail/400 Mail Server Framework Developer Guide January 1995

Contents of a Generic EnvelopeThe generic envelope should be provided as part of the envelope list. Forinformation on the envelope list, see Chapter 5, “Mail Server FrameworkMessage” on page 44.

Table 26 summarizes the attributes that are defined by IBM along with theattribute ID.

Table 26. IBM Defined Attributes

Attribute Description Attribute ID Attribute Description Attribute ID

Subject 1 Creation date/t ime 2

Expiration date/t ime 3 Reply-by date/t ime 4

Delivery type 5 Priority 6

Electronic Signature 7 Sensit ivity 8

Return contents 9 Non-delivery report 10

Del ivery report 11 Receipt notif ication 12

Forward notif ication 13 Encryption 14

Conversion 15 No loss conversion 16

Disclose recipients 17 Alternate recipientallowed

18

Reassignment ofrecipients

19 Expand distribution list 20

Note content 21 Message size 22

Application unique ID 23 Application referenceunique ID

24

Reference 25 Attachment 26

Importance 27 Object DistributionFacility parameters

98

Generic Envelope HeaderThe following syntax describes the fields that make up the header for the GETenvelope.

Appendix A. Generic Envelope Type (GET) 229

Page 254: AnyMail/400 Mail Server Framework Developer Guide January 1995

Syntax

#include <qzmf.h>

/*********************************************************************//* Type Definition for the GET Envelope *//**** ****//* NOTE: The following type definition only defines the fixed *//* portion of the format. Any varying length field will *//* have to be defined by the user. *//*********************************************************************/

typedef _Packed struct Qzmf_GET{

long int GET_Length;long int First_Attribute_Offset;long int Num_Of_Attributes;

/*char GET_Attribute[];*/ /* varying length */} Qzmf_GET_t;

The header within the generic envelope consists of the following attributes:

GET_LengthThis is the length, in bytes, of the entire list of attributes within the envelope.

First_Attribute_OffsetThis is the offset to the first attribute in the GET from the beginning of theenvelope data.

Num_Of_AttributesThis is the number of attributes present in the GET.

Generic Attribute Definition Syntax

#include <qzmf.h>

/*********************************************************************//* Type Definition for the GET Generic Attribute Structure *//**** ****//* NOTE: The following type definition only defines the fixed *//* portion of the format. Any varying length field will *//* have to be defined by the user. *//*********************************************************************/

typedef _Packed struct Qzmf_GET_Generic_Attrbt{

long int Attribute_Length;long int Attribute_Id;

/*char Attribute[];*/ /* varying length */} Qzmf_GET_Generic_Attrbt_t;

Each attribute in the envelope has the following definition:

230 AnyMail/400 MSF

Page 255: AnyMail/400 Mail Server Framework Developer Guide January 1995

Attribute_LengthThis is the length of the attribute including this field, the ID field and thevariable length attribute value.

Attribute_IdThis is identifier of the attribute to distinguish one attribute from another. Forexample, the subject attribute ID is 1, the ID of the priority field is 6. Eachattribute in the generic envelope is unique and it is this field thatdistinguishes one attribute from the next. Attribute IDs from 1 to 9999 aredefined by MSF. Attribute IDs 10000 and above can be defined by non-IBMmail applications. For further information on this, see “Extensions to theGET” on page 243.

AttributeThis is the data that is unique for each attribute. The attributes haveseparate typedefs that are defined below.

The structure definition of the generic envelope in C can be found in theQSYSINC/H file, member QZMF.

Certain mail applications may use only a subset of attributes within the genericenvelope. It is recommended that applications processing the generic envelopeattributes tolerate attributes that they do not understand or tolerate that aparticular attribute is not present. This allows for future attributes to be definedthat will not cause upward compatibility problems for these applications. This isespecially true for the attribute IDs that are 10000 and above.

General Considerations for GET AttributesTo ensure that the information contained within the generic envelope is easilyshared between mail applications, you should consider the following:

• All attributes are considered optional.

• Some attributes, where appropriate, have defaults associated with them. Forexample, the priority, if not specified, defaults to normal.

• It is required that if there is a generic envelope present in the envelope list,it must contain at least one attribute.

• The syntax of each attribute will be syntax checked where appropriate. Thisincludes verifying the attribute length and values that are defined for certainattributes.

• The length of an attribute must never be used that would cause the envelopelist to exceed 16000000 bytes. In some cases, the length must be exactly 12bytes. For example, the priority attribute has a defined syntax and length.

• In general, attributes occur only once within the generic envelope. However,no error is generated if this is done. It is up to the mail application todetermine the meaning of multiple copies of the same attribute.

Text AttributesThis section describes attributes that contain text type of information. Textattributes have two additional subfields beyond the attribute header. They are:

CCSIDThe character set of the text contained within this attribute. The valid valuesare 1 to 65533. The value of 65535 is also valid and can be used to indicatethat the text is not tagged as being a particular character set.

Appendix A. Generic Envelope Type (GET) 231

Page 256: AnyMail/400 Mail Server Framework Developer Guide January 1995

LengthThis field is the length of the following text not including this length field.

Note that the attribute ID is shown in parentheses.

Syntax

#include <qzmf.h>

typedef _Packed struct Qzmf_GET_Subject_Attrbt{

long int Attribute_Length;long int Attribute_Id;Qzmf_CCSID_t CCSID;long int Subject_Length;

/*char Subject[];*/ /* varying length */} Qzmf_GET_Subject_Attrbt_t;

Subject (1)The subject of the E-mail message.

Syntax

#include <qzmf.h>

typedef _Packed struct Qzmf_GET_Ref_Attrbt{

long int Attribute_Length;long int Attribute_Id;Qzmf_CCSID_t CCSID;long int Ref_Data_Length;

/*char Ref_Data[];*/ /* varying length */} Qzmf_GET_Ref_Attrbt_t;

Reference (25)This attribute contains text from one user to another referencing othermessages, etc. For example, the text could be ″Per our phone conversationyesterday.″

Syntax

#include <qzmf.h>

typedef _Packed struct Qzmf_GET_Note_Attrbt{

long int Attribute_Length;long int Attribute_Id;Qzmf_CCSID_t CCSID;long int Note_Content_Length;

/*char Note_Content[];*/ /* varying length */} Qzmf_GET_Note_Attrbt_t;

232 AnyMail/400 MSF

Page 257: AnyMail/400 Mail Server Framework Developer Guide January 1995

Note content (21)This attribute is used for short messages from one person to another. Thisattribute is not intended to be used as the main content of a message.

For example, when the send network message (SNDNETMSG) CL commandis used, or for additional information similar to the attached memo slipsupported by the OfficeVision/400 product.

Date and Time AttributesThis section describes attributes that contain date and time type of information.Dates and times are always provided in GMT format. For a description of thisformat, see “GET Date/Time GMT Structure” on page 239.

Note that the attribute ID is shown in parentheses.

Syntax

#include <qzmf.h>

typedef _Packed struct Qzmf_GET_Timestamp_Attrbt{

long int Attribute_Length;long int Attribute_Id;union{

Qzmf_GET_Timestamp_t GET_Creation_Timestamp;Qzmf_GET_Timestamp_t GET_Expiration_Timestamp;Qzmf_GET_Timestamp_t GET_Reply_By_Timestamp;

} Qzmf_GET_Tmstmp_Attrbt_Info;} Qzmf_GET_Timestamp_Attrbt_t;

Creation date/time (2)The date and time, in GMT (Greenwich Mean Time), of when the messagewas created on the originating system.

Expiration date/time (3)The date and time, in GMT, specified by the originator that indicates whenthe message is considered to have expired.

Reply-by date/time (4)The date and time, in GMT, specified by the originator that indicates when areply is expected from the recipients.

Fixed Value AttributesThis section describes attributes that contain specific values. For example, thepriority can be normal, high or low. The attribute is considered fixed in that itcan only have values that are defined by MSF.

The fixed attributes, in general, have defined values that are to be used. In allcases, the attribute length should be exactly 12 bytes.

Note that the attribute ID is shown in parentheses.

Appendix A. Generic Envelope Type (GET) 233

Page 258: AnyMail/400 Mail Server Framework Developer Guide January 1995

Syntax

#include <qzmf.h>

typedef _Packed struct Qzmf_GET_Int_Attrbt{

long int Attribute_Length;long int Attribute_Id;union{

Qzmf_GET_Delv_Type_Values_t GET_Delivery_Info;Qzmf_GET_Priority_Values_t GET_Priority_Info;Qzmf_GET_Sensitivity_Values_t GET_Sensitivity_Info;Qzmf_GET_Rtrn_Cntnts_Values_t GET_Return_Contents_Info;Qzmf_GET_Non_Delv_Values_t GET_Non_Delv_Report_Info;Qzmf_GET_Delv_Rpt_Values_t GET_Delivery_Report_Info;Qzmf_GET_Rcpt_Notif_Values_t GET_Receipt_Notif_Info;Qzmf_GET_Frwrd_Notif_Values_t GET_Forward_Notif_Info;Qzmf_GET_Encryption_Values_t GET_Encryption_Info;Qzmf_GET_Conversion_Values_t GET_Conversion_Info;Qzmf_GET_Loss_Cnvrsn_Values_t GET_No_Loss_Conversion_Info;Qzmf_GET_Dscl_Rcpnts_Values_t GET_Disclose_Rcpnts_Info;Qzmf_GET_Alt_Rcpnts_Values_t GET_Alternate_Rcpnts_Info;Qzmf_GET_Rsgn_Rcpnts_Values_t GET_Reassign_Rcpnts_Info;Qzmf_GET_Expand_DL_Values_t GET_Expand_DLs_Info;Qzmf_GET_Importance_Values_t GET_Importance_Info;long int GET_Msg_Size_In_KBytes_Info;

} Qzmf_GET_Int_Attrbt_Info;} Qzmf_GET_Int_Attrbt_t;

The QZMF.H header that can be found in the QZMF member of file QSYSINC inlibrary QUSRSYS does not contain the definitions associated with the importanceattribute. The following definitions should be added to the file.

• The enum Qzmf_Get_Attrbt_Type should have Qzmf_GET_Importance_ID =27 added to the list.

• The following enums should be added,

typedef enum Qzmf_GET_Importance_Values{

Qzmf_Importance_Normal = 0,Qzmf_Importance_Low = 1,Qzmf_Importance_High = 2,Qzmf_Importance_Long_Force = LONG_MAX

} Qzmf_GET_Importance_Values_t;

Note: The use of the LONG_MAX for the typedefs for the attributes assures thatthe definition is always a long int (4 bytes).

Delivery type (5)An indication of the type of message. The following values are allowed:

0 A new message (default if not specified).

1 A delivery report.

2 A non-delivery report.

3 A receipt notification report.

234 AnyMail/400 MSF

Page 259: AnyMail/400 Mail Server Framework Developer Guide January 1995

4 A forwarding notification report.

Priority (6)An indication of the priority of a message. The following values are allowed:

0 Normal (default if not specified)

1 Non-urgent

2 Urgent

Sensitivity (8)An indication of the sensitivity of the information within the content of themessage. The following values are allowed:

0 None (default if not specified)

1 The contents of the message are to be treated as personal

2 The contents of the message are to be treated as private

3 The contents of the message are to be treated as company confidentialand should be handled according to company policies

Importance (27)An indication of the importance of the content of a message. The followingvalues are allowed:

0 Normal (default if not specified)

1 Low

2 High

Return contents (9)An indication of whether or not the contents of a message are to be returnedto the originator if the message is undeliverable to one or more recipients.The following values are allowed:

0 The contents are not to be returned (default if not specified)

1 Return the contents if the message cannot be delivered

Non-delivery report (10)An indication of whether or not a delivery report should be sent to theoriginator if the message cannot be delivered to one or more of therecipients. The following values are allowed:

0 It is not necessary to send a non-delivery report (default if not specified)

1 Send a non-delivery report if the message cannot be delivered

Delivery report (11)An indication of whether or not to send a delivery report when a message isdelivered to one or more recipients. The following values are allowed:

0 It is not necessary to send a delivery report (default if not specified)

1 Send a delivery report to the originator when the message is considereddelivered. That is, a delivery report is being requested for this E-mailmessage

Appendix A. Generic Envelope Type (GET) 235

Page 260: AnyMail/400 Mail Server Framework Developer Guide January 1995

Receipt notification (12)An indication of whether or not to send a receipt notification when amessage has been received. The following values are allowed:

0 It is not necessary to send a receipt notification (default if not specified)

1 Send a receipt notification to the originator when the message isconsidered received by a user

Forward notification (13)An indication of whether or not to send a forward notification when amessage has been forwarded to another recipient. The following values areallowed:

0 It is not necessary to send a forward notification (default if not specified)

1 Send a forward notification to the originator when the message has beenforwarded to another user by the mail application

Encryption (14)An indication of whether or not the contents of the message are encrypted.The following values are allowed:

0 The contents are not encrypted (default if not specified)

1 The contents are encrypted

Conversion allowed (15)An indication of whether or not conversion is allowed for the contents of themessage. The following values are allowed:

0 Conversion is allowed (default if not specified)

1 Conversion is not allowed

No loss conversion (16)An indication of whether or not conversion is allowed for if no loss ofinformation occurs. The following values are allowed:

0 Conversion is allowed even if loss of data occurs (default if not specified)

1 Conversion is prohibited if a loss of data will occur

Disclose recipients (17)An indication of whether or not a mail service is to disclose the completerecipient list to a user. The following values are allowed:

0 Recipients are allowed to be disclosed to the user (default if notspecified)

1 Recipients are not allowed to be disclosed to the user

Alternate recipient allowed (18)An indication of whether or not the message may be forwarded to analternate recipient specified by the recipient. The following values areallowed:

0 The message may be forwarded to an alternate recipient specified by therecipient (default if not specified)

1 The message may not be forwarded to an alternate recipient

236 AnyMail/400 MSF

Page 261: AnyMail/400 Mail Server Framework Developer Guide January 1995

Reassignment of recipient (19)An indication of whether or not reassignment of a recipient is allowed. Thefollowing values are allowed:

0 The message may be reassigned to another recipient (default if notspecified)

1 The message may not be reassigned to another recipient

Expand distribution list (20)An indication of whether or not the distribution list is to be expanded by thenetwork. The following values are allowed:

0 Any distribution lists may be expanded (default if not specified)

1 Distribution lists are not be to expanded

Message size (22)This attribute is an estimate , in kilobytes, of the size of a particular E-mailmessage. This can be useful in providing filtering mechanisms that arebased on the size of a message. The size should include all attachments.

Miscellaneous AttributesThis section describes other attributes that can be specified in the genericenvelope.

Note that the attribute ID is shown in parentheses.

Syntax

#include <qzmf.h>

typedef _Packed struct Qzmf_GET_Appl_UId_Attrbt{

long int Attribute_Length;long int Attribute_Id;long int Appl_Unique_Id_Length;

/*char Appl_Unique_Id[];*/ /* varying length */} Qzmf_GET_Appl_UId_Attrbt_t;

Application unique ID (23)This attribute contains a unique identifier of a message. This information isprovided by mail applications that have a need to communicate this type ofinformation across the network. It is useful when reporting back to theoriginator on the success or failure of the delivery of a message to therecipients.

Appendix A. Generic Envelope Type (GET) 237

Page 262: AnyMail/400 Mail Server Framework Developer Guide January 1995

Syntax

#include <qzmf.h>

typedef _Packed struct Qzmf_GET_Appl_Rf_UId_Attrbt{

long int Attribute_Length;long int Attribute_Id;long int Appl_Ref_Unique_Id_Length;

/*char Appl_Ref_Unique_Id[];*/ /* varying length */} Qzmf_GET_Appl_Rf_UId_Attrbt_t;

Application reference unique ID (24)This attribute contains a unique identifier of a message. This information isprovided in reference to a previously distributed message. For example, if areceipt notification is being sent back to the originator of a message, thereceipt notification contains the original application unique ID in thisreference unique ID. Similarly, if a user is replying to a previous message,the original unique ID is returned to the originator in this reference unique IDattribute. This allows the mail application to correlate the reply with theoriginal message.

Syntax

#include <qzmf.h>

typedef _Packed struct Qzmf_GET_Attach_Attrbt{

long int Attribute_Length;long int Attribute_Id;long int Attach_Entry_Length;

/*char Attach_Entry[];*/ /* varying length */} Qzmf_GET_Attach_Attrbt_t;

Attachment (26)This attribute contains information about the attachments that are found inthe attachment reference list. The information is not defined by the mailserver framework. The information provided here is assumed to besupplemental information to the attachment reference list. Note that whenthis attribute is not present it is not an indication there are no attachments.Rather, it is an indication that there is no supplemental information about theattachment reference list.

This attribute could be specified multiple times. In this case, each attachmentattribute should correspond one to one with the attachment references in theattachment reference list.

238 AnyMail/400 MSF

Page 263: AnyMail/400 Mail Server Framework Developer Guide January 1995

Syntax

#include <qzmf.h>

typedef _Packed struct Qzmf_GET_Signtr_Attrbt{

long int Attribute_Length;long int Attribute_Id;long int Signature_Length;

/*char Elctrnc_Signtr[];*/ /* varying length */} Qzmf_GET_Signtr_Attrbt_t;

Electronic Signature (7)This attribute contains the electronic signature. The content of this attributeis not defined by the mail server framework.

Object Distribution Facility parameters (98)This attribute contains information about object distributions as they flowthrough the framework. These distributions are created by the AS/400 ObjectDistribution Facility using ODF CL commands such as the send network file(SNDNETF) or send network spool file (SNDNETSPLF).

GET Date/Time GMT StructureWhen dates and times are provided within the generic envelope, they areprovided in a format that indicates the GMT (Greenwich Mean Time) format. Thedates and times that use this format are the following,

• Creation Date/Time

• Expiration Date/Time

• Reply-by Date/Time

The format of dates and times are shown in the following C structures.

Appendix A. Generic Envelope Type (GET) 239

Page 264: AnyMail/400 Mail Server Framework Developer Guide January 1995

Syntax

#include <qzmf.h>

/*-------------------------------------------------------------------*//**** Following are the valid values for GMT Delta Indicator in ****//**** IBM GET ****//*-------------------------------------------------------------------*/

#define QZMF_GET_GMT_DELTA_POSITIVE ′ 0 ′#define QZMF_GET_GMT_DELTA_NEGATIVE ′ 1 ′#define QZMF_GET_GMT_DELTA_UNSPECIFIED ′ 2 ′

typedef _Packed struct Qzmf_GET_GMT_Delta{

char Delta_Hour[2];char Delta_Minute[2];

} Qzmf_GET_GMT_Delta_t;

typedef _Packed struct Qzmf_GET_Timestamp{

char Century_Digit;Qzmf_Date_t Date;Qzmf_Time_t Time;char GMT_Delta_Indctr;Qzmf_GET_GMT_Delta_t GMT_Delta;

} Qzmf_GET_Timestamp_t;

Century_DigitThis 1-byte character field indicates the century. The following values areallowed:

0 The date represents the twentieth century.

1 The date represents the twenty-first century.

DateThis field indicates the date. The format of the field is defined by the typedefQzmf_Date_t and is in the YYMMDD format where YY is the year, MM is themonth and DD is the date. For example, for June 26, 1994, the date is 940626in character format.

TimeThis field indicates the time. The format of the field is defined by the typedefQzmf_Time_t and is in the HHMMSS format where HH is the hour, MM is theminutes and SS is the seconds. For example, for 8:12:20 pm, the time is201220 in character format.

GMT_Delta_IndctrThe GMT delta indicator is a one byte field that indicates how the GMT deltathat follows is to be treated. That is, it indicates that the GMT time specifiedin the time field is to be adjusted up or down to arrive at the actual time. It isassumed that the time is given in GMT time with an offset that is specified inhours and minutes. The time is then adjusted by adding or subtracting thedelta given. There are three possibilities that can be specified. They are:

240 AnyMail/400 MSF

Page 265: AnyMail/400 Mail Server Framework Developer Guide January 1995

QZMF_GET_GMT_DELTA_POSITIVEWhen the GMT_Delta_Indctr field is set to this value (0), this is anindication that the GMT_Delta field is to be added to the time specified toarrive at the local time.

QZMF_GET_GMT_DELTA_NEGATIVEWhen the GMT_Delta_Indctr field is set to this value (1), this is anindication that the GMT_Delta field is to be subtracted from the timespecified to arrive at the local time.

QZMF_GET_GMT_DELTA_UNSPECIFIEDWhen the GMT_Delta_Indctr field is set to this value (2), this is anindication that the GMT_Delta field has not been specified and that thetime has been specified in local time with no offset from GMT.

GMT_DeltaThis is the delta that is to be added or subtracted to the time to determinethe local time. The delta is made up of the following fields:

Delta_HourThis is the number of hours that is to be added or subtracted from thetime to determine the local time.

Delta_MinuteThis is the number of minutes that is to be added or subtracted from thetime to determine the local time.

OfficeVision/400 Use of the GETThis section describes how E-mail that originates from OfficeVision/400 uses thegeneric envelope.

OfficeVision/400 uses some, but not all, of the attributes defined for the genericenvelope. The use of each attribute follows:

SubjectUsage of this attribute is limited to the first 60 characters. The maximumlength would be 60. Also, if a mapping occurs from one mail application toOfficeVision/400, only the first 60 characters would appear in the mail item.This attribute is mapped from the IDP (Interchange Document Profile).

ReferenceIn the case of OfficeVision/400 messages, this attribute is mapped from theIDP reference field.

Note contentWhen a note or document has a memoslip attached, the text of the memoslipis placed in the note content.

Creation date/timeThis attribute is mapped from the creation date in the IDP. If there is nocreation date, the time that the E-mail was sent is used.

Expiration date/timeThis attribute is mapped from the expiration date in the IDP. If there is noexpiration date, it is not specified in the GET.

Appendix A. Generic Envelope Type (GET) 241

Page 266: AnyMail/400 Mail Server Framework Developer Guide January 1995

Reply-by da te/timeThis attribute is mapped from the reply-by date in the IDP. If there is noreply-by date, it is not specified in the GET.

Delivery typeThis attribute is based on the type of distribution. OfficeVision/400 generatesstatus messages when reporting confirmation of delivery. In this case, thedelivery type is a delivery report. If a message was considered to beundeliverable by either OfficeVision/400 or SNADS, the status distribution isconsidered to be a non-delivery report.

PriorityThis attribute is mapped directly from the grade of delivery attribute inOfficeVision/400.

SensitivityThis attribute is mapped directly from the sensitivity attribute inOfficeVision/400.

ImportanceThis attribute is mapped directly from the importance attribute inOfficeVision/400.

Non-delivery reportA non-delivery report is requested for all messages except statusdistributions which represent confirmation of delivery reports.

ConversionThis attribute is mapped directly from the conversion allowed attribute inOfficeVision/400.

Disclose recipientsThis attribute is mapped directly from the disclose recipients attribute inOfficeVision/400.

Alternate recipient allowedThis attribute is mapped directly from the alternate recipient allowedattribute in OfficeVision/400.

Object Distribution Facility Use of the GETThis section describes how distributions that originates from the ObjectDistribution Facility (ODF) uses the generic envelope.

ODF uses some, but not all, of the attributes defined for the generic envelope.The use of each attribute follows:

SubjectThis attribute contains the file, library and member name of the file that isbeing distributed when the message represents a file distribution. This isthe case when the file was distributed using the SNDNETF CL command.

Creation date/timeThis attribute is set from the time the distribution was sent.

Object Distribution Facility parametersThis attribute contains information about object distributions as they flowthrough the framework. These distributions are created by the AS/400

242 AnyMail/400 MSF

Page 267: AnyMail/400 Mail Server Framework Developer Guide January 1995

Object Distribution Facility using ODF commands such as SNDNETF orSNDNETSPLF.

Extensions to the GETAlthough many attributes have been defined for the generic envelope, a mailapplication may have the need to specify additional attributes. These attributescan be added to the generic envelope. This can be done by using an attributewhich has a value of 10000 or greater. Attributes in the range from 1 to 9999 aredefined by MSF. Although not all of the attributes in this range are currentlydefined, those that are not defined may be used by MSF in the future. Sinceapplication defined attributes are in the range of 10000 and above, duplicatedefinitions will not be a problem.

For example, if a mail application has the need for attribute XYZ and theattribute is not defined by MSF, then it could assign its own attribute ID, such as10003. It is highly recommended that a mail application document theseattributes so that other applications may use them.

Appendix A. Generic Envelope Type (GET) 243

Page 268: AnyMail/400 Mail Server Framework Developer Guide January 1995

Appendix B. SNADS File Server APIs

This appendix describes the SNADS file server APIs and how to use them. Youwould use these APIs if you were dealing with MSF messages that containedSNADS attachments. You would use the file server object read API if the MSFmessage was originated by OfficeVision/400* or Object Distribution Facility(ODF). You would use the create and write APIs if the MSF message wasdestined for an OfficeVision/400 or ODF user.

File Server Operations — OverviewWith the SNADS file server interface, you can create and manipulate eitherSNADS general file server objects or Document Interchange Architecture (DIA)file server objects. A file server object (FSO) in this context is used by SNADSand by applications like Object Distribution Facility and OfficeVision/400 to storedata associated with a message (for example, an OfficeVision note). Thisinterface includes the following APIs:

• QZDCRFSO - Create a File Server Object• QZDWTFSO - Write to a File Server Object• QZDRDFSO - Read a File Server Object• QZDASNID - Assign a File Server Object Access ID• QZDRVKID - Revoke a File Server Object Access ID• QZDLSTID - List File Server Object Access IDs• QZDRTVID - Retrieve a File Server Object Access ID

Although SNADS general file server objects and DIA file server objects aremanipulated via the same interface, they differ in content.

All the APIs listed above will be shipped with PUBLIC authority of *EXCLUDE.See Chapter 17, “Security and Authority” on page 205 for more details.

File Server ObjectsA SNADS file server object has two representations, external and internal. Theexternal representation is important to you as a creator or user of file serverobjects and is the one that is described in this appendix.

There is an internal implementation to support the external image. This is anencapsulated form of the file server object that is described is this appendix.File server object contents are kept in internal OS/400 system space objects thatare protected from access except through the FSO APIs. These system objectsare not documented externally. They are mentioned here only to make sure thatthe external versus internal nature of file server objects is understood. Thereare also OS/400 system considerations, actions, or functions that might beperformed that could affect file server objects.

Following are some system considerations related to how the internal file serverobjects are used by the file server object APIs.

• All file server objects created using the FSO APIs are stored in theQUSRSYS library. If that library is ever cleared, all file server objects aredeleted.

244 Copyright IBM Corp. 1995

Page 269: AnyMail/400 Mail Server Framework Developer Guide January 1995

• All file server objects are permanent system objects. They are not deleteddue to a system IPL (normal or abnormal) or due to an installation of OS/400.

• All file server objects are owned by the QSNADS user profile. To determinethe amount of space used by the system for file server objects, you candisplay the amount of storage owned by the QSNADS user profile.

• To manage the existence of a file server object, you would use the assignand revoke access ID APIs. However, if these APIs are not used, there is noprotection on the file server object (see “Assign and Revoke APIs Example”on page 246). If someone issues the RCLSTG command and there is noprotection on a file server object, that file server object will be deleted.

• File server objects cannot be saved. When you perform a save of thesystem, file server objects currently existing on that system are not saved.File server objects that were created on one system cannot be restored ontoanother system.

File Servers Supported by FSO APIsThe following sections talk about the two file servers that are supported by theFSO APIs. These file servers are programs that are called by the APIs toperform specific operations. Both file servers have the same interface. Toindicate which file server program should be used by the API, you pass in thename of the file server on the API call.

Note: Only one file server can be used for any one file server object. Forexample, to manipulate file server object ″A″, you cannot use the DIA fileserver to create the object and then the SNADS general file server towrite data to the object. Only one of the file servers may be used to doboth operations. Likewise, if file server object ″A″ was created using theDIA file server, the DIA file server must be used to read the object later.

SNADS General File Server: The SNADS general file server is used to createobjects (called SNADS general file server objects (FSOs)) which are simply astream of bytes. When this type of FSO is created, no data conversions takeplace and the only information in the FSO is the data itself. For example, theSNADS general file server is used by Object Distribution Facility to store data forfiles or spooled files.

DIA File Server: The DIA file server is used to create DIA FSOs. These objectsare used by OfficeVision/400 and can consist of more information than just thedata. Examples include the subject, origination date, expiration date, andpriority. This additional information is stored in the IDP (interchange documentprofile) in the document that comes right before the actual document data. Seethe Interchange Document Profile Reference (SC23-0764-03) for more informationon the IDP structure.

The data in a DIA document is the actual contents of an OfficeVision/400 note,message or document. The data in a DIA FSO can take on several differentformats that include final format text (FFT), revised format text (RFT), or PC fileformat. See the Document Interchange Architecture: Technical Reference(C23-0781-01) for more details on DIA.

Appendix B. SNADS File Server APIs 245

Page 270: AnyMail/400 Mail Server Framework Developer Guide January 1995

Attachment ReferencesFile server objects can be associated with an MSF message by keeping areference to the object in the attachment reference list of the MSF message. Byusing a reference to the FSO, only one copy of the FSO needs to exist on thesystem at any given time. The structure of the reference is described as follows:

typedef _Packed struct Qzmf_FSO{

long int Attach_Ref_Length;long int Reserved1;char Access_ID[8];char Product_ID[7];char Reserved2;long int Data_Length;char FSO_Handle[32];long int FS_Name_Length;char FS_Name[64];long int Resume_Position;

} Qzmf_FSO_t;

Assign and Revoke APIs ExampleWithin SNADS there are several jobs that work with an MSF message. When anMSF message has a file server object attached to it, each job must secure itsusage of the FSO by assigning an access ID to that FSO.

1. When the first job has assigned an access ID and completed its work on theMSF message, it passes the message to the next job.

2. The next job assigns an access ID for itself, but also revokes the access ID ofthe previous job.

3. The last job to work with the MSF message never actually assigns an accessID to the FSO, but it does revoke the access ID of the previous job.

When all access IDs to an FSO have been revoked, the file server object isdeleted.

How Usage Counts Are UsedThe SNADS general file server uses a usage count to keep track of the use of afile server object. The usage count indicates how many MSF messages arereferencing the object, and it is stored in the header portion of the file serverobject. For example, as an MSF message (that refers to an attachment) flowsthrough SNADS, the MSF message is processed by several different jobs. Thesejobs may each make copies of the MSF message in order to change some of thedistribution data. The attachment, or file server object, could then be refered toby more than one MSF message at a time. For each reference, the QZDASNIDAPI should be called to increment the usage count by one. As each job finishesits processing of the distribution, it calls the QZDRVKID API. This decrementsthe usage count by one. When the usage count becomes zero, the file serverobject is destroyed.

The assigning and revoking operations for DIA documents follows the samemethodology as the SNADS general file server. The usage count for DIAdocuments is stored in the distribution tracking object (DTO) for the document.

246 AnyMail/400 MSF

Page 271: AnyMail/400 Mail Server Framework Developer Guide January 1995

After the usage count has been decremented by invoking the QZDRVKID API, thedocument and DTO are deleted if they are eligible for deletion.

Create SNADS File Server Object (QZDCRFSO) API Parameters

Required Parameter Group:

The Create SNADS File Server Object (QZDCRFSO) API allows a user to create afile server object on the AS/400. A file server object can also be referred to asan attachment (for example, MSF messages can have attachments). There aretwo types of file server objects that the QZDCRFSO API will build: SNADSgeneral file server objects and DIA file server objects. The interface to both ofthese types of objects is the same.

In order to create an FSO, the Create API needs to know for which file server(SNADS or DIA) the object is being created. The length of the FSO is an inputparameter which tells the QZDCRFSO API about how big the FSO will be. If thisparameter is greater than zero, the QZDCRFSO API will allocate an initial space(up to 16MB) for the FSO. Additional spaces may be created during the fileserver write operation if the data length parameter is greater than 16MB. If thedata length parameter is zero, QZDCRFSO will allocate an initial space of only32KB. This API then returns the FSO handle to the caller. The caller must usethis handle on every other SNADS file server API in order to operate on the FSOjust created.

1 File server object handle Output Char(32)2 File server object data length Input Bin(4)3 File server name structure Input Char(68)4 Error code I/O Char(*)

SNADS General File ServerFile server objects created by the SNADS general file server are stored in libraryQUSRSYS and owned by the QSNADS user profile. The QZDCRFSO API alsochecks the system storage threshhold (ASP) to make sure there is enough roomon the system for the entire file server object. If the size of the data to write isnot passed into this function, the QZDCRFSO API will check if there is enoughroom for 32K bytes of data. If the system storage threshhold has already beenexceeded, or if the creation of the new file server object would cause it to beexceeded, the QZDCRFSO returns the CPF3A0D (temporary server error) errorcode.

DIA File ServerWhen a file server object is created by the DIA file server, the DIA file serverprogram creates a distribution tracking object (DTO) and a name is generatedusing a date/time stamp. The DIA file server program will also create adocument to store the document content and IDP.

Appendix B. SNADS File Server APIs 247

Page 272: AnyMail/400 Mail Server Framework Developer Guide January 1995

Required Parameter GroupFile server object handle

OUTPUT; CHAR(32)The file server object handle contains the necessary linkage to the file serverobject. This parameter is set as output on the QZDCRFSO API, and is usedas input on all other file server object operations.

File server object data lengthINPUT; BIN(4)The server object data length is the calculated length of the data to bewritten. The QZDCRFSO API creates an FSO space (up to 16MB) which isbig enough to hold the length of data specified. Valid values for thisparameter are:

1 byte to 4.2 gigabytes SNADS general file server object data length

1 byte to 2.1 gigabytes DIA file server object data length

File server name structureINPUT; CHAR(68)This structure contains the architected file server name (either DIA orSNADS) and the server name length.

Valid values for length of the file server name are:

4 SNADS general file server name

4 DIA file server name

Valid values for file server name:

′21F0F0F6′X (hex) SNADS general file server name

′20F0F0F1′X (hex) DIA file server name

Error codeI/O; CHAR(*)See System API Reference for details on the error code structure.

Table 27. File Server Name Structure

Offset

Type FieldDec Hex

0 0 BIN(4) Length of fi le server name

4 4 CHAR(64) File server name

Error MessagesCPF3A0D E Temporary server error. The system storage threshhold has been

exceeded. System storage must be reduced before this API can beused.

CPF3A17 E Permanent server error. The file server object being created wasdamaged. Call this API again.

CPF3A09 E System error. An unrecoverable system error has occurred. Callthis API again.

CPF3A1D E Limit of number of open file server objects exceeded. There is alimit of 10 file server objects that can be created at one time by a job.

248 AnyMail/400 MSF

Page 273: AnyMail/400 Mail Server Framework Developer Guide January 1995

CPF3CF1 E Error code parameter not valid. Correct the error and call this APIagain.

CPF24B4 E Severe error while addressing parameter list. Correct the error andcall this API again.

CPF9872 E Program ended. An error occurred with one of the parameters.Correct the error and call this API again.

The following syntax diagram is the C language equivalent of the QZDCRFSOprototype. This header can be found in the QSYSINC library. See Exampleusing QZDCRFSO on page 268.

Syntax

#include <qzdcrfso.h>void QZDCRFSO(

void *fso_handle, /* FSO Handle */long int *data_len, /* FSO Data Length */void *fs_name, /* File server name */void *error_str /* API Returned Error */

);

Write to SNADS File Server Object (QZDWTFSO) API Parameters

Required Parameter Group:

You can write to a file server object using the Write to SNADS File Server Object(QZDWTFSO) API. The QZDWTFSO API has four operations that can be used towrite to an FSO. The first two operations, write and terminate write , are requiredin order to completely write to an FSO. The write operation copies the datafrom the callers buffer into the file server object. This operation may be calledmultiple times in order to write all the data. The terminate write operation mustbe done after all the writes have been completed. This operation closes the fileserver object and makes the FSO available for other processes to read it.

The two optional operations are suspend write and resume write , both of whichare supported only by the SNADS general file server. These operations can beused to suspend the writing of a SNADS general FSO and then return to writing(resume) at a later time. These operations could be used in conjunction with theinitiate read location operation described below.

1 File server object handle Input Char(32)2 Operation requested (write,term,suspend,resume) Input Bin(4)3 File server object data length Output Bin(4)4 File server name structure Input Char(68)5 Resume position Input Bin(4)6 Pointer to buffer area Input Ptr(SPP)7 Bytes provided in buffer area Input Bin(4)8 Error code I/O Char(*)

Appendix B. SNADS File Server APIs 249

Page 274: AnyMail/400 Mail Server Framework Developer Guide January 1995

An example of the usage of these operations follows. When data is being sentfrom one system to another, the sender on the source side is reading the fileserver object and the receiver is writing the data received into a new FSO on thetarget side. If the communications connection goes down during the middle ofthis data transmission, the receiver will issue the suspend write operation.When the communications connection comes back up, the sender starts readingagain using the initiate read location operation (part of the file server read(QZDRDFSO) API), and the receiver starts writing again using the resume writeoperation.

There are two types of file server objects that the QZDWTFSO API will operateon - SNADS general file server objects and DIA file server objects. The interfaceto both of these types of objects is essentially the same. There are four SNADSgeneral file server write operations and two DIA file server write operationsprovided by this API.

SNADS General File ServerThe SNADS general file server provides a means for SNADS support to save thedata object portion of a distribution request. The general file server storesobjects in a byte stream format. No transformations are done to the data when itis written into or read out of a general file server object. General file serverobjects are owned by QSNADS and are stored in the QUSRSYS library.

The SNADS general file server can support objects up to 4 gigabytes. Each fileserver object space can only be 16MB large, but the SNADS general file serverhas the capability of chaining file server objects together. If the amount of datais greater than 16MB, the SNADS general file server creates as many file serverobject spaces as necessary and then chains them together. This function istransparent to the caller of the SNADS general file server APIs. After a chain ofFSOs is created, this chain is still referenced by one file server object handle.

The following paragraphs describe each of the SNADS general file server writeoperations.

Write: The write operation copies the contents of the caller′s buffer to the fileserver object. If the data being written is greater than 16MB, the write operationwill automatically create new file server object spaces and chain them together.The caller may call the write operation multiple times in order to write all thedata.

Terminate Write: Once this operation has been called, no other write operationscan be done on the specific file server object. Also, the file server object cannotbe read or have an access ID assigned to it until the terminate write operationhas completed.

Suspend Write: The suspend write operation allows the caller to temporarilysuspend the writing of an object. This operation will not assign an access ID tothe file server object, nor will it increment the objects usage count.

Resume Write: The resume write operation does the setup needed in order toresume writing into a file server object. It is similar to the create file serverobject API since it needs to be called only once before write operations can bedone. The caller of this operation must pass in the starting position of where tocontinue writing in the file server object. This number would be based on howmany bytes were written when the suspend write operation was called.

250 AnyMail/400 MSF

Page 275: AnyMail/400 Mail Server Framework Developer Guide January 1995

Note: The resume write operation also checks the system storage threshhold tomake sure there is enough room for the rest of the data to be written.

DIA File ServerThe DIA file server provides a means for SNADS to save the data object portionof an OfficeVision/400 distribution request. The DIA file server objects are oftype *DTO (distribution tracking object), are owned by the QDOC user profile andare stored in the QUSRSYS library.

The DIA file server can support objects up to 2 gigabytes. Each file server objectspace can only be 16MB large, but the DIA file server has the capability ofchaining file server objects together. If the amount of data is greater than 16MB,the DIA file server creates as many file server object spaces as necessary andthen chains them together. This function is transparent to the caller of the DIAfile server routines.

The following sections describe each of the DIA file server write operations.

Write: The write operation copies the contents of the caller′s buffer to the DIAdocument object. If the data being written is greater than 16MB, the writeoperation will automatically create new spaces and chain them together. Thecaller may call the write operation multiple times in order to write all the data.

Terminate Write: When the caller has completed writing the entire document,the terminate write operation must be called to save the distribution trackingobject. The DIA document will also be closed. The DTO and the document willnot be available to other processes until this operation has been called. Oncethis operation has been called, no other write operations can be done on thespecific file server object. Also, the file server object cannot be read or have anaccess ID assigned to it until the terminate write operation has completed.

Required Parameter GroupFile server object handle

INPUT; CHAR(32)Contains the necessary linkage to the file server object. The value of thisparameter should be taken from the FSO handle that was returned on thecall to the QZDCRFSO Create API.

Operation requestedINPUT; BIN(4)Used by the QZDWTFSO API to determine which operation, write, terminatewrite, suspend write, or resume write, the caller is requesting. Valid valuesfor this parameter are:

Write 5Terminate Write 6Suspend Write 7Resume Write 8

File server object data lengthOUTPUT; BIN(4)The total length of the file server object that has been written. Thisparameter is returned on the terminate write, suspend write, and resumewrite operations.

Appendix B. SNADS File Server APIs 251

Page 276: AnyMail/400 Mail Server Framework Developer Guide January 1995

File server name structureINPUT; CHAR(68)The architected file server name (either DIA or SNADS) and the server namelength. See the Table 27 on page 248 for details.

Resume positionINPUT; BIN(4)Used by the Resume Write operation to indicate where to resume writing inthe FSO. This parameter is ignored on the write, terminate write, andsuspend write operations. Valid values for this parameter are:

1 to <= the current file server object data length

Pointer to buffer areaINPUT; PTR(SPP)The buffer area, defined by the caller, contains the data that the callerwishes to write into a file server object.

Bytes provided in buffer areaINPUT; BIN(4)The number of bytes of data in the buffer area that are to be written to thefile server object. Valid values for this parameter are:

1 to 16 megabytes

Error codeI/O; CHAR(*)See System API Reference for more details on the error code structure.

Error MessagesCPF3A0D E Temporary server error. The system storage threshhold has been

exceeded. System storage must be reduced before this API can beused.

CPF3A17 E Permanent server error. The file server object being created wasdamaged. Call this API again.

CPF3A09 E System error. An unrecoverable system error has occurred. Callthis API again.

CPF3A1A E Location not valid. The byte location specified on the resume writeoperation is either zero or greater than the current size of the FSO.Specify a correct resume location and call this API again.

CPF3A1B E Operation not valid. The file server object create (QZDCRFSO) APImust be called before QZDWTFSO can be called. A suspend writeoperation must be done before a resume write operation can bedone.

CPF3A1C E Request not valid. Specify a valid operation (write, terminate write,suspend write, or resume write) on the operation requestedparameter and call this API again.

CPF3A15 E File server object not found. Specify a valid file server object handlefor an FSO that currently exists, and call this API again.

CPF3CF1 E Error code parameter not valid. Correct the error and call this APIagain.

CPF24B4 E Severe error while addressing parameter list. Correct the error andcall this API again.

252 AnyMail/400 MSF

Page 277: AnyMail/400 Mail Server Framework Developer Guide January 1995

CPF9872 E Program ended. An error occurred with one of the parameters.Correct the error and call this API again.

The following syntax diagram is the C language equivalent of the QZDWTFSOprototype. This header can be found in the QSYSINC library. See Exampleusing QZDWTFSO on page 269.

Syntax

#include <qzdwtfso.h>void QZDWTFSO(

void *fso_handle, /* FSO handle */long int *operation, /* FSO operation

requested */long int *data_len, /* FSO data length */void *fs_name, /* File server name */long int *resume_pos, /* FSO resume write

position */void *buffer, /* FSO buffer area */long int *buffer_prov, /* Bytes provided in

buffer area */void *error_str /* API Returned Error */

);

Read SNADS File Server Object (QZDRDFSO) API Parameters

Required Parameter Group:

The Read SNADS File Server Object (QZDRDFSO) API, like the Write API, alsohas required operations that must be done and optional operations. The threerequired operations are initiate read , read , and terminate read . The initiate readoperation opens up an existing file server object that is based on the informationgiven to it by the caller. Once this operation has been called, the read operationcan be used to read the data contained in the file server object. The readoperation can be called multiple times in order to read all the data. After allread operations have been completed, the terminate read operation must beissued to close the file server object.

The optional operation provided on the QZDRDFSO API is initiate read location .This operation can be used to start reading the file server object at a specificlocation.

1 File server object handle Input Char(32)2 Operation requested (init,read,term,init read

location)Input Bin(4)

3 File server object data length Output Bin(4)4 File server name structure Input Char(68)5 Pointer to buffer area Input Ptr(SPP)6 Bytes provided in buffer area Input Bin(4)7 Bytes available in buffer area Output Bin(4)8 Error code I/O Char(*)

Appendix B. SNADS File Server APIs 253

Page 278: AnyMail/400 Mail Server Framework Developer Guide January 1995

The QZDRDFSO API operates on SNADS general file server objects and DIA fileserver objects. The interface to both of these types of objects is essentially thesame.

SNADS General File ServerThe SNADS general file server provides a means for SNADS support to save thedata object portion of a distribution request. The general file server storesobjects in a byte stream format. No transformations are done to the data when itis written into or read out of a general file server object. The SNADS general fileserver objects are owned by QSNADS and are stored in the QUSRSYS library.

The SNADS general file server can support objects up to 4 gigabytes. Each fileserver object space can be only 16MB large, but the SNADS general file serverhas the capability of chaining file server objects together. If the amount of datais greater than 16MB, the SNADS general file server creates as many file serverobject spaces as necessary and then chains them together. This function istransparent to the caller of the SNADS general file server routines.

The SNADS general file server read operations are as follows:

Initiate Read: The initiate read operation does the set up necessary to read thegeneral file server object. This includes finding the object specified by the objectname in the input parameters. This operation must be the first called before anyof the other read operations can be used for the specific file server object. Theinitiate read operation only needs to be called once in the sequence of readoperations.

Initiate Read Location: The initiate read location operation is similar to theinitiate read operation, but allows a caller to set up a general file server objectto begin reading at a specified location rather than at the beginning of the object.This operation also needs to be called only once in the sequence of readoperations.

Read: The caller of the read operation must specify what object is to be read,where to put the data that is read, and how much data is to be read. If theamount of actual data is less than the size of the caller′s buffer space (that is,where the data will be read in), the read operation reads as much data as it canand then returns.

Because a space can be a maximum of 16MB, the caller′s buffer space shouldbe no more than 16MB, and the caller should not request more data than 16MBto be read. If the object being read is larger than 16MB, the caller will have tocall the read operation more than once to read all the data. If more than oneread is done, the SNADS general file server read operation keeps a marker inthe data (offset inside the object) so that on subsequent read operations, theread operation knows where to start reading.

Terminate Read: The terminate read operation does the cleanup processingafter all data has been read from the file server object. After this operation hasbeen called, the file server object may still exist, but an initiate read operationmust be done in order to read the file server object again.

254 AnyMail/400 MSF

Page 279: AnyMail/400 Mail Server Framework Developer Guide January 1995

DIA File ServerThe DIA file server provides a means for SNADS support to save the data objectportion of an OfficeVision/400 distribution request. The DIA file server objectsare of the type *DTO (distribution tracking object), are owned by the QDOC userprofile and are stored in the QUSRSYS library.

The DIA file server can support objects up to 2 gigabytes. Each file server objectspace can be only 16MB large, but the DIA file server has the capability ofchaining file server objects together. If the amount of data is greater than 16MB,the DIA file server creates as many file server object spaces as necessary andthen chains them together. This function is transparent to the caller of the DIAfile server routines.

The DIA file server read operations are as follows:

Initiate Read: The initiate read operation does the set up necessary to read theDIA distribution tracking object. This includes finding the object specified by theobject name in the input parameters. This operation must be the first operationcalled before any of the other read operations can be used for the specific fileserver object.

Read: The caller of the read operation must specify what document object is tobe read, where to put the data that is read, and how much data is to be read. Ifthe amount of actual data is less than the size of the caller′s buffer space (thatis, where the data will be read in), the read operation reads as much data as itcan and then returns.

Because a space can be a maximum of 16MB, the caller′s buffer space shouldbe no more than 16MB, and the caller should not request more data than 16MBto be read. If the document object being read is larger than 16MB, the caller willhave to call the read operation more than once to read all the data. If more thanone read operation is done, the DIA file server read operation keeps a marker inthe data (offset inside the object) so that on subsequent read operations, theread operation knows where to start reading.

Terminate Read: The terminate read operation should be called when the entiredocument has been read. This operation closes the document object.

Required Parameter GroupFile server object handle

INPUT; CHAR(32)The file server object handle contains the necessary linkage to the file serverobject. This parameter must be entered on all file server read operations.The value of this parameter should be taken from the file server objecthandle that was returned on the call to the Create File Server Object(QZDCRFSO) API.

Operation requestedINPUT; BIN(4)The operation requested is used by the QZDRDFSO API to determine whichoperation, initiate read, read, terminate read, or initiate read location, thecaller is requesting. Valid values for this parameter are:

Initiate Read 1Read 2Terminate Read 3

Appendix B. SNADS File Server APIs 255

Page 280: AnyMail/400 Mail Server Framework Developer Guide January 1995

Initiate Read Location 4

File server object data lengthOUTPUT; BIN(4)The total length of the file server object that is being read. This parameter isreturned on the initiate read operation and the intiate read locationoperation.

File server name structureINPUT; CHAR(68)The architected file server name (either DIA or SNADS) and the server namelength. See Table 27 on page 248 for more details.

Pointer to buffer areaINPUT; PTR(SPP)The buffer area is defined by the caller. It is used by the read operation tostore the data that is being read.

Bytes provided in buffer areaINPUT; BIN(4)The number of bytes of data that can be read into the buffer area. Validvalues for this parameter are:

1 to 16 megabytes

Bytes available in buffer areaOUTPUT; BIN(4)The number of actual bytes of data that was read into the buffer area.

Error codeI/O; CHAR(*)See System API Reference for more details on the error code structure.

Error MessagesCPF3A17 E Permanent server error. The file server object being created was

damaged. Call this API again.

CPF3A09 E System error. An unrecoverable system error has occurred. Callthis API again.

CPF3A1A E Location not valid. The byte location specified on the resume writeoperation is either zero or greater than the current size of the FSO.Specify a correct resume location and call this API again.

CPF3A1B E Operation not valid. The file server object create (QZDCRFSO) APImust be called before QZDWTFSO can be called. A suspend writeoperation must be done before a resume write operation can bedone.

CPF3A1C E Request not valid. Specify a valid operation (write, terminate write,suspend write, or resume write) on the operation requestedparameter and call this API again.

CPF3A1D E Limit of number of open file server objects exceeded. There is alimit of 10 file server objects that can be created at one time by a job.

CPF3A1E E End of file server object data reached.

CPF3A15 E File server object not found. Specify a valid file server object handlefor an FSO that currently exists, and call this API again.

256 AnyMail/400 MSF

Page 281: AnyMail/400 Mail Server Framework Developer Guide January 1995

CPF3CF1 E Error code parameter not valid. Correct the error and call this APIagain.

CPF24B4 E Severe error while addressing parameter list. Correct the error andcall this API again.

CPF9872 E Program ended. An error occurred with one of the parameters.Correct the error and call this API again.

The following syntax diagram is the C language equivalent of the QZDRDFSOprototype. This header can be found in the QSYSINC library. See Exampleusing QZDRDFSO on page 274.

Syntax

#include <qzdrdfso.h>void QZDRDFSO(

void *fso_handle, /* FSO handle */long int *operation, /* FSO operation

requested */long int *data_len, /* FSO data length */void *fs_name, /* File server name */void *buffer, /* FSO buffer area */long int *buffer_prov, /* Bytes provided in

buffer area */long int *buffer_avail, /* Bytes available in

buffer area */void *error_str /* API Returned Error */

);

Assign SNADS File Server Object Access ID (QZDASNID) API Parameters

Required Parameter Group:

The Assign SNADS File Server Object Access ID (QZDASNID) API can be used toassociate an identifier with a file server object. The identifier lets the systemknow that there is a process that is currently working with the file server objectand that the file server object should not be deleted. When you are finished witha file server object, you can delete it by disassociating the access ID from thefile server object (see “Revoke SNADS File Server Object Access ID (QZDRVKID)API” on page 259 for more details).

When you assign an access ID to a file server object, the usage count for theFSO is incremented by one. Each time you call the QZDASNID API, the FSO′susage count is incremented by one. There is no limit to the number of access

1 File server object handle Input Char(32)2 Correlation Input Char(3000)3 Correlation bytes provided Input Bin(4)4 Product ID Input Char(7)5 Access ID Output Char(8)6 Error code I/O Char(*)

Appendix B. SNADS File Server APIs 257

Page 282: AnyMail/400 Mail Server Framework Developer Guide January 1995

IDs that can be assigned to a particular file server object, and multiple accessIDs assigned at the same time.

Note that you do not need to specify the file server name as an input parameter.This API works for both the DIA file server and the SNADS general file server.

Required Parameter GroupFile server object handle

INPUT; CHAR(32)The file server object handle contains the necessary linkage to the file serverobject. The value of this parameter should be taken from the FSO handlethat was returned on the call to the QZDCRFSO API.

CorrelationINPUT; CHAR(3000)The correlation can be used to futher identify a file server object access.The correlation information is defined by the caller. If the bytes-providedfield is zero, this indicates that no correlation is to be stored with the FSO.

This field is defined by the caller.

Correlation bytes providedINPUT; BIN(4)This field specifies the length of the correlation data.

Product IDINPUT; CHAR(7)The product ID is used along with the access ID to identify the file serverobject access. The product ID should be the ID of the product that is usingthe Assign Access API. This parameter is necessary to group access IDstogether by product and to help clean up file server objects. For instance, aproduct that had been installed on a system and was involved in using theAccess APIs was taken off the system, but there were still FSOs beingrefered to by that product. The access cleanup routines check to make surethat a product is installed, and if not, clean up those FSOs.

Valid values for this parameter are:

′QMSFPRD′ MSF product identifier. This value can be used for all file serverobjects that are referenced by MSF messages.

Valid product identifier on the AS/400

Access IDOUTPUT; CHAR(8)The access ID is used along with the product ID to identify the file serverobject access.

Error codeI/O; CHAR(*)See System API Reference for more details on the error code structure.

258 AnyMail/400 MSF

Page 283: AnyMail/400 Mail Server Framework Developer Guide January 1995

Error MessagesCPF3A12 E Parameter structure at wrong level. Correct the error and call this

API again.

CPF3A0D E Temporary server error. The system storage threshhold has beenexceeded. System storage must be reduced before this API can beused.

CPF3A09 E System error. An unrecoverable system error has occurred. Callthis API again.

CPF3CF1 E Error code parameter not valid. Correct the error and call this APIagain.

CPF24B4 E Severe error while addressing parameter list. Correct the error andcall this API again.

CPF9872 E Program ended. An error occurred with one of the parameters.Correct the error and call this API again.

The following syntax diagram is the C language equivalent of the QZDASNIDprototype. This header can be found in the QSYSINC library. See Exampleusing QZDASNID on page 270.

Syntax

#include <qzdasnid.h>void QZDASNID(

void *fso_handle, /* FSO handle */void *correlation, /* Correlation info */char *product_ID, /* Product ID */char *access_ID, /* Access ID */void *error_str /* API Returned Error */

);

Revoke SNADS File Server Object Access ID (QZDRVKID) API Parameters

Required Parameter Group:

The Revoke SNADS File Server Access ID (QZDRVKID) API revokes an access IDto a specific file server object that was previously assigned. When you callQZDRVKID to revoke an access ID, you let the system know that the currentprocess is finished working with the file server object. The access ID that wasoriginally assigned to the file server object must be passed as input. This APIalso decrements the usage count of the FSO by one.

Note: When the usage count of the file server object goes to zero, theQZDRVKID API deletes the file server object.

1 Product ID Input Char(7)2 Access ID Input Char(8)3 Error code I/O Char(*)

Appendix B. SNADS File Server APIs 259

Page 284: AnyMail/400 Mail Server Framework Developer Guide January 1995

Required Parameter GroupProduct ID

INPUT; CHAR(7)The product ID is used along with the access ID to identify the file serverobject access. The product ID should be the ID of the product that is usingthe Assign SNADS File Server Access ID (QZDASNID) API. This parameter isnecessary to group access IDs together by product and to help clean up fileserver objects. For instance, a product that had been installed on a systemand was involved in using the access APIs was taken off the system, butthere were still file server objects being refered to by that product. Theaccess cleanup routines check to make sure that a product is installed, andif not, clean up those FSOs.

Valid values for this parameter are:

′QMSFPRD′ MSF product identifier. This value can be used for all file serverobjects that are referenced by MSF messages.

Valid product identifier on the AS/400

Access IDINPUT; CHAR(8)The access ID is used along with the product ID to identify the file serverobject access. The value of this parameter should be taken from the accessID that was returned on the call to the Assign SNADS File Server Access ID(QZDASNID) API.

Error codeI/O; CHAR(*)See System API Reference for more details on the error code structure.

Error MessagesCPF3A12 E Parameter structure at wrong level. Correct the error and call this

API again.

CPF3A13 E Access ID not found. Specify a valid access ID and call this APIagain.

CPF3A09 E System error. An unrecoverable system error has occurred. Callthis API again.

CPF3CF1 E Error code parameter not valid. Correct the error and call this APIagain.

CPF24B4 E Severe error while addressing parameter list. Correct the error andcall this API again.

CPF9872 E Program ended. An error occurred with one of the parameters.Correct the error and call this API again.

The following syntax diagram is the C language equivalent of the QZDRVKIDprototype. This header can be found in the QSYSINC library. See Exampleusing QZDRVKID on page 272.

260 AnyMail/400 MSF

Page 285: AnyMail/400 Mail Server Framework Developer Guide January 1995

Syntax

#include <qzdrvkid.h>void QZDRVKID(

char *product_ID, /* Product ID */char *access_ID, /* Access ID */void *error_str /* API Returned Error */

);

List SNADS File Server Object Access IDs (QZDLSTID) API Parameters

Required Parameter Group:

The List SNADS File Server Object Access IDs (QZDLSTID) API can be used tolist current access IDs that are owned by the specified product. Each access IDrepresents an access done on a file server object that was obtained by using theQZDASNID API.

The main purpose for this API is to provide a way for a product to clean up if itloses memory of assigned access IDs. A product should use this list API atsome periodic interval to check if it has any assigned access IDs that were notrevoked.

If you use the MSF product ID, ′QMSFPRD′, you do not have to use this list APIfor cleanup purposes. Cleanup routines currently exist in the system to removeaccess IDs assigned to the MSF product. These cleanup routines will removeaccess IDs only when the IDs are no longer associated with any file serverobject (the file server object is no longer needed and has been deleted).

The starting access ID parameter can either be set to zero to have this API startthe search at the beginning of all access IDs, or to a specific access ID. When aspecific access ID is entered, QZDLSTID starts searching with the next greateraccess ID. (No error is returned if the starting access ID does not exist.) If moreaccess IDs exist for a product than were returned on the call to QZDLSTID, thisAPI sets the information status variable in the generic user space header toindicate partially complete information. To retrieve more access IDs, the callershould use the continuation access ID as input for the next call to QZDLSTID.

If the number of access IDs found is greater than the amount of space that isavailable to return the list, QZDLSTID extends the space to contain all the accessIDs.

1 User space name Input Char(20)2 Format Input Char(8)3 Product ID Input Char(7)4 Continuation access ID Input Char(8)5 Error code I/O Char(*)

Appendix B. SNADS File Server APIs 261

Page 286: AnyMail/400 Mail Server Framework Developer Guide January 1995

Required Parameter GroupUser space

INPUT; CHAR(20)The user space is defined by the caller and used by the List Access IDs(QZDLSTID) API to store all the access IDs that are found. This structurecontains the user space name and the library name where the user space isdefined. Each entry in the user space list is an access ID, and the size ofeach list entry in the user space is CHAR(8). For more information on thedetailed structure of the user space, see System API Reference.

Format nameINPUT; CHAR(8)The name of the format that returns access ID information. You can specifythese formats:

ACID0100 Each entry contains an access ID. For a detailed description ofthis format, see “ACID0100 Format” on page 263.

Product IDINPUT; CHAR(7)The product ID should be the ID of the product that is using the List AccessIDs API. This parameter is necessary to group access IDs together byproduct and to help clean up file server objects. For instance, a product thathad been installed on a system and was involved in using the access APIswas taken off the system, but there were still FSOs being referenced by thatproduct. The access cleanup routines check to make sure a product isinstalled, and if not, will clean up those FSOs.

′QMSFPRD′ MSF product identifier. This value can be used for all file serverobjects that are referenced by MSF messages.

A valid product identifier on the AS/400.

Continuation access IDINPUT; CHAR(8)The continuation access ID is used along with the product ID to identify thefirst file server object access to find. You can determine if a previous callresulted in partially complete information by checking the information statusvariable in the generic user space header that follows the API call.

If the API is not attempting to continue from a previous call, this parametermust be set to hex zeros. Otherwise, a valid continuation value must besupplied. The value may be obtained from the list header section of the userspace that was used in the previous call. When continuing, the first entry inthe returned list is the entry that immediately follows the last entry that wasreturned in the previous call.

Error codeI/O; CHAR(*)See System API Reference for more details on the error code structure.

Table 28. User Space Name Structure

Offset

Type FieldDec Hex

0 0 CHAR(10) User space name

10 A CHAR(10) Library name where user space is stored

262 AnyMail/400 MSF

Page 287: AnyMail/400 Mail Server Framework Developer Guide January 1995

User Space VariablesThe following tables describe the order and format of the data that is returned inthe user space. For detailed descriptions of the fields in the tables, see “FieldDescriptions.”

Input Parameter Section: The input parameter section contains a copy of all theinput parameters for QZDLSTID. The copy is made by the QZDLSTID API.

Header Section: The header section contains output information for the caller.The continuation access ID here is passed out to the caller if more access IDsexist. The caller could then use this continuation access ID as an inputparameter on the next call to QZDLSTID.

ACID0100 Format: The ACID0100 format specifies the format of each list entry inthe user space.

Table 29. Input Parameter Section

Offset

Type FieldDec Hex

0 0 CHAR(10) User space name specified

10 A CHAR(10) User space library name specified

20 14 CHAR(8) Format name

28 1C CHAR(7) Product ID

35 23 CHAR(8) Continuation access ID

Table 30. Header Section

Offset

Type FieldDec Hex

0 0 CHAR(8) Continuation access ID

Table 31. ACID0100 Format

Offset

Type FieldDec Hex

0 0 CHAR(8) Access ID

Field DescriptionsContinuation access ID (header section).

OUTPUT; CHAR(8)A continuation point for the API. This value is set based on the contents ofthe information status variable in the generic header for the user space. Thefollowing situations can occur:

• Information Status C. The information returned in the user space is validand complete. No continuation is necessary, and the continuationaccess ID is set to blanks.

• Information Status P. The information returned in the user space is validbut incomplete. The user may call the API again, starting where the lastcall left off. The continuation access ID contains a value that may besupplied as an input parameter in later calls.

Appendix B. SNADS File Server APIs 263

Page 288: AnyMail/400 Mail Server Framework Developer Guide January 1995

• Information Status I. The information returned in the user space is notvalid and is incomplete. The content of the continuation access ID isunpredictable.

Continuation access ID (input section).INPUT; CHAR(8)Used to continue from a previous call to this API which results in partiallycomplete information.

Format name.INPUT; CHAR(8)The name of the format that is used to return access ID information.

Product IDINPUT; CHAR(7)The product ID should be the ID of the product that is using the List AccessIDs API. This parameter is necessary to group access IDs together byproduct and to help clean up file server objects. For instance, a product thathad been installed on a system and was involved in using the access APIswas taken off the system, but there were still FSOs being referenced by thatproduct. The access cleanup routines check to make sure a product isinstalled, and if not, will clean up those FSOs.

User space library name specified.INPUT; CHAR(10)The name of the library that contains the user space.

User space name specified.INPUT; CHAR(10)The name of the user space to which the list of access IDs is returned.

Error MessagesCPF3A12 E Parameter structure at wrong level. Correct the error and call this

API again.

CPF3A13 E Access ID(s) not found. No access IDs exist for the specified product.

CPF3A09 E System error. An unrecoverable system error has occurred. Callthis API again.

CPF3CF1 E Error code parameter not valid. Correct the error and call this APIagain.

CPF24B4 E Severe error while addressing parameter list. Correct the error andcall this API again.

CPF9872 E Program ended. An error occurred with one of the parameters.Correct the error and call this API again.

The following syntax diagram is the C language equivalent of the QZDLSTIDprototype.

264 AnyMail/400 MSF

Page 289: AnyMail/400 Mail Server Framework Developer Guide January 1995

Syntax

#include <qzdlstid.h>void QZDLSTID(

void *user_space, /* User space name */char *list_format, /* List format name */char *product_ID, /* Product ID */char *access_ID, /* Continuation access

id */void *error_str /* API Returned Error */

);

Retrieve SNADS File Server Object Access ID (QZDRTVID) API Parameters

Required Parameter Group:

The Retrieve SNADS File Server Object Access ID (QZDRTVID) API allows thecaller to retrieve information about one access ID. This information includes thefile server object handle for the access ID and any correlation informationassociated with the access ID.

1 Product ID Input Char(7)2 Access ID Input Char(8)3 File server object handle Output Char(32)4 Correlation Output Char(3000)5 Correlation bytes available Output Bin(4)6 Error code I/O Char(*)

Required Parameter GroupProduct ID

INPUT; CHAR(7)The product ID is used along with the access ID to identify the file serverobject access. The product ID should be the ID of the product that is usingthe List Accesses API. This parameter is necessary to group access IDstogether by product and to help clean up file server objects. For instance, aproduct that had been installed on a system and was involved in using theaccess APIs was taken off the system, but there were still FSOs beingreferenced by that product. The access cleanup routines check to make surea product is installed, and if not, will clean up those FSOs.

Valid values for this parameter are:

′QMSFPRD′ MSF product identifier. This value can be used for all file serverobjects that are referenced by MSF messages.

Valid product identifier on the AS/400

Access IDINPUT; CHAR(8)The access ID is used along with the product ID to identify the file serverobject access to find. Valid values for this parameter are:

Appendix B. SNADS File Server APIs 265

Page 290: AnyMail/400 Mail Server Framework Developer Guide January 1995

′0000000000000000′X to ′FFFFFFFFFFFFFFFF′X (hex)

File server object handleOUTPUT; CHAR(32)The file server object handle contains the necessary linkage to the file serverobject that was found by this API.

CorrelationOUTPUT; CHAR(3000)The correlation can be used to further identify a file server object access thatwas found by this API. The correlation information is defined by the caller.

Correlation bytes availableOUTPUT; BIN(4)This field represents the number of bytes of correlation data that is returned.Valid values for this parameter are:

0 to 3000:

Error codeI/O; CHAR(*)See System API Reference for more details on the error code structure.

Error MessagesCPF3A12 E Parameter structure at wrong level. Correct the error and call this

API again.

CPF3A13 E Access ID not found. Specify a valid access ID and call this APIagain.

CPF3A09 E System error. An unrecoverable system error has occurred. Callthis API again.

CPF3CF1 E Error code parameter not valid. Correct the error and call this APIagain.

CPF24B4 E Severe error while addressing parameter list. Correct the error andcall this API again.

CPF9872 E Program ended. An error occurred with one of the parameters.Correct the error and call this API again.

The following syntax diagram is the C language equivalent of the QZDRTVIDprototype.

Syntax

#include <qzdrtvid.h>void QZDRTVID(

char *product_ID, /* Product ID */char *access_ID, /* Continuation access

id */void *fso_handle, /* FSO handle */void *correlation, /* Correlation info */long int *correl_len, /* Correlation length */void *error_str /* API Returned Error */

);

266 AnyMail/400 MSF

Page 291: AnyMail/400 Mail Server Framework Developer Guide January 1995

SNADS File Server APIs — ExamplesThe following examples show how to use the SNADS file server APIs.

• The “Creating an Attachment for an MSF Message” example shows whichfile server APIs you would use if you were creating a file server object tosend.

• The “Using an MSF Message with an Attachment” on page 270 exampleshows how an MSF exit point program would use the QZDASNID andQZDRVKID APIs.

• The “Receiving an MSF Message with an Attachment” on page 272 exampleshows how you can read a file server object.

The APIs shown are being called from different processes, including a mailserver framework exit point program.

Creating an Attachment for an MSF MessageThis example shows how you would use the create FSO API and the write FSOAPI when you create an MSF message. There are two input parameters to themain program: the length of the buffer of data and a pointer to the buffer of data.

#include <stdlib.h>#include <stdio.h>#include <string.h>

#include <qusec.h> /* contains error code typedef */#include <qzmf.h> /* contains MSF structures */#include <qzdcrfso.h> /* contains QZDCRFSO prototype */#include <qzdwtfso.h> /* contains QZDWTFSO prototype */#include <qzdasnid.h> /* contains QZDASNID prototype */

typedef struct Exc_Data_Struct{int excdtalen; /* exception data length */char excdta[500];

} Exc_Data_t;

typedef struct Error_Code_Struct{Qus_EC_t Error;

Exc_Data_t Exc_Data;} Error_Code_t;

/**************************************************************//* File-scoped variables *//**************************************************************/

static Qzd_FS_Handle_t fshandle;static Qzd_FS_Operation_Req_t operation;static Qzd_FS_Obj_Data_Length_t datalen;static Qzd_FS_Name_t fsname;static Qzd_FS_Resume_Pos_t resumepos;

static Qzd_FS_Product_ID_t productid;static Qzd_FS_Access_ID_t accessid;

Appendix B. SNADS File Server APIs 267

Page 292: AnyMail/400 Mail Server Framework Developer Guide January 1995

static Qzd_FS_Correl_t correlation;static Qzd_FS_Correl_Len_t correllen;

static Error_Code_t API_Error_Code;

static Qzmf_Msg_Desc_Hdr0100_t *List_HdrP;static Qzmf_ATTL0100_t *AttP;

/**************************************************************//* Executable code *//**************************************************************/

void main(int argc, char *argv[]){

/**********************************************************//* argv[0] = pointer to buffer of data *//* argv[1] = length of buffer data *//**********************************************************/Qzd_FS_Buffer_t

fsbuffer = (char *)(*(argv));

Qzd_FS_Buffer_Len_tbufferlen = (long int)(*(argv+1))

;/**********************************************************//* Create the file server object. *//**********************************************************/

datalen = 4800; /* Length of data to bewritten is approximately4800 bytes. */

fsname.Qzd_FS_Name_Len = 4;memcpy(fsname.Qzd_FS_Name,

QZD_SNADS_GEN_FILE_SERVER,fsname.Qzd_FS_Name_Len); /* Set file server name

to indicate using theSNADS general file server.*/

API_Error_Code.Error.Bytes_Provided = 500; /* Set the errorcode structure so that anerror code is returned. */

QZDCRFSO( (void *)fshandle,&datalen,(void *)&fsname,(void *)&API_Error_Code);

if (API_Error_Code.Error.Bytes_Available > 0){

printf(″ERROR in call to QZDCRFSO\n″ ) ;exit(1);

}

/**********************************************************//* Write to the file server object. This code assumes *//* that there is less than 16MB of data in the buffer. *//**********************************************************/

operation = QZD_WRITE; /* Request to write to the

268 AnyMail/400 MSF

Page 293: AnyMail/400 Mail Server Framework Developer Guide January 1995

file server object. */API_Error_Code.Error.Bytes_Provided = 500; /* Set the error

code structure so that anerror code is returned. */

QZDWTFSO( (void *)fshandle,&operation,&datalen,(void *)&fsname,&resumepos,(void *)fsbuffer,&bufferlen,(void *)&API_Error_Code);

if (API_Error_Code.Error.Bytes_Available > 0){

printf(″ERROR in call to QZDWTFSO - write.\n″ ) ;exit(1);

}

/**********************************************************//* Terminate writing to the file server object. *//**********************************************************/

operation = QZD_TERM_WRITE; /* Request to terminatethe writing to the FSO. */

API_Error_Code.Error.Bytes_Provided = 500; /* Set the errorcode structure so that anerror code is returned. */

QZDWTFSO( (void *)fshandle,&operation,&datalen,(void *)&fsname,&resumepos,(void *)fsbuffer,&bufferlen,(void *)&API_Error_Code);

if (API_Error_Code.Error.Bytes_Available > 0){

printf(″ERROR in call to QZDWTFSO - terminate write.\n″ ) ;exit(1);

}

/**********************************************************//* Assign access ID to the file server object. *//**********************************************************/

/* Set up correlationinformation. */

memcpy(correlation, ″Library: MYLIB Name: MYFILE″, 27);

/* Get the product ID whichthis program is runningunder. */

API_Error_Code.Error.Bytes_Provided = 500; /* Set the error

Appendix B. SNADS File Server APIs 269

Page 294: AnyMail/400 Mail Server Framework Developer Guide January 1995

code structure so that anerror code is returned. */

QZDASNID( (void *)fshandle,(void *)correlation,productid,accessid,(void *)&API_Error_Code);

if (API_Error_Code.Error.Bytes_Available > 0){

printf(″ERROR in call to QZDASNID.\n″ ) ;exit(1);

}}

Using an MSF Message with an AttachmentThis example shows how you would use the Assign and Revoke APIs in an exitpoint program that is being called from the MSF message forwarding exit point.There is one input parameter to the main program: the access ID that wasoriginally assigned when the file server object was created.

#include <stdlib.h>#include <stdio.h>#include <string.h>

#include <qusec.h> /* contains error code typedef */#include <qzmf.h> /* contains MSF structures */#include <qzdrvkid.h> /* contains QZDRVKID prototype */#include <qzdasnid.h> /* contains QZDASNID prototype */

typedef struct Exc_Data_Struct{int excdtalen; /* exception data length */char excdta[500];

} Exc_Data_t;

typedef struct Error_Code_Struct{Qus_EC_t Error;

Exc_Data_t Exc_Data;} Error_Code_t;

/**************************************************************//* File-scoped variables *//**************************************************************/

static Qzd_FS_Handle_t fshandle;static Qzd_FS_Product_ID_t productid;static Qzd_FS_Access_ID_t accessid;static Qzd_FS_Correl_t correlation;static Qzd_FS_Correl_Len_t correllen;

static Error_Code_t API_Error_Code;

270 AnyMail/400 MSF

Page 295: AnyMail/400 Mail Server Framework Developer Guide January 1995

static int i;static int NumQueues;static Qzd_FS_Access_ID_t crtaccessid;

/**************************************************************//* Executable code *//**************************************************************/

void main(int argc, char *argv[]){

/**********************************************************//* Route the MSF message. This code makes copies of the *//* MSF message and fans them out to the message forwarding*//* queues. Each copy of the MSF message will have a *//* reference to the file server object, so the Assign *//* FSO Access ID (QZDASNID) needs to be called for each *//* copy. *//**********************************************************/

memcpy(crtaccessid, argv[0], 8); /* Copy the input paramterinto the localvariable. */

/* Set up correlationinformation. This will bethe same for each access. */

memcpy(correlation, ″Library: MYLIB Name: MYFILE″, 27);

memcpy(productid,QZMF_FSO_PROD_ID,7); /* Use the product IDfor the mail serverframework. */

for (i=1; i=NumQueues; i++){

/*** Make copy of MSF message. ***/

API_Error_Code.Error.Bytes_Provided = 500; /* Set theerror code structure so thatan error code is returned.*/

QZDASNID( (void *)fshandle,(void *)correlation,productid,accessid,(void *)&API_Error_Code);

if (API_Error_Code.Error.Bytes_Available > 0){

printf(″ERROR in call to QZDASNID.\n″ ) ;exit(1);

}

}

/**********************************************************//* Now that all the MSF message copies have been routed, *//* revoke the access ID that was assigned when the */

Appendix B. SNADS File Server APIs 271

Page 296: AnyMail/400 Mail Server Framework Developer Guide January 1995

/* original message was created. *//**********************************************************/

API_Error_Code.Error.Bytes_Provided = 500; /* Set theerror code structure so thatan error code is returned.*/

QZDRVKID( productid,crtaccessid,(void *)&API_Error_Code);

if (API_Error_Code.Error.Bytes_Available > 0){

printf(″ERROR in call to QZDASNID.\n″ ) ;exit(1);

}

}

Receiving an MSF Message with an AttachmentThis example shows how you would use the read FSO API when you receive anMSF message.

#include <stdlib.h>#include <stdio.h>#include <string.h>

#include <qzmfasrv.h> /* contains MSF protoypes */#include <qzmf.h> /* contains MSF structures */#include <qusec.h> /* contains error code typedef */#include <qzdrvkid.h> /* contains QZDRVKID prototype */#include <qzdrdfso.h> /* contains QZDRDFSO prototype */

#define MAX_BUFFER_LEN 5000;

typedef struct Exc_Data_Struct{int excdtalen; /* exception data length */char excdta[500];

} Exc_Data_t;

typedef struct Error_Code_Struct{Qus_EC_t Error;

Exc_Data_t Exc_Data;} Error_Code_t;

/**************************************************************//* File-scoped variables *//**************************************************************/

static Qzd_FS_Handle_t fshandle;static Qzd_FS_Operation_Req_t operation;static Qzd_FS_Obj_Data_Length_t datalen;

272 AnyMail/400 MSF

Page 297: AnyMail/400 Mail Server Framework Developer Guide January 1995

static Qzd_FS_Name_t fsname;static Qzd_FS_Buffer_t fsbuffer;static Qzd_FS_Buffer_Len_t bufferlen;static Qzd_FS_Buffer_Avail_t bufferavail;

static Qzd_FS_Product_ID_t productid;static Qzd_FS_Access_ID_t crtaccessid;

static Error_Code_t API_Error_Code;

/**************************************************************//* Executable code *//**************************************************************/

void main(int argc, char *argv[]){/************************************************************//* The argv vector contains all the information that is *//* passed by MSF to this exit point program. *//* *//* This code example shows how the MSF message descriptor *//* list is passed in and how the attachment reference list *//* is used. *//************************************************************/

Qzmf_Msg_Desc_Hdr0100_t*List_HdrP

;

Qzmf_ATTL0100_t *AttP;

Qzmf_FSO_t*FSOP

;

long int*Return_Code = (long int *)(*(argv + 6)),Passed_Num_Attrbts = *(long int *)(*(argv + 4));

short intDesc_Indx = 0;

/* Set a pointer to the passed message descriptor attribute *//* array. */Qzmf_Msg_Desc_Attrbt_Entity_t

*Passed_Msg_Desc_AttrP =(Qzmf_Msg_Desc_Attrbt_Entity_t *)(*(argv + 3))

;

/* Locate the message descriptor corresponding to the *//* attachment reference list. */while (Desc_Indx < Passed_Num_Attrbts){if ( !memcmp( (Passed_Msg_Desc_AttrP + Desc_Indx) ->

Appendix B. SNADS File Server APIs 273

Page 298: AnyMail/400 Mail Server Framework Developer Guide January 1995

Msg_Desc_Format_Name,QZMF_ATTACH_REF_FMT,QZMF_MSG_DESC_FMT_LENGTH) )

{/* Set the attachment reference list header pointer. */List_HdrP = (Qzmf_Msg_Desc_Hdr0100_t *)

((Passed_Msg_Desc_AttrP + Desc_Indx) ->Msg_Desc_Ptr);

break;}++Desc_Indx;

} /* end while loop */

if (Desc_Indx == Passed_Num_Attrbts){printf(″No attachment reference list exists; quitting\n″ ) ;exit(1);

}

/* Set up pointer to the first attachment reference listentry. It is assumed that there is only one attachmentreference in the attachment reference list and that it isa SNADS FSO attachment reference. */

AttP = (Qzmf_ATTL0100_t *)((char *)List_HdrP +List_HdrP->First_Entry_Offset);

/* Set pointer to the entry-specific information in the *//* attachment reference entry. */FSOP = (Qzmf_FSO_t *)( (char *)AttP + AttP->Displacement);

/************************************************************//* After receiving the MSF message, the contents of the FSO *//* are read and placed into a user buffer area. *//************************************************************/

memcpy(fshandle, FSOP->FSO_Handle, 32);operation = QZD_INIT_READ; /* An initiate read operation

is done first. */fsname.Qzd_FS_Name_Len = FSOP->FS_Name_Length;memcpy(fsname.Qzd_FS_Name, FSOP->FS_Name,

fsname.Qzd_FS_Name_Len);

bufferlen = MAX_BUFFER_LEN;

fsbuffer = (char *)malloc(bufferlen); /* Allocate memoryfor the buffer of data. */

API_Error_Code.Error.Bytes_Provided = 500; /* Set theerror code structure so thatan error code is returned.*/

QZDRDFSO( (void *)fshandle,&operation,&datalen,(void *)&fsname,(void *)fsbuffer,&bufferlen,&bufferavail,(void *)&API_Error_Code);

274 AnyMail/400 MSF

Page 299: AnyMail/400 Mail Server Framework Developer Guide January 1995

if (API_Error_Code.Error.Bytes_Available > 0){

printf(″ERROR in call to QZDRDFSO.\n″ ) ;exit(1);

}

/************************************************************//* After reading all the data from the FSO, revoke the *//* access ID that was assigned when the FSO was created on *//* this system. *//************************************************************/

memcpy(productid, FSOP->Product_ID, 7);memcpy(crtaccessid, FSOP->Access_ID, 8);

API_Error_Code.Error.Bytes_Provided = 500; /* Set theerror code structure so thatan error code is returned.*/

QZDRVKID( productid,crtaccessid,(void *)&API_Error_Code);

if (API_Error_Code.Error.Bytes_Available > 0){

printf(″ERROR in call to QZDRVKID.\n″ ) ;exit(1);

}

}

Appendix B. SNADS File Server APIs 275

Page 300: AnyMail/400 Mail Server Framework Developer Guide January 1995

Appendix C. Using the AS/400 System Distribution Directory

This appendix describes how the AS/400 system distribution directory can beused by MSF exit point programs. The system distribution directory can helpexit point programs perform their functions (such as obtaining E-mail addresses).

This is not a thorough discussion of the system distribution directory and itscapabilities. This appendix discusses the aspects of the system distributiondirectory that are important to MSF and MSF exit point programs. For a morethorough description of the system distribution directory, see SNA DistributionServices.

Description of the System Distribution DirectoryThe system distribution directory is supplied with OS/400. There may be otherdirectories that exist on the AS/400, but there is only one system distributiondirectory. We only discuss the system distribution directory here and refer to itas the directory . The directory contains a collection of entries for users on boththe local system and remote systems that are authorized to send and receivedistributions on the network. Distributions are defined to be messages, data orobjects that are sent between network users.

Each entry in the system distribution directory contains information about anetwork user. This information includes the user′s ID and address along with atextual description. Optional fields for each entry specify information such as thenetwork user′s E-mail addresses (for example, X.400 O/R address or SMTPaddress).

You can add, change, and remove entries from the local system distributiondirectory. Also, entries from system distribution directories located on remoteAS/400s can be shadowed to the local system. Directory shadowing provides amethod to share directory information among AS/400s in a network. If adirectory entry is added, removed, or modified on any AS/400 in the network, thechange can be sent (shadowed) to the other AS/400s in the network.

You can add directory entries by using the Add Directory Entry (ADDDIRE)command, change entries by using the Change Directory Entry (CHGDIRE)command, remove entries by using the Remove Directory Entry (RMVDIRE)command, and display entries by using the Display Directory Entries (DSPDIRE)command. You can use the Work with Directory Entries (WRKDIRE) command tointeractively perform any of the previous commands on a list of entries.

The following displays show the result of using the Display Directory Entries(DSPDIRE) command to display one of the entries in the directory. The firstdisplay shows the SNADS address, text description and the person′s name.

276 Copyright IBM Corp. 1995

Page 301: AnyMail/400 Mail Server Framework Developer Guide January 1995

� �Display Directory Entry Details

User ID/Address . . . . : JDOE RCHASD0X Description . . . . . . : J. Doe on rchasd0x System name/Group . . . : RCHASD0X User profile . . . . . : Network user ID . . . . : JDOE RCHASD0X

Name:Last . . . . . . . . : DoeFirst . . . . . . . . : JohnMiddle . . . . . . . :Preferred . . . . . . :Full . . . . . . . . : Doe, John

Department . . . . . . : Job title . . . . . . . : Company . . . . . . . . :

More... Press Enter to continue.

F3=Exit F12=Cancel F14=Display X.400 O/R name F18=Display location details F19=Display name for SMTP F24=More keys

� �Figure 83. Display Directory Entry (First Display)

The second display shows the person′s telephone number, FAX telephonenumber, and physical location and address.

� �Display Directory Entry Details

Telephone numbers . . . : 1-123-555-1234

FAX telephone number . : 1-123-555-1111

Location . . . . . . . : Building . . . . . . . : Office . . . . . . . . :

Mailing address . . . . :

Forward from user identifier:User ID/Address . . . :

More... Press Enter to continue.

F3=Exit F12=Cancel F14=Display X.400 O/R name F18=Display location details F19=Display name for SMTP F24=More keys

� �Figure 84. Display Directory Entry (Second Display)

The third display shows the person′s preferred address as being UserID/Address (SNADS). The display shows the person′s mail service level is userindex, which indicates mail is delivered to this person by means of OS/400distribution services.

Appendix C. Using the AS/400 System Distribution Directory 277

Page 302: AnyMail/400 Mail Server Framework Developer Guide January 1995

� �Display Directory Entry Details

Locally-defined . . . . : Yes

Indirect user . . . . . : No Print cover page . . . : Mail notification . . . :

Text . . . . . . . . . :

Mail service level . . : User index

Preferred address . . . : User ID/AddressAddress type . . . . :

More... Press Enter to continue.

F3=Exit F12=Cancel F14=Display X.400 O/R name F18=Display location details F19=Display name for SMTP F24=More keys

� �Figure 85. Display Directory Entry (Third Display)

The fourth display shows information about the last time this entry was updated.

� �Display Directory Entry Details

cc:Mail (trademark of Lotus Development Corporation):cc:Mail address . . . :

cc:Mail comment . . . :

Last update:Date/Time . . . . . . : 09/23/94 13:24:59User ID/Address . . . : JDOE RCHAS365

Bottom Press Enter to continue.

F3=Exit F12=Cancel F14=Display X.400 O/R name F18=Display location details F19=Display name for SMTP F24=More keys

� �Figure 86. Display Directory Entry (Fourth Display)

The system distribution directory can be used by MSF exit point programs to findinformation about message recipients and originators. Figure 87 on page 279shows an MSF exit point program accessing address information in the directory.

278 AnyMail/400 MSF

Page 303: AnyMail/400 Mail Server Framework Developer Guide January 1995

Figure 87. MSF Exit Point Program Searching the Directory

There is a system distribution directory API, Search System Directory(QOKSCHD), that you can use to search the directory for entries that match aspecified criteria. The system distribution directory also allows you to defineyour own user-defined fields in the directory. The search system directory APIalong with the user-defined fields allow you to create information about messagerecipients and originators, store the information in the system distributiondirectory, and retrieve the information during a search.

As an example, assume an address resolution exit point program processes anMSF message that has a recipient with an SMTP address. The exit pointprogram can search the directory for an entry whose SMTP address fieldmatches the recipient′s SMTP address. If the entry is found in the directory, theexit point program can verify if the recipient is at a remote system by checking ifthe user profile field in the entry is blank. If the recipient is at a remote system,the exit point program may map the address to another E-mail address for thatrecipient, such as an X.400 address (which is also found in the directory entry).

For more information on the system distribution directory and directoryshadowing, see SNA Distribution Services. The user-defined fields and theSearch System Directory (QOKSCHD) API are described further in the followingtopics.

User-Defined Directory FieldsYou are able to define your own fields in the system distribution directory. Bydefining your own fields, you can store additional information about networkusers in the directory. The fields that you define are called user-defined fields.

You can create the user-defined fields in the directory by using the ChangeSystem Directory Attributes (CHGSYSDIRA) command. This will create the fieldsfor every entry in the directory. You can put a value in an entry′s user-definedfield (USRDFNFLD) by using the Add Directory Entry (ADDDIRE) or ChangeDirectory Entry (CHGDIRE) commands.

Once the user-defined fields have been specified, you can use the SearchSystem Directory API to look for specific values in the user-defined fields.

Note: When you configure a new address data type in MSF, you specify the typename . This type name is used by MSF as the field name when searching

Appendix C. Using the AS/400 System Distribution Directory 279

Page 304: AnyMail/400 Mail Server Framework Developer Guide January 1995

the directory. Therefore, if you intend on creating a new address typeand storing the address values in the directory, you should create auser-defined field having the same field name as the type name . Formore information on type names, see “MSF Data Types” on page 18.

Search System Directory APIThe Search System Directory (QOKSCHD) API searches the system distributiondirectory for entries that match the specified search criteria.

The API can search any of the directory entry fields, including the user-definedfields. You specify both the field name to search and the value of the field in therequest variable parameter of the API. The API returns the results of the searchin the receiver variable parameter. The receiver variable contains all directoryentries that match the search criteria.

Allowing Directory Searches

OS/400 is shipped such that searches of the system distribution directory arenot allowed. The reason for this is because the time to create the searchdata can be long and the created files that contain the search data can belarge (if there are many directory entries). By not allowing directorysearches, those resources can be better utilized on AS/400s that do notrequire searches on the directory.

For programs to be able to use the Search System Directory API, searches ofthe directory must be allowed. You can use the Change System DirectoryAttributes (CHGSYSDIRA) command to specify that directory searches areallowed by changing the Allow search (ALWSCH) parameter to *YES. If this isnot done, attempts to use the search API will result in error messageCPI9A9C (Search data does not exist).

The CHGSYSDIRA command may fail due to error message CPD9A9A. Inthis case, there are other processes with locks on required directory files. Ifthis occurs, look at the extended help on the CPD9A9A message to determinethe files that are locked. Then, use the Work with Object Locks(WRKOBJLCK) command to find the processes that are holding the locks.Usually, these processes are SNADS processes running in the QSNADSsubsystem. Have the processes that are holding the locks release them.This may involve ending the processes, such as ending the QSNADSsubsystem or QSERVER subsystem by using the End Subsystem (ENDSBS)command. Once the locks are released, the CHGSYSDIRA command cancomplete successfully.

For more information on the search system directory API, see the System APIReference.

A Program that Uses the Search System Directory API — ExampleThe following C code is an example of using the Search System Directory(QOKSCHD) API. Note that this example is an interactive program that obtainsinput from the keyboard and gives output to the screen. It is a basic examplethat shows how to obtain a person′s telephone number from the person′s name.It is not an MSF exit point program, but is intended to give only an example of

280 AnyMail/400 MSF

Page 305: AnyMail/400 Mail Server Framework Developer Guide January 1995

code that uses the API. The CHGSYSDIRA command must be used to allowdirectory searches before this program can be run.

STRUCT.H Header File for Lookup.CThe STRUCT.H file is a header file that is included by the LOOKUP.C program. Itcontains structures used by LOOKUP.C program.

/**************************************************************//* *//* Include: struct.h *//* *//* This include is for the program lookup.c. It must *//* be used on an AS/400 level V3R1 or later. See the *//* program listing for more detail. *//* *//**************************************************************/

#ifndef _STRUCT_H#define _STRUCT_H

typedef union /* Fields to return */{Qok_SREQ0102_t sreq0102[FIELDSRTN];

/* Format SREQ0102 is larger*/Qok_SREQ0103_t sreq0103[FIELDSRTN];

/* than SREQ0103, so it is */} send_union_t; /* defined over SREQ0102 */

typedef struct{Qok_SREQ0101_t req0101header;

/* Header part of SREQ0101 */char Request_Field_Value[942];

/* Data part of SREQ0101942 bytes is currentlythe biggest field youcan search on:Preferred Address */

} request0101_t;

typedef struct /* Request format data */{Qok_SREQ0100_t sreq0100; /* Format SREQ0100 */request0101_t sreq0101[FIELDSCH];

/* Fields to search on */ send_union_t sendbuf; /* Format of fields returned*/} reqbuf_t;

typedef struct /* Data for a returned field*/{Qok_SRCV0111_t srcv0111[FIELDSRTN];

/* Header for SRCV0111 */char data_0111[942]; /* Data for SRCV0111

942 bytes is currentlythe biggest field youcan search on:Preferred Address */

} return_union_t;

Appendix C. Using the AS/400 System Distribution Directory 281

Page 306: AnyMail/400 Mail Server Framework Developer Guide January 1995

typedef struct /* Information on each user */{Qok_SRCV0101_t return_header;/* Header for SRCV0101 */return_union_t return_data; /* Data for SRCV0101 */

} returnbuf_t;

typedef struct /* Receive format data */{Qok_SRCV0100_t srcv0100; /* Request format SRCV0100 */returnbuf_t srcv0101[USERS];/* enough space for each

user */} rcvbuf_t; /* returned from the API */

typedef struct{char userid[USERIDLEN]; /* User ID array */char useradd[USERADDLEN]; /* User address array */char fulnam[FULLNAMELEN]; /* Full name array */char telnum1[TELNUMLEN]; /* Telephone number 1 */char telnum2[TELNUMLEN]; /* Telephone number 2 */

} user_format_t;

typedef struct{rcvbuf_t rcvsearchbuf; /* Receiver variable */long int reclength; /* Length of receiver var.*/char recformat[8]; /* Format of info returned*/char apifunction[10]; /* Function to perform */char resindicator; /* Temp resource indicator*/reqbuf_t reqsearchbuf; /* Request variable */long int reqlength; /* Length of request var */char reqformat[8]; /* Format of information

requested */Qus_EC_t errors; /* Format for errors

returned */} searchtype_t;

#endif /* _STRUCT_H */

CONSTS.H Header File for Lookup.CThe CONSTS.H file is a header file that is included by the LOOKUP.C program. Itcontains constants and structures used by the LOOKUP.C program.

/**************************************************************//* *//* Include: consts.h *//* *//* This include is for the program lookup.c. It must *//* be used on an AS/400 level V3R1 or later. See the *//* program listing for more detail. *//* *//**************************************************************/

#ifndef _CONSTS_H#define _CONSTS_H

282 AnyMail/400 MSF

Page 307: AnyMail/400 Mail Server Framework Developer Guide January 1995

#define WILDCARD ″* ″ /* Default wildcard is * */#define PRODIBM ″*IBM ″ /* Product id for IBM fields */#define BLANK8 ″ ″ /* Blanks for ordered format */#define BLANK16 ″ ″

/* Blanks for initializing theResource Handler */

#define SEARCH ″*SEARCH ″ /* Value to indicate a search*/#define CLEANUP ″*CLEANUP ″ /* Value to indicate cleanup */#define OFF ′ 0 ′ /* Used to set indicators off*/#define ON ′ 1 ′ /* Used to set indicators on */#define TERM ′ \0′ /* Ending char for strings */

#define USERS 3 /* Number of users to returnper call */

#define FIELDSCH 2 /* Number of fields that aresearched on */

#define FIELDSRTN 5 /* Number of fields to return*/#define FULLNAMELEN 51 /* A Full name is only 50

characters (max) but weneed an extra character tohold the ′ \0′ characterfor displaying acharacter string in C */

#define USERIDLEN 9 /* 8 chars + 1 for the ′ \0′ */#define USERADDLEN 9 /* 8 chars + 1 for the ′ \0′ */#define TELNUMLEN 27 /* 26 chars + 1 for the ′ \0′ */

#endif /* _CONSTS_H */

LOOKUP.C Program to Search DirectoryThe LOOKUP.C file is the example ILE C/400 program that uses the SearchSystem Directory API.

/*************************************************************//* */ /* This program is an example of how to call and use the */ /* System Distribution Directory′ s Search API (QOKSCHD). */ /* */ /* This program acts as a telephone directory to search */ /* for a person′ s telephone number that is stored in */ /* the system distribution directory. The program is called */ /* with a single person′ s name as a parameter that is */ /* passed to the program by the PARM(last name first name) */ /* on the call to this program. You can state the name */ /* directly, or use the wildcard *. */ /* */ /* example: CALL DIR/LOOKUP PARM(JONES SHAWN) */ /* */ /* -OR- with a wildcard in the first or last name or both: */ /* */ /* example: CALL DIR/LOOKUP PARM(GORDON G*) */ /* example: CALL DIR/LOOKUP PARM(O* TANYA) */ /* example: CALL DIR/LOOKUP PARM(SCH* JO*) */ /* */ /* (to search for multiple people, to save keystrokes or */ /* to find a name that you don′ t quite know how to spell) */ /* */ /*************************************************************/

Appendix C. Using the AS/400 System Distribution Directory 283

Page 308: AnyMail/400 Mail Server Framework Developer Guide January 1995

/*************************************************************/ /* Important note: The AS/400 that runs this program */ /* must be set up for directory search. This is done by */ /* changing the system directory attributes by entering */ /* CHGSYSDIRA ALWSCH(*YES) on any command line. */ /*************************************************************/

#include <stdio.h> /* Standard I/O library */#include <stdlib.h> /* General utilities library */#include <stddef.h> /* Common definitions library */#include <string.h> /* Strings and memory library */#include <qusec.h> /* API Error structure */#include <qokschd.h> /* Search API structures */#include ″consts.h″ /* Constants values used */#include ″struct.h″ /* Search API structures used */

char* fieldin[2] = {″LSTNAM ″ , ″FSTPREFNAM″};/* Field names to search on */

char* fieldout[5] ={″USRID ″ , ″USRADDR ″ , ″FULNAM ″ ,″TELNBR1 ″ , ″TELNBR2 ″}; /* Field names to return */

int srchoffset; /* Offset to the search request array */int numsrchflds; /* Num of fields in the search req array*/int returnoffset; /* Offset to array of fields returned */int numrtnflds; /* Num of elements in the field array */int numusersrtn; /* Num of elements in the array of users*/

char *walk_ptr; /* Generic pointer to any structure */

void init_data(searchtype_t *fill, char *name[]){

int i; /* Loop variable */

/**************************************************************//* Initialize request format SREQ0100 *//**************************************************************/

fill->reqsearchbuf.sreq0100.Data_Input_CCSID = 0; /* CCSID */

fill->reqsearchbuf.sreq0100.Data_Input_CS = 0; /* Char set */

fill->reqsearchbuf.sreq0100.Data_Input_CP = 0; /* Code page */

memcpy(&fill->reqsearchbuf.sreq0100.Wildcard[0],(char *)WILDCARD, sizeof(WILDCARD)-1);

/* Wildcard defaulted to * */fill->reqsearchbuf.sreq0100. /* Do not convert the data */

Convert_Receiver_Indicator[0] = ′ 2 ′ ;/* return CCSID *//* instead of GCID */

fill->reqsearchbuf.sreq0100.Data_To_Search[0] = ON;/* Search ALL data */

fill->reqsearchbuf.sreq0100.Verification_Indicator[0] = ON;/* Verify input parameters */

fill->reqsearchbuf.sreq0100.Request_Continue_Handle[0] = OFF;

/* Must be 0 initially */memcpy(&fill->reqsearchbuf.sreq0100.

284 AnyMail/400 MSF

Page 309: AnyMail/400 Mail Server Framework Developer Guide January 1995

Request_Resource_Handle,(char *)BLANK16,sizeof(BLANK16)-1); /* Blank out res. handler */

memcpy(&fill->reqsearchbuf.sreq0100.Request_Array_Format[0],(char *)FmtSREQ0101,sizeof(FmtSREQ0101)-1); /* Request format SREQ0101 */

fill->reqsearchbuf.sreq0100.Request_Array_Offset =srchoffset; /* Starting position of data

in format SREQ0101 */fill->reqsearchbuf.sreq0100.Request_Array_Elements =

numsrchflds; /* Number of search fields */memcpy(&fill->reqsearchbuf.sreq0100.

Flds_To_Return_Array_Format[0],(char *)FmtSREQ0102,sizeof(FmtSREQ0102)-1); /* Request format SREQ0102 */

fill->reqsearchbuf.sreq0100.Fields_To_Return_Array_Offset =returnoffset; /* Starting position of data

in format SREQ0102 */fill->reqsearchbuf.sreq0100.Fields_To_Return_Array_Elements=

numrtnflds; /* Number of return fields */memcpy(&fill->reqsearchbuf.sreq0100.

Users_To_Return_Array_Format[0],(char *)FmtSRCV0101,sizeof(FmtSRCV0101)-1); /* Receive format SRCV0101 */

fill->reqsearchbuf.sreq0100.Users_To_Return_Array_Elements=numusersrtn; /* Number of users to return

per call to search API */memcpy(&fill->reqsearchbuf.sreq0100.

Fields_Returned_Array_Format[0],(char *)FmtSRCV0111,sizeof(FmtSRCV0111)-1); /* Receive format SRCV0111 */

memcpy(&fill->reqsearchbuf.sreq0100.Order_Of_Flds_Returned_Format[0],(char *)BLANK8,sizeof(BLANK8)-1); /* Do not return data

ordered by array */

/**************************************************************//* Initialize request format SREQ0101 *//**************************************************************/

walk_ptr = (char *)fill->reqsearchbuf.sreq0101;/* Start the walk pointer at

SREQ0101 */for(i=0;i<numsrchflds;i++){ /* Define all search fields*/((Qok_SREQ0101_t *)walk_ptr)->Current_Entry_Length =sizeof(Qok_SREQ0101_t) + strlen(name[i+1]);

/* Length of current entryis the header + data */

((Qok_SREQ0101_t *)walk_ptr)->Compare_Value[0] = ON;/* Compare value must be 1 */

memcpy(&((Qok_SREQ0101_t *)walk_ptr)->Request_Field_Name[0], fieldin[i],sizeof(fieldin[i])-1);

/* Field name to search on */memcpy(&((Qok_SREQ0101_t *)walk_ptr)->

Request_Product_ID[0],(char *)PRODIBM,sizeof(PRODIBM)-1); /* Product ID to search on

which is ′ *IBM′ for thisexample */

((Qok_SREQ0101_t *)walk_ptr)->Request_Field_Length =strlen(name[i+1]); /* Set length of the search

data */walk_ptr += sizeof(Qok_SREQ0101_t);

Appendix C. Using the AS/400 System Distribution Directory 285

Page 310: AnyMail/400 Mail Server Framework Developer Guide January 1995

/* Advance the pointer bythe size of the SREQ0101structure */

memcpy(walk_ptr,name[i+1],strlen(name[i+1]));/* Fill in search data */

walk_ptr += strlen(name[i+1]);/* Advance pointer to the

end of the search data */}

/**************************************************************//* Initialize request format SREQ0102 *//**************************************************************/

for(i=0;i<numrtnflds;i++){ /* Define the return fields*/memcpy(&fill->reqsearchbuf.sendbuf.sreq0102[i].

Field_To_Return_Field_Name[0], fieldout[i],sizeof(fieldout[i])-1);

/* Field name to return */memcpy(&fill->reqsearchbuf.sendbuf.sreq0102[i].

Field_To_Return_Product_ID[0],(char *)PRODIBM,sizeof(PRODIBM)-1);

/* Product id to return */}

/**************************************************************//* Initialize the rest of the search parameters *//**************************************************************/

fill->reclength = sizeof(rcvbuf_t);/* Size of receiver */

memcpy(&fill->recformat[0],(char *)FmtSRCV0100,sizeof(FmtSRCV0100)-1); /* Receiver format SRCV0100*/

memcpy(&fill->apifunction[0],(char *)SEARCH,sizeof(SEARCH)-1); /* Request a search */

fill->resindicator = ON; /* Keep resource files open.This MUST be done if youwant to get continuousdata from the directory.Otherwise the API willpull out the same dataafter every search */

fill->reqlength = sizeof(reqbuf_t);/* Size of request struct */

memcpy(&fill->reqformat[0],(char *)FmtSREQ0100,sizeof(FmtSREQ0100)-1); /* Request format SREQ0100 */

fill->errors.Bytes_Provided = 0;/* Initialize for no error

receiving */}

void send_data(searchtype_t *send){

/**************************************************************//* Send search data to Search API *//**************************************************************/

QOKSCHD (&send->rcvsearchbuf,send->reclength,&send->recformat[0],&send->apifunction[0],&send->resindicator,&send->reqsearchbuf,

286 AnyMail/400 MSF

Page 311: AnyMail/400 Mail Server Framework Developer Guide January 1995

send->reqlength,&send->reqformat[0],&send->errors);

}

void display_data(searchtype_t *process){

int i,j; /* Loop variable */char key; /* Check for key press */long int datalen; /* Temporary data variable */user_format_t user; /* All the data fields for

each user to be filled inby the API */

char *data[FIELDSRTN]; /* Array of pointers to data */

data[0] = &user.userid[0]; /* First field returneddata[1] = &user.useradd[0]; /* Second field returneddata[2] = &user.fulnam[0]; /* Third field returneddata[3] = &user.telnum1[0]; /* Fourth field returneddata[4] = &user.telnum2[0]; /* Fifth field returned

walk_ptr = (char *)process; /* Start at beginning of data*/

/**************************************************************//* Loop through data sent back from the search API and format *//* it to display it on the screen. *//**************************************************************/

if (process->rcvsearchbuf.srcv0100.Entries_Returned > 0){walk_ptr += process->rcvsearchbuf.srcv0100.

User_Array_Offset;/* Advance pointer past

SRCV0100 header data */for (i=0;i<process->rcvsearchbuf.srcv0100.

Entries_Returned;i++)/* For each user returned */

{walk_ptr += 2*sizeof(long int);

/* Advance ptr past SRCV0101header information */

for (j=0;j<FIELDSRTN;j++)/* For each field returned*/

{datalen = ((Qok_SRCV0111_t *)walk_ptr)->

ReturnedFieldLength;/* length of current entry */

if (datalen > 0) /* If data exists... copy */memcpy(data[j],walk_ptr +

sizeof(Qok_SRCV0111_t),datalen);/* it to its proper field */

*(data[j] + datalen) = TERM;/* Add a termination character

to the end of the data */walk_ptr += sizeof(Qok_SRCV0111_t) + datalen;

/* Advance pointer past nextSRCV0111 header */

}

Appendix C. Using the AS/400 System Distribution Directory 287

Page 312: AnyMail/400 Mail Server Framework Developer Guide January 1995

/**************************************************************//* Display the current user′ s name, user ID, address, and *//* telephone numbers to the screen. *//**************************************************************/

printf(″Full name : %s\n″″User ID / Address : %s / %s\n″″Telephone number(s) : %s\n″″ : %s\n\n″ ,&user.fulnam[0],&user.userid[0],&user.useradd[0],&user.telnum1[0],&user.telnum2[0]);

}}

/**************************************************************//* Put the new resource handle back in SREQ0100 in case you *//* need to call the search API again. If this is not done, *//* the same information is retrieved on the next *//* call to the API (inside of this program). *//**************************************************************/

memcpy(&process->reqsearchbuf.sreq0100.Request_Resource_Handle[0],&process->rcvsearchbuf.srcv0100.Receiver_Resource_Handle[0],sizeof(process->reqsearchbuf.sreq0100.

Request_Resource_Handle));

/**************************************************************//* Check the handle return code to see if there are more *//* users in the directory that match the search criteria *//* that can be retrieved. Also check to see if the person *//* running this program would like to continue searching *//* for more users that match the given criteria. *//**************************************************************/

if (process->rcvsearchbuf.srcv0100.Receiver_Continue_Handle[0] == ON)

/* If more users exists toreturn from the directory */

{process->reqsearchbuf.sreq0100.Request_Continue_Handle[0] = ON;

/* Set continue flag on inSREQ0100 request field */

printf(″\n\n%s″ ,″press <enter> to continue, ″″or q <enter> to quit.\n″ ) ;

if ((key = getchar()) == ′ q′ | | key == ′ Q′ )process->rcvsearchbuf.srcv0100.Receiver_Continue_Handle[0] = OFF;

/* Set continue value off */}

}

void main(int argc, char *argv[]){

searchtype_t data; /* Data to send to the API */int i; /* Loop variable */

288 AnyMail/400 MSF

Page 313: AnyMail/400 Mail Server Framework Developer Guide January 1995

if (argc != 3) /* Must pass in 2 parameters */{printf(″\n%s\n″ ,

″To use this program, you must specify a ″″person′ s name in the program′ s\n″″parameter in the form of PARM(last name ″″first name) with a valid wildcard\n″″of * in either the first or last ″″name (or both). Only one name\n″″can be specified per call.\n″ ) ;

exit(0); /* End the program */}

srchoffset = offsetof(reqbuf_t,sreq0101);/* Offset to SREQ0101 data */

returnoffset = offsetof(reqbuf_t,sendbuf);/* Offset to SREQ0102 data */

numsrchflds = 2; /* Number of fields to searchon (last and first name) */

numrtnflds = 5; /* Number of fields to bereturned per user(full name, tele #,useridand address) */

numusersrtn = USERS; /* Setup search to return 3users per call. */

init_data(&data, &argv[0]); /* Procedure to initialize thesearch data and to read thename passed in from thecommand line */

data.rcvsearchbuf.srcv0100.Receiver_Continue_Handle[0]= ON; /* Use this to initialize the

main loop since it gets setafter the call to the API */

/**************************************************************//* Main loop to search through the directory and call the API *//**************************************************************/

while (data.rcvsearchbuf.srcv0100.Receiver_Continue_Handle[0] == ON)

/* While data exists on thesystem matching criteria */

{ send_data(&data); /* Send search data to API */

display_data(&data); /* Display data on the screen*/}

printf(″\n.........................Directory ″″search complete.........................\n\n″ ) ;

memcpy(&data.apifunction[0],(char *)CLEANUP,sizeof(CLEANUP)-1); /* Issue a CLEANUP request.

This must be done since weasked to leave the resourcefiles open. The cleanuprequest closes those files*/

send_data(&data); /* Close the necessary files */}

Appendix C. Using the AS/400 System Distribution Directory 289

Page 314: AnyMail/400 Mail Server Framework Developer Guide January 1995

Output from the LOOKUP.C ProgramThe LOOKUP.C program produces output similar to the following display.

� �Full name : Gordon, Gregory D. (Greg)User ID / Address : GGORDON / AS400SXTelephone number(s) : 1-800-555-9000

: 1-800-444-8000

Full name : Hasan, AliUser ID / Address : AHASAN / ASLIB20Telephone number(s) : 1-800-777-3232

: 1-800-332-8181

Full name : Jones, Shawn C. (Shawn)User ID / Address : SJONES / AS400SXTelephone number(s) : 1-800-333-7000

:

press <enter> to continue, or q <enter> to quit.

===>

� �

Helpful Hints about the System Distribution DirectoryThe following list contains information that may be helpful when working with thesystem distribution directory.

• In order to specify an entry′s preferred address to be something other than aSNADS UserID/Address, the entry′s mail service level must not be userindex. Note that no message is issued if the preferred address is specifiedas something other than UserID/Address, but the preferred address does notactually change . This is because the mail service level value of user indexindicates that the only valid preferred address is UserID/Address.

• When you change the mail service level of a directory entry to Systemmessage store by using the ADDDIRE or CHGDIRE commands, you mayreceive a CPI9A9E message (System message store does not exist). If thesystem message store does not exist, but you need to specify a preferredaddress for the entry, either choose another mail service level or ignore theCPI9A9E by pressing the enter key again. This will change the value of themail service level and allow you to change the preferred address value.

• If the Search System Directory (QOKSCHD) API will be used (by theQZMFSNPA exit point program or any other program), remember to changethe directory attribute ″allow search″ (ALWSCH) to *YES.

290 AnyMail/400 MSF

Page 315: AnyMail/400 Mail Server Framework Developer Guide January 1995

Appendix D. QZMFSNPA Exit Point Program

This appendix describes the IBM-supplied exit point program QZMFSNPA. Thisis the one exit point program that is supplied by IBM that is not associated witha particular protocol (such as SNADS).

The purpose of this program is to switch the E-mail addresses of the messagerecipients to their preferred addresses. This function is provided because it is acommon function for mail gateways.

Description of the QZMFSNPA Exit Point ProgramThe system distribution directory contains a number of fields for each entry.Many of these fields specify various E-mail addresses. For instance, an entrymay have a SNADS E-mail address, a SMTP E-mail address, and a X.400 E-mailaddress. Each of these addresses are used to route E-mail messages to theuser by means of the corresponding protocol. For example, SMTP addressesare used to send E-mail messages to the recipient via the SMTP protocol.

However, at times it may be necessary to switch protocols of the message. Thisrequires the use of the corresponding E-mail address. For example, a mailgateway may need to convert every E-mail message to an SMTP message. Partof this function requires the recipients′ E-mail addresses to be switched to SMTPaddresses. QZMFSNPA is an exit point program provided by IBM that switchesaddresses of the recipients by using information in the system distributiondirectory.

The QZMFSNPA exit point program is configured for the address resolution exitpoint (QIBM_QZMFMSF_ADR_RSL). The QZMFSNPA program is shipped withthe system in the QSYS library.

Use of the Preferred Address and Directory Search APIThe QZMFSNPA exit point program uses the Search System Directory(QOKSHCD) API to obtain the preferred address field of each recipient. Thepreferred address field of a directory entry specifies which E-mail addressshould be used to route messages to that recipient. When the QZMFSNPA exitpoint program processes an MSF message, it searches for each of themessage ′s recipients in the directory. QZMFSNPA uses each recipient′saddress value that is specified in the recipient list as the search criteria of theAPI.

When each recipient is found in the directory, its preferred address (addresstype and value) is returned by the directory search API to the QZMFSNPAprogram. If the recipient′s address value in the MSF message does not matchthe recipient′s preferred address, QZMFSNPA changes the MSF message byreplacing the recipient′s address with the preferred address. If the recipient′saddress value in the MSF message does match the recipient′s preferredaddress, QZMFSNPA does not replace the recipient′s address. For moreinformation about preferred addresses, see SNA Distribution Services.

The directory field that is searched is specified by the address type of therecipient in the MSF message. Only one entry that has the matching value for

Copyright IBM Corp. 1995 291

Page 316: AnyMail/400 Mail Server Framework Developer Guide January 1995

that field must be in the directory. Otherwise, there would be multiple recipientsthat have the same address. In this case, the QZMFSNPA exit point program willnot switch the address of the recipient.

MSF is shipped such that the QZMFSNPA exit point program processes everyMSF message recipient in the address resolution exit point, if the message typeof the recipient has not already been set by an earlier program in that exit point.Therefore, an MSF message with a recipient that has an address type notrecognized by any other exit point program in the address resolution exit point isgiven to the QZMFSNPA program. For example, assume an MSF message isreceived for a recipient with an X.400 address of

c=US/admd=ATT/prmd=IBM/o=ROCHESTER/s=DOE

and there is no address resolution program that processes the X.400 address.MSF calls the QZMFSNPA program to process the message. QZMFSNPAsearches the directory for the specified X.400 address and obtains the preferredaddress for the recipient that has that X.400 address. Assume the recipient hasa preferred address of SMTP, and the recipient′s SMTP address is

[email protected]

QZMFSNPA changes the recipient′s address in the MSF message from the X.400address to the SMTP address. The MSF message can then be processed by exitpoint programs for SMTP addresses.

Note: If a recipient′s address is not found in the directory, that recipient′saddress is not processed. This implies that if there are no otherprograms in the address resolution exit point that can process thatrecipient ′s address, the MSF message becomes non-deliverable for thatrecipient.

Figure 88 shows MSF message information for a recipient that has an addresstype of 01A1 (SNADS type) and an address value of ′ Address1′ being given tothe QZMFSNPA exit point program. The QZMFSNPA program uses the SearchSystem Directory (QOKSCHD) API to find the preferred address of the recipient.The preferred address obtained from the directory happens to be of type 01A5(full name) and of value ′ Address2′ . Because these values are different thanthose specified in the MSF message, the MSF message is changed (using theChange Mail Message API) so the recipient now has the preferred address valueof ′ Address2′ .

Figure 88. QZMFSNPA Exit Point Program Switching Addresses

292 AnyMail/400 MSF

Page 317: AnyMail/400 Mail Server Framework Developer Guide January 1995

Switching SMTP Addresses

When the QZMFSNPA program searches for an SMTP address that isspecified in the recipient entry, QZMFSNPA uses resources from the AS/400TCP/IP licensed program. Therefore, you must have the AS/400 TCP/IPlicensed program installed on your system in order for QZMFSNPA to switchan SMTP address to another address.

Use of User-Defined AddressesYou can configure a new address data type in MSF and add a user-defined fieldto the system distribution directory to store this address. When the QZMFSNPAexit point program searches the directory for these addresses, it uses the typename that was specified for the address data type. This type name is used asthe field name in the directory to search. Therefore, the field name in thedirectory must exactly match the type name of the address data type.Otherwise, the QZMFSNPA program will not be able to switch these user-definedaddresses.

Switching User-Defined Addresses

MSF is not able to determine the product ID of a user-defined directory fieldname. Therefore, when the QZMFSNPA program searches for a user-definedaddress in the directory, it uses a product ID value of *NONE.

When creating a user-defined field in the directory, you must use the datatype name as the field name and *NONE as the value of the product ID.

For more information on user-defined directory fields, see “User-DefinedDirectory Fields” on page 279. For more information on data type names, see“MSF Data Types” on page 18. For a list of IBM-defined address data types, seeTable 2 on page 20.

Appendix D. QZMFSNPA Exit Point Program 293

Page 318: AnyMail/400 Mail Server Framework Developer Guide January 1995

Appendix E. An MSF Application — Example

This appendix provides some example programs that illustrate the fundamentalMSF programming concepts described in this publication. These programs canalso serve as prototypes to construct your own mail applications.

The files that contain the source of these example programs can be found on thediskette that is provided with this publication. The files on the diskette are:TESTMSG, TESTTYPE, TCFGTYPE, TCRTMOD, TCRTMSG, TLSTEXPN,TADDRSLN, TRTVMSG, and TRSRVMSG. These files can be transferred to anAS/400 by copying the files to a shared folder and then to a source physical file.TESTMSG and TESTTYPE are header files and are intended to be members offile H.

The following steps describe how the diskette files can be transferred to sourcephysical files on an AS/400:

1. Insert the diskette into a personal computer that has a connection to sharedfolders on the AS/400

2. Use the COPY command (a DOS command) to copy the files from thediskette to documents in a shared folder on the AS/400. For example, youcan use

copy a:*.* i:\samples\*.*

to copy all the files to a folder named ″Samples″ on the AS/400 (the foldermust already exist). Note that i: is the drive letter used to access the sharedfolder.

3. Create the source physical files on the AS/400 where the files wil l be copiedto. For example, you could use the following sequence:

CRTLIB LIB(SAMPLES)CRTSRCPF FILE(SAMPLES/SAMPLEPGMS) TEXT(′ Sample Modules and Programs′ )CRTSRCPF FILE(SAMPLES/H) TEXT(′ Sample Header Files′ )

4. Use the Copy From PC Document (CPYFRMPCD) command to copy the PCdocuments from the shared folder to the source physical files createdpreviously. For example, you could use the following sequence:

CPYFRMPCD FROMFLR(SAMPLES) TOFILE(SAMPLES/H) FROMDOC(TESTMSG)TOMBR(*FROMDOC)

CPYFRMPCD FROMFLR(SAMPLES) TOFILE(SAMPLES/H) FROMDOC(TESTTYPE)TOMBR(*FROMDOC)

CPYFRMPCD FROMFLR(SAMPLES) TOFILE(SAMPLES/SAMPLEPGMS)FROMDOC(TCFGTYPE) TOMBR(*FROMDOC)

CPYFRMPCD FROMFLR(SAMPLES) TOFILE(SAMPLES/SAMPLEPGMS)FROMDOC(TCRTMOD) TOMBR(*FROMDOC)

CPYFRMPCD FROMFLR(SAMPLES) TOFILE(SAMPLES/SAMPLEPGMS)FROMDOC(TCRTMSG) TOMBR(*FROMDOC)

CPYFRMPCD FROMFLR(SAMPLES) TOFILE(SAMPLES/SAMPLEPGMS)FROMDOC(TLSTEXPN) TOMBR(*FROMDOC)

CPYFRMPCD FROMFLR(SAMPLES) TOFILE(SAMPLES/SAMPLEPGMS)FROMDOC(TADDRSLN) TOMBR(*FROMDOC)

294 Copyright IBM Corp. 1995

Page 319: AnyMail/400 Mail Server Framework Developer Guide January 1995

CPYFRMPCD FROMFLR(SAMPLES) TOFILE(SAMPLES/SAMPLEPGMS)FROMDOC(TRTVMSG) TOMBR(*FROMDOC)

CPYFRMPCD FROMFLR(SAMPLES) TOFILE(SAMPLES/SAMPLEPGMS)FROMDOC(TRSRVMSG) TOMBR(*FROMDOC)

Header File ExamplesThe following two header files are needed for the sample programs. We assumethat the header files are placed in a file named H in a library namedQZMFSAMPLE, but you can place the file H in any other suitable library youwant.

Header File Example — TESTTYPEThe first header file, TESTTYPE, contains MSF data type definitions that you canuse to configure your MSF system. These sample MSF data types are intendedfor the sample programs and are for illustration purposes only.

#ifndef _TESTTYPE_H#define _TESTTYPE_H

/*********************************************************************//* *//* Example Header. *//* *//* The header file contains the Test Type definitions used in *//* the example programs. *//* *//* File Name: TESTTYPE *//*********************************************************************/

#define ADDRESS_GROUP ″01″#define MESSAGE_GROUP ″02″#define ENVELOPE_GROUP ″03″#define ATTACHMENT_GROUP ″04″

#define NUM_OF_TEST_MSF_DATA_TYPES 5

#define TEST_ADDRESS_TYPE_VALUE ″01TV″#define TEST_MESSAGE_TYPE_VALUE ″02TV″#define TEST_ENVELOPE_TYPE_VALUE ″03TV″#define TEST_ATTACHMENT_TYPE_VALUE ″04TV″#define TEST_AS400_ATTACH_TYPE_VALUE ″04TA″

#define GET_ENVELOPE_TYPE_VALUE ″03AF″ /* as defined by MSF */

#define TEST_ADDRESS_TYPE_NAME ″01TVNAME″#define TEST_MESSAGE_TYPE_NAME ″02TVNAME″#define TEST_ENVELOPE_TYPE_NAME ″03TVNAME″#define TEST_ATTACHMENT_TYPE_NAME ″04TVNAME″#define TEST_AS400_ATTACH_TYPE_NAME ″04TANAME″

#define TEST_TYPE_TEXT ″TEMP ADDITION FOR MSF CONFIG API TESTING″

#define TYPE_NOT_FOUND ″CPFAFB1″

Appendix E. An MSF Application — Example 295

Page 320: AnyMail/400 Mail Server Framework Developer Guide January 1995

#define USER_SPACE_NAME ″MSFTSTSPACQTEMP ″#define USER_SPACE_SIZE 100 /* arbitrary value */

enum TEST_MSF_Types{

Address_Type = 1, Message_Type = 2, Envelope_Type = 3, Attachment_Ref_Type = 4, AS400_Attach_Ref_Type = 5

};

#endif /* _TESTTYPE_H */

Header File Example — TESTMSGThe second header file, TESTMSG, contains sample definitions for the originator,the recipients, and other data.

#ifndef _TESTMSG_H#define _TESTMSG_H

/*********************************************************************//* *//* Example message API header file. *//* *//* The header file containing the definitions and typedefs for the *//* creation, retrieval, and change of MSF test messages. *//* *//* File Name: TESTMSG *//* *//*********************************************************************/

#define TEST_ORIGINATOR ″MIKE WILLIAMS″

#define TEST_DL ″DEPT44A″

#define TEST_RECIPIENT1 ″MARY RICHARDS″#define TEST_RECIPIENT2 ″JOHN SMITH″#define TEST_RECIPIENT3 ″CHARLES RICE″

#define TEST_GET_SUBJECT ″Team Meeting Notice″

#define TEST_ATTACHMENT ″ /Dept44/DeptA/Group/Agenda.Meeting″

#define TEST_SPIN1 ″MARY RICHARDS: ROCHESTER Machine″#define TEST_SPIN2 ″JOHN SMITH: ROCHESTER Machine″#define TEST_SPIN3 ″CHARLES RICE: NEWYORK Machine″

#define AS400_NAME_SIZE 10#define TEST_AS400_LIBRARY ″MSFTESTLIB″#define TEST_AS400_FILE ″MSFTESTFLE″#define TEST_AS400_MEMBER ″MSFTESTMBR″

#define NULL_MSG_TYPE ″ ″#define NULL_RCPT_STATUS 0

296 AnyMail/400 MSF

Page 321: AnyMail/400 Mail Server Framework Developer Guide January 1995

#define DEFAULT_CCSID 500

#define WORK_SPACE_NAME ″MSFWORKSPCQTEMP ″#define WORK_SPACE_SIZE 1024 /* Rough Estimate */#define AUTO_EXTEND_INDCTR -1 /* Indication to the Retrieve */

/* Msg API about the *//* auto-extendibility of the *//* passed user space */

enum Msg_Attribute_Types{

Originator = 0, Envelope = 1, Recipient = 2, Attachment = 3

};

/*******************************************************************//* The following typedef corresponds to an Attachment Reference *//* type corresponding to an AS/400 file. *//*******************************************************************/

typedef struct{

char Library_Name[AS400_NAME_SIZE];char File_Name[AS400_NAME_SIZE];char Member_Name[AS400_NAME_SIZE];

} AS400_File_Attachment_t;

#endif /* _TESTMSG_H */

Type Configuration Program — ExampleThe program TCFGTYPE adds the five test MSF data types that are defined in theheader file TESTTYPE to your MSF static configuration. This program must berun before the other sample programs, and MSF must be restarted for thechanges to take effect.

The program consists of a single module. To create this program, follow thesteps in “Creating a Module and Program in ILE C/400 — Example” on page 199.

/*********************************************************************//* *//* Example: MSF Configuration APIs *//* Deletion, Addition, and Retrieval of MSF data types. *//* *//* File Name: TCFGTYPE *//* *//* *//*********************************************************************/

#pragma strings(readonly)

#include <stdio.h>#include <string.h>#include <stdlib.h>

Appendix E. An MSF Application — Example 297

Page 322: AnyMail/400 Mail Server Framework Developer Guide January 1995

#include <except.h>#include <pointer.h>

#include <quscrtus.h>#include <qusptrus.h>#include <qusdltus.h>#include <qusgen.h>#include <qusec.h>#include <qmhchgem.h>

#include <qzmfasrv.h> /* contains MSF API prototypes */

#include ″testtype.h″

typedef struct{ Qus_EC_t Error; char Exception_Data[1];} Error_Code_t; /* We will expect exceptions to be */

/* signalled and not care about *//* the returned codes */

/*--------------------------------------------------------------------*//* file-scoped variables *//*--------------------------------------------------------------------*/

static Qzmf_DLTC0100_tDelete_Type_Param;

static Qzmf_ADDC0100_tAdd_Type_Param;

static Qzmf_LSTC0100_tSelect_Type_Param;

static Error_Code_tApi_Error_Code;

static _SPCPTRConfig_Space_Ptr;

static short intindx;

static char*Seperator =

″==================================================================″;

/*--------------------------------------------------------------------*//* file-scoped functions *//*--------------------------------------------------------------------*

298 AnyMail/400 MSF

Page 323: AnyMail/400 Mail Server Framework Developer Guide January 1995

static void Quit_Execution(void

);

static void Handle_Type_Not_Found(_INTRPT_Hndlr_Parms_T*

);

static void Fill_Delete_Type_Param(Qzmf_DLTC0100_t*

, short int);

static void Fill_Add_Type_Param(Qzmf_ADDC0100_t*

, short int);

static void Print_Type_Tuples(Qus_Generic_Header_0300_t*

);

/*--------------------------------------------------------------------*//* Executable code *//*--------------------------------------------------------------------*/

/**********************************************************************//* General exception handler function. The program ends *//* prematurely after printing a general error statement. *//**********************************************************************/

static void Quit_Execution(void

){

printf(″Unexpected CPFxxxx exception from API invocation; ″″quitting\n″ ) ;

/****************************************************************//* For simplicity we are not attempting to destroy the QTEMP *//* user space. It remains until the end of the invoking *//* interactive job. For permanent spaces and for your *//* applications, you should have code to delete the work spaces *//* in relevant exception handlers. *//****************************************************************/exit(1);

} /* end of Quit_Execution Exception Handler */

/**********************************************************************/

/**********************************************************************//* An exception handler function. If the ″Type_Not_Found″ = CPFAFB1 *//* exception is passed to this exception handler, it is handled and *//* removed from the job log. All other exceptions cause the program */

Appendix E. An MSF Application — Example 299

Page 324: AnyMail/400 Mail Server Framework Developer Guide January 1995

/* to end prematurely. *//**********************************************************************/

static void Handle_Type_Not_Found(_INTRPT_Hndlr_Parms_T *Excp_InfoP

){

Error_Code_tError_Code;

/* The following variable indicates whether the exception message *//* should be removed from the job log. */short int

Remove_Message = !memcmp(Excp_InfoP -> Msg_Id,TYPE_NOT_FOUND, 7)

;

Error_Code.Error.Bytes_Provided = 0;

if (Remove_Message)

/* Remove the exception from job log and mark the exception as *//* handled for continuation of further processing. */QMHCHGEM(

&(Excp_InfoP -> Target), 0, (char *)&(Excp_InfoP -> Msg_Ref_Key), ″*REMOVE ″, ″″, 0, (void *)&Error_Code

);else /* Quit Processing */{

printf(″Unexpected CPFxxxx exception from API invocation; ″″quitting\n″ ) ;

exit(1);}

} /* end of Handle_Type_Not_Found exception handler */

/**********************************************************************/

/**********************************************************************//* The following function fills the Remove-Type-Configuration *//* parameter (the DLTC0100 structure for the five different *//* test MSF data types). *//**********************************************************************/

static void Fill_Delete_Type_Param(Qzmf_DLTC0100_t

*Delete_Type_ParamP, short int Type_Indx

){

switch (Type_Indx){

300 AnyMail/400 MSF

Page 325: AnyMail/400 Mail Server Framework Developer Guide January 1995

case Address_Type:memcpy( (Delete_Type_ParamP -> Type_Group), ADDRESS_GROUP,

sizeof(Qzmf_Type_Group_t) );memcpy( (Delete_Type_ParamP -> Type_Value),

TEST_ADDRESS_TYPE_VALUE, sizeof(Qzmf_Type_Value_t) );memcpy( (Delete_Type_ParamP -> Type_Name),

TEST_ADDRESS_TYPE_NAME, sizeof(Qzmf_Type_Name_t) );break;

case Message_Type:memcpy( (Delete_Type_ParamP -> Type_Group), MESSAGE_GROUP,

sizeof(Qzmf_Type_Group_t) );memcpy( (Delete_Type_ParamP -> Type_Value),

TEST_MESSAGE_TYPE_VALUE, sizeof(Qzmf_Type_Value_t) );memcpy( (Delete_Type_ParamP -> Type_Name),

TEST_MESSAGE_TYPE_NAME, sizeof(Qzmf_Type_Name_t) );break;

case Envelope_Type:memcpy( (Delete_Type_ParamP -> Type_Group),

ENVELOPE_GROUP, sizeof(Qzmf_Type_Group_t) );memcpy( (Delete_Type_ParamP -> Type_Value),

TEST_ENVELOPE_TYPE_VALUE, sizeof(Qzmf_Type_Value_t) );memcpy( (Delete_Type_ParamP -> Type_Name),

TEST_ENVELOPE_TYPE_NAME, sizeof(Qzmf_Type_Name_t) );break;

case Attachment_Ref_Type:memcpy( (Delete_Type_ParamP -> Type_Group),

ATTACHMENT_GROUP, sizeof(Qzmf_Type_Group_t) );memcpy( (Delete_Type_ParamP -> Type_Value),

TEST_ATTACHMENT_TYPE_VALUE, sizeof(Qzmf_Type_Value_t) );memcpy( (Delete_Type_ParamP -> Type_Name),

TEST_ATTACHMENT_TYPE_NAME, sizeof(Qzmf_Type_Name_t) );break;

case AS400_Attach_Ref_Type:memcpy( (Delete_Type_ParamP -> Type_Group),

ATTACHMENT_GROUP, sizeof(Qzmf_Type_Group_t) );memcpy( (Delete_Type_ParamP -> Type_Value),

TEST_AS400_ATTACH_TYPE_VALUE, sizeof(Qzmf_Type_Value_t) );memcpy( (Delete_Type_ParamP -> Type_Name),

TEST_AS400_ATTACH_TYPE_NAME, sizeof(Qzmf_Type_Name_t) );break;

default:break;

} /* end of switch on Type_Indx */

} /* end of Fill_Delete_Type_Param function */

/**********************************************************************/

/**********************************************************************//* The following function fills the Add-Type-Configuration *//* parameter (the ADDC0100 structure for all the different */

Appendix E. An MSF Application — Example 301

Page 326: AnyMail/400 Mail Server Framework Developer Guide January 1995

/* test MSF data types). *//**********************************************************************/

static void Fill_Add_Type_Param(Qzmf_ADDC0100_t *Add_Type_ParamP

, short int Type_Indx)

{memset( (Add_Type_ParamP -> Type_Text), ′ ′ , 100);

switch (Type_Indx){

case Address_Type:memcpy( (Add_Type_ParamP -> Type_Group), ADDRESS_GROUP,

sizeof(Qzmf_Type_Group_t) );memcpy( (Add_Type_ParamP -> Type_Value),

TEST_ADDRESS_TYPE_VALUE, sizeof(Qzmf_Type_Value_t) );memcpy( (Add_Type_ParamP -> Type_Name),

TEST_ADDRESS_TYPE_NAME, sizeof(Qzmf_Type_Name_t) );memcpy( (Add_Type_ParamP -> Type_Text), TEST_TYPE_TEXT,

strlen(TEST_TYPE_TEXT) );break;

case Message_Type:memcpy( (Add_Type_ParamP -> Type_Group), MESSAGE_GROUP,

sizeof(Qzmf_Type_Group_t) );memcpy( (Add_Type_ParamP -> Type_Value),

TEST_MESSAGE_TYPE_VALUE, sizeof(Qzmf_Type_Value_t) );memcpy( (Add_Type_ParamP -> Type_Name),

TEST_MESSAGE_TYPE_NAME, sizeof(Qzmf_Type_Name_t) );memcpy( (Add_Type_ParamP -> Type_Text), TEST_TYPE_TEXT,

strlen(TEST_TYPE_TEXT) );break;

case Envelope_Type:memcpy( (Add_Type_ParamP -> Type_Group), ENVELOPE_GROUP,

sizeof(Qzmf_Type_Group_t) );memcpy( (Add_Type_ParamP -> Type_Value),

TEST_ENVELOPE_TYPE_VALUE, sizeof(Qzmf_Type_Value_t) );memcpy( (Add_Type_ParamP -> Type_Name),

TEST_ENVELOPE_TYPE_NAME, sizeof(Qzmf_Type_Name_t) );memcpy( (Add_Type_ParamP -> Type_Text), TEST_TYPE_TEXT,

strlen(TEST_TYPE_TEXT) );break;

case Attachment_Ref_Type:memcpy( (Add_Type_ParamP -> Type_Group), ATTACHMENT_GROUP,

sizeof(Qzmf_Type_Group_t) );memcpy( (Add_Type_ParamP -> Type_Value),

TEST_ATTACHMENT_TYPE_VALUE, sizeof(Qzmf_Type_Value_t) );memcpy( (Add_Type_ParamP -> Type_Name),

TEST_ATTACHMENT_TYPE_NAME, sizeof(Qzmf_Type_Name_t) );memcpy( (Add_Type_ParamP -> Type_Text), TEST_TYPE_TEXT,

strlen(TEST_TYPE_TEXT) );break;

case AS400_Attach_Ref_Type:memcpy( (Add_Type_ParamP -> Type_Group), ATTACHMENT_GROUP,

sizeof(Qzmf_Type_Group_t) );

302 AnyMail/400 MSF

Page 327: AnyMail/400 Mail Server Framework Developer Guide January 1995

memcpy( (Add_Type_ParamP -> Type_Value),TEST_AS400_ATTACH_TYPE_VALUE, sizeof(Qzmf_Type_Value_t) );

memcpy( (Add_Type_ParamP -> Type_Name),TEST_AS400_ATTACH_TYPE_NAME, sizeof(Qzmf_Type_Name_t) );

memcpy( (Add_Type_ParamP -> Type_Text), TEST_TYPE_TEXT,strlen(TEST_TYPE_TEXT) );

break;

default:break;

} /* end of switch on Type_Indx */

} /* end of Fill_Add_Type_Param function */

/**********************************************************************/

/**********************************************************************//* Print-Type-Tuples prints all the MSF data types returned in the *//* passed user space by the List MSF Configuration API. *//**********************************************************************/

static void Print_Type_Tuples(Qus_Generic_Header_0300_t

*Config_Space_HdrP)

{Qzmf_LSTL0100_t

*Type_TupleP;

short intNum_Of_Entries =

Config_Space_HdrP -> Number_List_Entries, Entry_Size = Config_Space_HdrP -> Size_Each_Entry, indx = 1;

if (Num_Of_Entries){

/* Set the Type_Tuple pointer to the beginning of the list *//* of type tuples */Type_TupleP = (Qzmf_LSTL0100_t *)

( (char *)Config_Space_HdrP +Config_Space_HdrP -> Offset_List_Data );

while (indx <= Num_Of_Entries){

printf(″Type Group: %.2s, Type Value: %.4s, Type Name: %.8s\n″ ,Type_TupleP -> Type_Group, Type_TupleP -> Type_Value,Type_TupleP -> Type_Name);

printf(″Type Text: %.100s\n″ , Type_TupleP -> Type_Text);

/* Advance Type_TupleP to the next Tuple */Type_TupleP = (Qzmf_LSTL0100_t *)

( (char *)Type_TupleP + Entry_Size);++indx;

} /* end of loop over all the returned Type-Tuples */

Appendix E. An MSF Application — Example 303

Page 328: AnyMail/400 Mail Server Framework Developer Guide January 1995

} /* end of non-zero num of returned type tuples */else

printf(″No Type Tuples are returned meeting the list ″″requirement\n″ ) ;

} /* end of Print_Type_Tuples function */

/**********************************************************************/

/**********************************************************************//**********************************************************************//**************** main ****************************************//**********************************************************************//**********************************************************************/

void main(void){

/* Specify exceptions should be signalled from all the OS/400 *//* system APIs rather than using return codes. */Api_Error_Code.Error.Bytes_Provided = 0;

/*******************************************************************//* First, clear all the test data types from the MSF *//* configuration. Normally, these test data types are not *//* present. But in case any previous run of the test program *//* has left the test data types configured, this step deletes them.*//* *//* If the test data types are not present, the Remove MSF *//* Configuration API gives the CPFAFB1 = TYPE_NOT_FOUND *//* exception (which this test program handles). *//*******************************************************************/

/* Fill the variable length component of Delete_Type_Param */Delete_Type_Param.Param_List_Length = sizeof(Qzmf_DLTC0100_t);

indx = 1;while (indx <= NUM_OF_TEST_MSF_DATA_TYPES){

Fill_Delete_Type_Param(&Delete_Type_Param

, indx);

#pragma exception_handler(Handle_Type_Not_Found, 0, 0,\_C2_MH_ESCAPE)

QzmfRmvMailCfg((void *)&Delete_Type_Param

, QZMF_DEL_CONFIG_FORMAT, (void *)&Api_Error_Code

);

#pragma disable_handler

++indx;}

304 AnyMail/400 MSF

Page 329: AnyMail/400 Mail Server Framework Developer Guide January 1995

/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*//* For deleting the added test data types, the following exit *//* statement can be uncommented before creating the test type *//* cleanup program. *//* *//* exit(0); *//* *//*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/

/*******************************************************************//* Set up a user space for invoking the List MSF Configuration *//* API. This creates the user space in the QTEMP library where *//* the scope is limited to the scope of the job running this *//* particular program. For more permanent spaces that can be *//* accessed from other jobs, use some other library. *//* *//* There is no need to specify the exact size of the space needed. *//* The MSF List Configuration API extends the space when *//* necessary. *//*******************************************************************/

#pragma exception_handler(Quit_Execution, 0, 0, _C2_MH_ESCAPE)

QUSCRTUS(USER_SPACE_NAME

, ″ ″, USER_SPACE_SIZE, ″\0″, ″*ALL ″, ″MSF Type API Test User Space″, ″*YES ″, (void *)&Api_Error_Code, ″*USER ″

);

#pragma disable_handler

/******************************************************************//* Set the space pointer to the user space just mentioned. *//* The pointer is needed for accessing the contents of the space *//* after a call to the List MSF Configuration API. *//******************************************************************/

#pragma exception_handler(Quit_Execution, 0, 0, _C2_MH_ESCAPE)

QUSPTRUS(USER_SPACE_NAME

, &Config_Space_Ptr, (void *)&Api_Error_Code

);

#pragma disable_handler

/* Now, retrieve all the configured attachment reference types */

/* Fill the variable length portion of the Select_Type_Param */

Appendix E. An MSF Application — Example 305

Page 330: AnyMail/400 Mail Server Framework Developer Guide January 1995

Select_Type_Param.Sel_List_Length = sizeof(Qzmf_LSTC0100_t);

/* Fill the remaining components of Select_Type_Param */memcpy( Select_Type_Param.Type_Group, ATTACHMENT_GROUP,

sizeof(Qzmf_Type_Group_t) );memset( Select_Type_Param.Type_Value, ′ ′ ,

sizeof(Qzmf_Type_Value_t) );memset( Select_Type_Param.Type_Name, ′ ′ ,

sizeof(Qzmf_Type_Name_t) );

/* Invoke the List MSF Configuration API */#pragma exception_handler(Quit_Execution, 0, 0, _C2_MH_ESCAPE)

QzmfLstMailCfg((void*)(USER_SPACE_NAME)

, QZMF_LST_RECEIVER_FORMAT, QZMF_LST_SELECTION_FORMAT, (void *)&Select_Type_Param, (void *)&Api_Error_Code

);

#pragma disable_handler

printf(″Following are all the MSF attachment types before ″″Test Type Additions:\n%s\n″ , Seperator);

/* Print all the returned Type-Tuples */Print_Type_Tuples(

(Qus_Generic_Header_0300_t *)Config_Space_Ptr

);

/* Now, we add the five data types to the MSF Configuration. */

/* Fill up the variables of the Add_Type_Param structure */Add_Type_Param.Param_List_Length = sizeof(Qzmf_ADDC0100_t);memset(Add_Type_Param.Reserved, ′ ′ , 2 ) ;Add_Type_Param.CCSID = 0;

indx = 1;while (indx <= NUM_OF_TEST_MSF_DATA_TYPES){

Fill_Add_Type_Param(&Add_Type_Param

, indx);

#pragma exception_handler(Quit_Execution, 0, 0, _C2_MH_ESCAPE)

QzmfAddMailCfg((void *)&Add_Type_Param

, QZMF_ADD_CONFIG_FORMAT, (void *)&Api_Error_Code

);

#pragma disable_handler

++indx;}

306 AnyMail/400 MSF

Page 331: AnyMail/400 Mail Server Framework Developer Guide January 1995

/******************************************************************//* Again, call the List MSF Configuration API to list all the *//* attachment reference types. The selection parameter has *//* already been filled before the previous invocation. *//******************************************************************/

#pragma exception_handler(Quit_Execution, 0, 0, _C2_MH_ESCAPE)

QzmfLstMailCfg((void*)(USER_SPACE_NAME)

, QZMF_LST_RECEIVER_FORMAT, QZMF_LST_SELECTION_FORMAT, (void *)&Select_Type_Param, (void *)&Api_Error_Code

);

#pragma disable_handler

printf(″Following are all the MSF attachment types after Test ″″Type Additions:\n%s\n″ , Seperator);

/* Print all the returned Type-Tuples */Print_Type_Tuples(

(Qus_Generic_Header_0300_t *)Config_Space_Ptr

);

/* Delete the configuration user space */#pragma exception_handler(Quit_Execution, 0, 0, _C2_MH_ESCAPE)

QUSDLTUS(USER_SPACE_NAME

, &Api_Error_Code);

#pragma disable_handler

exit(0);

} /* end of main */

/**********************************************************************//************ end of file TCFGTYPE *********************************//**********************************************************************/

Results from the TCFGTYPE ProgramWhen the TCFGTYPE program successfully runs, something similar to thefollowing should appear on your display:

Following are all the MSF attachment types before Test Type Additions:==================================================================Type Group: 04, Type Value: 04A1, Type Name: RTGFSType Text: SNADS general file server attachment reference type.

. . <All other 04 data type groups of your system> .

Appendix E. An MSF Application — Example 307

Page 332: AnyMail/400 Mail Server Framework Developer Guide January 1995

Following are all the MSF attachment types after Test Type Additions:==================================================================Type Group: 04, Type Value: 04A1, Type Name: RTGFSType Text: SNADS general file server attachment reference type.

. . <Other 04 data type groups of your system> .

Type Group: 04, Type Value: 04TA, Type Name: 04TANAMEType Text: TEMP ADDITION FOR MSF CONFIG API TESTING

Type Group: 04, Type Value: 04TV, Type Name: 04TVNAMEType Text: TEMP ADDITION FOR MSF CONFIG API TESTING

. . <Remaining 04 type groups of your system> .

Press ENTER to end terminal session.

Module and Program to Create MSF Messages — ExampleThe following file, TCRTMOD, can be used as the source to compile a modulethat contains two main functions for creating normal and reserved MSFmessages. This module will be used to create two MSF programs. This modulecan be used to create MSF messages that contain the test data types fields ofthe header file under the topic “Header File Examples” on page 295.

/*********************************************************************//* *//* Example: create MSF message module *//* *//* File Name: TCRTMOD *//* *//*********************************************************************/

#pragma strings(readonly)

#include <stdio.h>#include <string.h>#include <stdlib.h>

#include <except.h>#include <pointer.h>

#include <qusec.h>

#include <qzmfasrv.h>

#include ″testtype.h″#include ″testmsg.h″

#define NUM_CRT_ATTRBT 4 /* We will create messages with *//* four attributes */

308 AnyMail/400 MSF

Page 333: AnyMail/400 Mail Server Framework Developer Guide January 1995

typedef struct{ Qus_EC_t Error; char Exception_Data[1];} Error_Code_t; /* We will expect exceptions to be */

/* signalled and not care about *//* the returned codes */

/*--------------------------------------------------------------------*//* File-scoped variables *//*--------------------------------------------------------------------*/

static Qzmf_Msg_Desc_Hdr0100_t*List_HdrP;

static Qzmf_Msg_Desc_Attrbt_Entity_tMsg_Desc_Attr_Array[NUM_CRT_ATTRBT];

static Error_Code_tCrt_Error_Code;

static char*WalkP;

/*--------------------------------------------------------------------*//* File-scoped functions *//*--------------------------------------------------------------------*

static void Quit_Execution(void

);

static void Create_Originator_Descriptor(void

);

static void Create_Envelope_Descriptor(void

);

static void Create_Recipient_Descriptor(void

);

static void Create_Attachment_Descriptor(void

);

/*-------------------------------------------------------------------*//* Exported functions from this module *//*-------------------------------------------------------------------*/

void Create_A_Message(Qzmf_Msg_Id_t

Appendix E. An MSF Application — Example 309

Page 334: AnyMail/400 Mail Server Framework Developer Guide January 1995

);

void Create_A_Reserved_Message(Qzmf_Msg_Id_t

);

/*--------------------------------------------------------------------*//* Executable code *//*--------------------------------------------------------------------*/

/**********************************************************************//* General exception handler function. The program ends *//* prematurely after it prints a general error statement. *//**********************************************************************/

static void Quit_Execution(void

){

printf(″Unexpected CPFxxxx exception from MSF Create Message ″″API invocation; quitting\n″ ) ;

exit(1);} /* end of Quit_Execution Exception Handler */

/**********************************************************************/

/**********************************************************************//* Create_Originator_Descriptor function creates our originator *//* list, and places the relevant originator list information in the *//* message descriptor attribute array. *//**********************************************************************/

static void Create_Originator_Descriptor(void

){

intOriginator_Length = strlen(TEST_ORIGINATOR)

, Org_Size = sizeof(Qzmf_Msg_Desc_Hdr0100_t) + /* The size of */sizeof(Qzmf_ORGL0100_t) + /* orginator */Originator_Length /* list */

;

Qzmf_ORGL0100_t*OrgP;

/* Allocate space from heap for the originator list */WalkP = (char *)malloc(Org_Size);

if (WalkP == NULL){

printf(″Quitting, malloc error in creating ORGL\n″ ) ;exit(1);

}

310 AnyMail/400 MSF

Page 335: AnyMail/400 Mail Server Framework Developer Guide January 1995

/* Fill the proper message descriptor array element for the *//* originator list to be created */(Msg_Desc_Attr_Array + Originator) -> Msg_Desc_Ptr =

(_SPCPTR)(WalkP);(Msg_Desc_Attr_Array + Originator) -> Msg_Desc_Length = Org_Size;memcpy( (Msg_Desc_Attr_Array + Originator) -> Msg_Desc_Format_Name,

QZMF_ORIGINATOR_LIST_FMT, QZMF_MSG_DESC_FMT_LENGTH );(Msg_Desc_Attr_Array + Originator) -> Reserved = 0;

/* Now, fill the originator list header. */

/* First cast the walk pointer as a msg. descriptor header pointer */List_HdrP = (Qzmf_Msg_Desc_Hdr0100_t *)WalkP;

List_HdrP -> Msg_Desc_Total_Length = Org_Size;List_HdrP -> Bytes_Available = 0;memcpy( List_HdrP -> Msg_Desc_Format_Name, QZMF_ORIGINATOR_LIST_FMT,

QZMF_MSG_DESC_FMT_LENGTH );List_HdrP -> First_Entry_Offset = sizeof(Qzmf_Msg_Desc_Hdr0100_t);List_HdrP -> Total_Num_Of_Entries = 1; /* We have only one Originator */List_HdrP -> Reserved = 0;

/* Next, fill the single entry originator list */

/* Set up OrgP just beyond the originator list header */OrgP = (Qzmf_ORGL0100_t *)(List_HdrP + 1);

OrgP -> Entry_Length = sizeof(Qzmf_ORGL0100_t) + Originator_Length;OrgP -> Displacement = sizeof(Qzmf_ORGL0100_t);OrgP -> Addr_Length = Originator_Length;memcpy( OrgP -> Addr_Type, TEST_ADDRESS_TYPE_VALUE,

sizeof(Qzmf_Type_Value_t) );OrgP -> CCSID = DEFAULT_CCSID;OrgP -> Unique_Id = 0;OrgP -> Ref_Unique_Id = 0;OrgP -> Reserved = 0;

/*************************************************************//* Now insert the actual originator name in the list. *//* Set a walk pointer (WalkP) just beyond the portion *//* of the originator list that is created so far. *//* *//* If your originator has an internal structure rather than *//* a simple character string, you may declare a pointer and *//* cast WalkP to your originator type. General examples of *//* this nature can be found in the Create_Envelope_Descriptor*//* function where an IBM GET envelope is placed in an *//* envelope list entry and in the *//* Create_Attachment_Descriptor function where an AS400 file *//* attachment reference list entry is created. *//*************************************************************/WalkP = (char *)(OrgP + 1);memcpy( WalkP, TEST_ORIGINATOR, Originator_Length );

} /* end of Create_Originator_Descriptor function */

/**********************************************************************/

Appendix E. An MSF Application — Example 311

Page 336: AnyMail/400 Mail Server Framework Developer Guide January 1995

/**********************************************************************//* Create_Envelope_Descriptor function creates our envelope list *//* that contains our GET envelope as the only entry. The *//* function also places the relevant envelope list information in the *//* message descriptor attribute array. *//**********************************************************************/

static void Create_Envelope_Descriptor(void

){

/*****************************************************************//* Create a single GET envelope that contains only three *//* attributes: subject, sensitivity, and priority. *//*****************************************************************/

intEnvelope_Length = sizeof(Qzmf_GET_t) +

2 * QZMF_GET_INT_ATTRIBUTE_LENGTH +sizeof(Qzmf_GET_Subject_Attrbt_t) +strlen(TEST_GET_SUBJECT)

, Env_Size = sizeof(Qzmf_Msg_Desc_Hdr0100_t) +sizeof(Qzmf_ENVL0100_t) +Envelope_Length

, Temp_Subject_Length = strlen(TEST_GET_SUBJECT);

Qzmf_ENVL0100_t*EnvP;

Qzmf_GET_t*GETP;

Qzmf_GET_Int_Attrbt_t*GET_IntP;

Qzmf_GET_Subject_Attrbt_t*GET_SubjectP;

/* Allocate sufficient amount of space for the envelope descriptor */WalkP = (char *)malloc( Env_Size);

if (WalkP == NULL){

printf(″Quitting, malloc error in creating ENVL\n″ ) ;exit(1);

}

/* Fill the proper message descriptor array element for the *//* envelope list to be created */(Msg_Desc_Attr_Array + Envelope) -> Msg_Desc_Ptr = (_SPCPTR)(WalkP);(Msg_Desc_Attr_Array + Envelope) -> Msg_Desc_Length = Env_Size;

312 AnyMail/400 MSF

Page 337: AnyMail/400 Mail Server Framework Developer Guide January 1995

memcpy( (Msg_Desc_Attr_Array + Envelope) -> Msg_Desc_Format_Name,QZMF_ENVELOPE_LIST_FMT, QZMF_MSG_DESC_FMT_LENGTH );

(Msg_Desc_Attr_Array + Envelope) -> Reserved = 0;

/* Next, fill the header of the envelope list */List_HdrP = (Qzmf_Msg_Desc_Hdr0100_t *)WalkP;

List_HdrP -> Msg_Desc_Total_Length = Env_Size;List_HdrP -> Bytes_Available = 0;memcpy( List_HdrP -> Msg_Desc_Format_Name, QZMF_ENVELOPE_LIST_FMT,

QZMF_MSG_DESC_FMT_LENGTH );List_HdrP -> First_Entry_Offset = sizeof(Qzmf_Msg_Desc_Hdr0100_t);List_HdrP -> Total_Num_Of_Entries = 1;List_HdrP -> Reserved = 0;

/* As the final step, create the single entry envelope list *//* after setting up EnvP just beyond the envelope list header*//* constructed above. */EnvP = (Qzmf_ENVL0100_t *)(List_HdrP + 1);

EnvP -> Entry_Length = sizeof(Qzmf_ENVL0100_t) + Envelope_Length;EnvP -> Displacement = sizeof(Qzmf_ENVL0100_t);EnvP -> Envelope_Length = Envelope_Length;memcpy( EnvP -> Envelope_Type, GET_ENVELOPE_TYPE_VALUE,

sizeof(Qzmf_Type_Value_t) );EnvP -> Unique_Id = 0;EnvP -> Ref_Unique_Id = 0;EnvP -> Reserved = 0;

/* Finally, create and insert the actual GET envelope in the list */

/* Advance the walk pointer */WalkP = (char *)(EnvP + 1);

/* Create the sample GET */GETP = (Qzmf_GET_t *)WalkP;GETP -> GET_Length = Envelope_Length;GETP -> First_Attribute_Offset = sizeof(Qzmf_GET_t);GETP -> Num_Of_Attributes = 3;

/* Advance the walk pointer */WalkP = (char *)(GETP + 1);

/*****************************************************************//* Now, fill all three GET attributes. In this *//* example, we linearly advance the Walkp walk *//* pointer and cast it to the relevant types of attribute *//* pointers. In more general instances, you can set up a loop. *//*****************************************************************/

/*****************************************************************//* First, fill the two integer-valued attributes. *//* The GET attributes can appear in any order. There is no *//* requirement for how the various attributes are to be arranged.*//*****************************************************************/

GET_IntP = (Qzmf_GET_Int_Attrbt_t *)WalkP;GET_IntP -> Attribute_Length = QZMF_GET_INT_ATTRIBUTE_LENGTH;GET_IntP -> Attribute_Id = Qzmf_GET_Priority_Type_Id;

Appendix E. An MSF Application — Example 313

Page 338: AnyMail/400 Mail Server Framework Developer Guide January 1995

(GET_IntP -> Qzmf_GET_Int_Attrbt_Info).GET_Priority_Info =Qzmf_Normal_Priority;

/* Advance the walk pointer and fill the Sensitivity attribute */WalkP = (char *)(GET_IntP + 1);

GET_IntP = (Qzmf_GET_Int_Attrbt_t *)WalkP;GET_IntP -> Attribute_Length = QZMF_GET_INT_ATTRIBUTE_LENGTH;GET_IntP -> Attribute_Id = Qzmf_GET_Sensitivity_Type_Id;(GET_IntP -> Qzmf_GET_Int_Attrbt_Info).GET_Sensitivity_Info =

Qzmf_Not_Sensitive;

WalkP = (char *)(GET_IntP + 1);

/* Now fill the Subject attribute */GET_SubjectP = (Qzmf_GET_Subject_Attrbt_t *)WalkP;GET_SubjectP -> Attribute_Length =

sizeof(Qzmf_GET_Subject_Attrbt_t) +Temp_Subject_Length;

GET_SubjectP -> Attribute_Id = Qzmf_GET_Subject_Id;GET_SubjectP -> CCSID = DEFAULT_CCSID;GET_SubjectP -> Subject_Length = Temp_Subject_Length;

WalkP = (char *)(GET_SubjectP + 1);memcpy(WalkP, TEST_GET_SUBJECT, Temp_Subject_Length);

} /* end of Create_Envelope_Descriptor function */

/**********************************************************************/

/**********************************************************************//* The Create_Recipient_Descriptor function creates our recipient *//* list that contains the test distribution list. It also places the *//* relevant recipient list information in the message descriptor *//* attribute array. *//**********************************************************************/

static void Create_Recipient_Descriptor(void

){

intRecipient_Length = strlen(TEST_DL)

, Rcpnt_Size = sizeof(Qzmf_Msg_Desc_Hdr0100_t) + /* No SPIN is */sizeof(Qzmf_RCPL0100_t) + /* present */Recipient_Length /* during Msg */

; /* creation */

Qzmf_RCPL0100_t*RcpntP;

/****************************************************************//* Allocate space for the recipient descriptor. We are not *//* considering SPIN at this moment of message creation. SPIN *//* can be optionally placed by exit point programs in the */

314 AnyMail/400 MSF

Page 339: AnyMail/400 Mail Server Framework Developer Guide January 1995

/* descriptor elements. However, the message creator can also *//* specify SPIN if it is necessary for any particular *//* application. MSF is flexible enough to allow SPIN *//* during message creation. *//****************************************************************/

WalkP = (char *)malloc( Rcpnt_Size);

if (WalkP == NULL){

printf(″Quitting, malloc error in creating RCPL\n″ ) ;exit(1);

}

/* Fill the proper message descriptor array element for the *//* recipient list to be created. */(Msg_Desc_Attr_Array + Recipient) -> Msg_Desc_Ptr = (_SPCPTR)(WalkP);(Msg_Desc_Attr_Array + Recipient)-> Msg_Desc_Length = Rcpnt_Size;memcpy( (Msg_Desc_Attr_Array + Recipient) -> Msg_Desc_Format_Name,

QZMF_RECIPIENT_LIST_FMT, QZMF_MSG_DESC_FMT_LENGTH );(Msg_Desc_Attr_Array + Recipient) -> Reserved = 0;

/* Next fill the header of the recipient list */List_HdrP = (Qzmf_Msg_Desc_Hdr0100_t *)WalkP;

List_HdrP -> Msg_Desc_Total_Length = Rcpnt_Size;List_HdrP -> Bytes_Available = 0;memcpy( List_HdrP -> Msg_Desc_Format_Name,QZMF_RECIPIENT_LIST_FMT,

QZMF_MSG_DESC_FMT_LENGTH );List_HdrP -> First_Entry_Offset = sizeof(Qzmf_Msg_Desc_Hdr0100_t);List_HdrP -> Total_Num_Of_Entries = 1;List_HdrP -> Reserved = 0;

/* As the final step, create the single-entry recipient list *//* consisting of a distribution list name. */RcpntP = (Qzmf_RCPL0100_t *)(List_HdrP + 1);

RcpntP -> Entry_Length = sizeof(Qzmf_RCPL0100_t) +Recipient_Length;

RcpntP -> SPIN_Displacement = 0; /* Since there is no SPIN the *//* Disp, should be set to 0 */

RcpntP -> SPIN_Length = 0;RcpntP -> Recipient_Displacement = sizeof(Qzmf_RCPL0100_t);RcpntP -> Addr_Length = Recipient_Length;memcpy( RcpntP -> Addr_Type, TEST_ADDRESS_TYPE_VALUE,

sizeof(Qzmf_Type_Value_t) );RcpntP -> CCSID = DEFAULT_CCSID;RcpntP -> Reason_Code = 0;RcpntP -> Diag_Code = 0;

/*********************************************************//* During the creation of the message, set the *//* following two fields to ZERO values. In a typical *//* application, these two fields are set to proper *//* values by the exit point program at the address *//* resolution exit point. *//*********************************************************/

Appendix E. An MSF Application — Example 315

Page 340: AnyMail/400 Mail Server Framework Developer Guide January 1995

memcpy( RcpntP -> Msg_Type, NULL_MSG_TYPE,sizeof(Qzmf_Type_Value_t) );

RcpntP -> Status = NULL_RCPT_STATUS;

RcpntP -> Dist_Type = QZMF_DIST_TYPE_NORMAL; /* Normal Dist. Type *//* assumed */

RcpntP -> Unique_Id = 0;RcpntP -> Reserved = 0;

/* Now set the actual recipient (distribution list) name */WalkP = (char *)(RcpntP + 1);memcpy(WalkP, TEST_DL, Recipient_Length);

} /* end of Create_Recipient_Descriptor function */

/**********************************************************************/

/**********************************************************************//* Create_Attachment_Descriptor function creates our attachment *//* reference list that consists of (1) an attachment reference and *//* (2) an AS/400 qualified file member name. The function places *//* the relevant attachment reference list information in the message *//* descriptor attribute array. *//**********************************************************************/

static void Create_Attachment_Descriptor(void

){

intAttachment_Length = strlen(TEST_ATTACHMENT)

, Attachment_Size = sizeof(Qzmf_Msg_Desc_Hdr0100_t) +2 * sizeof(Qzmf_ATTL0100_t) +Attachment_Length +sizeof(AS400_File_Attachment_t)

;

Qzmf_ATTL0100_t*AttachmentP;

AS400_File_Attachment_t*AS400_AttachP;

/* Allocate space for attachment descriptor */WalkP = (char *)malloc(Attachment_Size);

if (WalkP == NULL){

printf(″Malloc Error in ATTL; quitting\n″ ) ;exit(1);

}

/* Fill the proper element of the message descriptor attribute */

316 AnyMail/400 MSF

Page 341: AnyMail/400 Mail Server Framework Developer Guide January 1995

/* array for the attachment reference list to be created. */(Msg_Desc_Attr_Array + Attachment) -> Msg_Desc_Ptr =

(_SPCPTR)(WalkP);(Msg_Desc_Attr_Array + Attachment)-> Msg_Desc_Length =

Attachment_Size;memcpy( (Msg_Desc_Attr_Array + Attachment) -> Msg_Desc_Format_Name,

QZMF_ATTACH_REF_FMT, QZMF_MSG_DESC_FMT_LENGTH );(Msg_Desc_Attr_Array + Attachment) -> Reserved = 0;

/* Fill the header of the attachment reference list */List_HdrP = (Qzmf_Msg_Desc_Hdr0100_t *)WalkP;

List_HdrP -> Msg_Desc_Total_Length = Attachment_Size;List_HdrP -> Bytes_Available = 0;memcpy( List_HdrP -> Msg_Desc_Format_Name,QZMF_ATTACH_REF_FMT,

QZMF_MSG_DESC_FMT_LENGTH );List_HdrP -> First_Entry_Offset = sizeof(Qzmf_Msg_Desc_Hdr0100_t);List_HdrP -> Total_Num_Of_Entries = 2;List_HdrP -> Reserved = 0;

/***********************************************************//* First, create the attachment reference list entry. *//***********************************************************/AttachmentP = (Qzmf_ATTL0100_t *)(List_HdrP + 1);

AttachmentP -> Entry_Length = sizeof(Qzmf_ATTL0100_t) +Attachment_Length;

AttachmentP -> Displacement = sizeof(Qzmf_ATTL0100_t);AttachmentP -> Attach_Length = Attachment_Length;memcpy( AttachmentP -> Attach_Type, TEST_ATTACHMENT_TYPE_VALUE,

sizeof(Qzmf_Type_Value_t) );AttachmentP -> Unique_Id = 0;AttachmentP -> Ref_Unique_Id = 0;AttachmentP -> Reserved = 0;

/* Now, set the attachment reference */WalkP = (char *)(AttachmentP + 1);memcpy(WalkP, TEST_ATTACHMENT, Attachment_Length);

/***********************************************************//* Now, create the second attachment reference list entry. *//* This second entry is actually an AS/400 qualified *//* file member name. *//***********************************************************/

/* Set ATTL0100-typed pointer just beyond the first *//* attachment reference list element. */AttachmentP = (Qzmf_ATTL0100_t *)(WalkP + Attachment_Length);

/* Fill the fixed portion of the ATTL0100 structure */AttachmentP -> Entry_Length = sizeof(Qzmf_ATTL0100_t) +

sizeof(AS400_File_Attachment_t);AttachmentP -> Displacement = sizeof(Qzmf_ATTL0100_t);AttachmentP -> Attach_Length = sizeof(AS400_File_Attachment_t);memcpy( AttachmentP -> Attach_Type, TEST_AS400_ATTACH_TYPE_VALUE,

sizeof(Qzmf_Type_Value_t) );AttachmentP -> Unique_Id = 0;AttachmentP -> Ref_Unique_Id = 0;

Appendix E. An MSF Application — Example 317

Page 342: AnyMail/400 Mail Server Framework Developer Guide January 1995

AttachmentP -> Reserved = 0;

/*************************************************************//* Now, append the AS400 file reference after setting up a *//* properly typed pointer. *//*************************************************************/AS400_AttachP = (AS400_File_Attachment_t *)(AttachmentP + 1);

/* Fill the actual AS400 library, file, and member names */memcpy(AS400_AttachP -> Library_Name, TEST_AS400_LIBRARY,

AS400_NAME_SIZE);memcpy(AS400_AttachP -> File_Name, TEST_AS400_FILE,

AS400_NAME_SIZE);memcpy(AS400_AttachP -> Member_Name, TEST_AS400_MEMBER,

AS400_NAME_SIZE);

} /* end of Create_Attachment_Descriptor function */

/**********************************************************************/

/**********************************************************************//* Create_A_Message function creates an MSF message that has four *//* different lists. Use the test definitions of the TESTMSG *//* header file to create the MSF message. *//**********************************************************************/

void Create_A_Message(Qzmf_Msg_Id_t Msg_Id

){

Qzmf_Msg_Id_tDummy_Rsvrd_Msg_Id;

long intNum_Of_Msg_Descs = NUM_CRT_ATTRBT;

short intDesc_Indx = Originator;

/* Create four message lists and the corresponding *//* message descriptor array. */Create_Originator_Descriptor();Create_Envelope_Descriptor();Create_Recipient_Descriptor();Create_Attachment_Descriptor();

/* Set the Dummy Reserved Message ID to Null-Value = ′ ′ *//* because we have not reserved a message ID. */memset(Dummy_Rsvrd_Msg_Id, ′ ′ , sizeof(Qzmf_Msg_Id_t));

/* Specify exceptions should be signalled from the API *//* rather than using return codes. */Crt_Error_Code.Error.Bytes_Provided = 0;

318 AnyMail/400 MSF

Page 343: AnyMail/400 Mail Server Framework Developer Guide January 1995

#pragma exception_handler(Quit_Execution, 0, 0, _C2_MH_ESCAPE)

/* No initialization is needed for Dummy_Msg_Id, Create_Msg *//* API will ignore its first parameter if there is any *//* valid Msg ID in its second parameter */QzmfCrtMailMsg(

(void *)Msg_Id, (void *)Dummy_Rsvrd_Msg_Id, TEST_MESSAGE_TYPE_VALUE, (void *)Msg_Desc_Attr_Array, &Num_Of_Msg_Descs, QZMF_CRT_MAIL_MSG_FORMAT, (void *)(&Crt_Error_Code)

);

#pragma disable_handler

/* Heap space can be freed now because MSF has already copied *//* all the information to its internal storage. */while (Desc_Indx <= Attachment){

free( (void *)( (Msg_Desc_Attr_Array + Desc_Indx) -> Msg_Desc_Ptr ));

++Desc_Indx;}

} /* end of Create_A_Message function */

/**********************************************************************/

/**********************************************************************//* Given R, a reserved MSF message ID, the Create_A_Reserved_Message *//* function attempts to create an MSF message with ID = R. The *//* contents of the message is built from the definitions in the *//* TESTMSG header file and is identical to the message that *//* can be created by using Create_A_Message function. *//* *//* Note: Create_A_Reserved_Message is not expected to a heavily used *//* MSF API. *//**********************************************************************/

void Create_A_Reserved_Message(Qzmf_Msg_Id_t Rsvrd_Msg_Id

){

Qzmf_Msg_Id_tDummy_Msg_Id;

long intNum_Of_Msg_Descs = NUM_CRT_ATTRBT;

short intDesc_Indx = Originator;

/* Create four message lists and the corresponding */

Appendix E. An MSF Application — Example 319

Page 344: AnyMail/400 Mail Server Framework Developer Guide January 1995

/* message descriptor array */Create_Originator_Descriptor();Create_Envelope_Descriptor();Create_Recipient_Descriptor();Create_Attachment_Descriptor();

/* Specify exceptions should be signalled from the API *//* rather than using return codes. */Crt_Error_Code.Error.Bytes_Provided = 0;

#pragma exception_handler(Quit_Execution, 0, 0, _C2_MH_ESCAPE)

/* No initialization is needed for Dummy_Msg_Id. The create *//* API will ignore its first parameter if there is any *//* valid Msg ID in its second parameter */QzmfCrtMailMsg(

(void *)Dummy_Msg_Id, (void *)Rsvrd_Msg_Id, TEST_MESSAGE_TYPE_VALUE, (void *)Msg_Desc_Attr_Array, &Num_Of_Msg_Descs, QZMF_CRT_MAIL_MSG_FORMAT, (void *)(&Crt_Error_Code)

);

#pragma disable_handler

/* Heap space can be freed now because MSF has already copied *//* all the information to its internal storage. */while (Desc_Indx <= Attachment){

free( (void *)( (Msg_Desc_Attr_Array + Desc_Indx) -> Msg_Desc_Ptr ));

++Desc_Indx;}

} /* end of Create_A_Reserved_Message function */

/**********************************************************************//************ end of file TCRTMOD *******************************//**********************************************************************/

TCRTMSG ProgramThe TCRTMSG program creates a test MSF message that consists of thefollowing:

• An originator.• A GET envelope that contains 3 attributes: subject, priority, and sensitivity.• A distribution list.• Attachment references.

To create the program, you need to bind this module with the TCRTMOD moduleshown in “Module and Program to Create MSF Messages — Example” onpage 308.

320 AnyMail/400 MSF

Page 345: AnyMail/400 Mail Server Framework Developer Guide January 1995

/*********************************************************************//* *//* Example: Create Message Program *//* *//* File Name: TCRTMSG *//* *//*********************************************************************/

#pragma strings(readonly)

#include <stdio.h>

#include <qzmfasrv.h> /* contains MSF API prototypes */

/*-------------------------------------------------------------------*//* Imported functions *//*-------------------------------------------------------------------*/

extern void Create_A_Message(Qzmf_Msg_Id_t

);

/*--------------------------------------------------------------------*//* Executable code *//*--------------------------------------------------------------------*/

/**********************************************************************//**********************************************************************//**************** main ****************************************//**********************************************************************//**********************************************************************/

void main(void){

Qzmf_Msg_Id_tMsg_Id

;

/* Create an MSF Message */Create_A_Message(

Msg_Id);

printf(″The Created Message′ s ID: %.32s\n″ , Msg_Id);

} /* end of main */

/**********************************************************************//************ end of file TCRTMSG *********************************//**********************************************************************/

Appendix E. An MSF Application — Example 321

Page 346: AnyMail/400 Mail Server Framework Developer Guide January 1995

Results from the TCRTMSG ProgramWhen the TRCTMSG program successfully runs, something similar to thefollowing should appear on your display:

The Created Message′ s ID: ID 10007259410251402100000000005Press ENTER to end terminal session.

List Expansion Exit Point Program — ExampleThe TLSTEXPN file is a sample MSF list expansion exit point program. The MSFmessage created by the TCRTMOD function contains DEPT44A as the distributionlist. The TLSTEXPN program expands DEPT44A into three recipients.

The program consists of a single module. To create this program, follow thesteps in “Creating a Module and Program in ILE C/400 — Example” on page 199.

/*********************************************************************//* *//* Example: List Expansion exit point program *//* *//* File Name: TLSTEXPN *//* *//*********************************************************************/

#pragma strings(readonly)

#include <stdio.h>#include <string.h>#include <stdlib.h>

#include <except.h>#include <pointer.h>

#include <qusec.h>#include <qus.h>#include <quscrtus.h>#include <quscusat.h>#include <qusptrus.h>#include <qusdltus.h>

#include <qzmfasrv.h>

#include ″testtype.h″#include ″testmsg.h″

#define NUM_CHNGD_ATTRBT 1 /* We will change only the *//* recipient list descriptor */

typedef struct{ Qus_EC_t Error; char Exception_Data[1];} Error_Code_t; /* We will expect exceptions to be */

/* signalled and not care about *//* the returned codes */

typedef struct{

Qus_Vlen_Rec_3_t Attr_Rec;

322 AnyMail/400 MSF

Page 347: AnyMail/400 Mail Server Framework Developer Guide January 1995

char Data[1];} Attr_Rec_t;

typedef struct{

long int Num_Of_Attrb;Attr_Rec_t Attribute[2];

} Change_Attr_t;

/*--------------------------------------------------------------------*//* File-scoped variables *//*--------------------------------------------------------------------*/

static Qzmf_Msg_Desc_Hdr0100_t*Old_List_HdrP

, *New_List_HdrP;

static Change_Attr_tSpace_Change_Attr;

static Error_Code_tChg_Error_Code;

static char*WalkP;

/*--------------------------------------------------------------------*//* File-scoped functions *//*--------------------------------------------------------------------*/

static void Quit_Execution(void

);

static int Create_Expanded_List(void

);

static void Create_A_Recipient_List_Element(int*

, int, int, char*, char*

);

static _SPCPTR Create_A_Work_Space(void

);

/*--------------------------------------------------------------------*//* Executable code *//*--------------------------------------------------------------------*/

Appendix E. An MSF Application — Example 323

Page 348: AnyMail/400 Mail Server Framework Developer Guide January 1995

/**********************************************************************//* General exception handler function. The program ends *//* prematurely after printing a general error statement. *//**********************************************************************/

static void Quit_Execution(void

){

printf(″Unexpected CPFxxxx exception; quitting\n″ ) ;

/****************************************************************//* For simplicity, this does not attempt to delete the QTEMP *//* user space. If the space has already been created, it *//* remains until the end of the MSF job. For permanent spaces *//* and for your applications, you should have code to delete *//* the user spaces in relevent exception handlers. *//****************************************************************/exit(1);

} /* end of Quit_Execution Exception Handler */

/**********************************************************************/

/**********************************************************************//* The Create_Expanded_List function creates three recipient *//* list entries by calling the Create_A_Recipient_List_Element *//* function three successive times. The contents of *//* the recipient list entries are picked up from the TESTMSG *//* header file. The function returns the total length of the three *//* recipient list entries. *//* *//* A file-scoped pointer, WalkP, is used to create successive *//* list entries. *//**********************************************************************/

static int Create_Expanded_List(void

){

short intRecipient_Length1 = strlen(TEST_RECIPIENT1)

, Recipient_Length2 = strlen(TEST_RECIPIENT2), Recipient_Length3 = strlen(TEST_RECIPIENT3), SPIN_Length1 = strlen(TEST_SPIN1), SPIN_Length2 = strlen(TEST_SPIN2), SPIN_Length3 = strlen(TEST_SPIN3);

intList_Length = 0

;

/* the walk pointer */WalkP = (char *)(New_List_HdrP + 1);

324 AnyMail/400 MSF

Page 349: AnyMail/400 Mail Server Framework Developer Guide January 1995

/* Attach the individual list entries to the list header */Create_A_Recipient_List_Element(

&List_Length, Recipient_Length1, SPIN_Length1, TEST_RECIPIENT1, TEST_SPIN1

);Create_A_Recipient_List_Element(

&List_Length, Recipient_Length2, SPIN_Length2, TEST_RECIPIENT2, TEST_SPIN2

);Create_A_Recipient_List_Element(

&List_Length, Recipient_Length3, SPIN_Length3, TEST_RECIPIENT3, TEST_SPIN3

);return List_Length;

} /* end of Create_Expanded_List function */

/**********************************************************************/

/**********************************************************************//* The Create_A_Recipient_List_Element function attaches a recipient *//* list entry to the next available position in the recipient list. *//**********************************************************************/

static void Create_A_Recipient_List_Element(int *Element_Length

, int Recipient_Length, int SPIN_Length, char *Recipient, char *SPIN

){

Qzmf_RCPL0100_t*RcpntP = (Qzmf_RCPL0100_t *)WalkP;

RcpntP -> Entry_Length = sizeof(Qzmf_RCPL0100_t) +Recipient_Length + SPIN_Length;

*Element_Length += RcpntP -> Entry_Length;RcpntP -> SPIN_Displacement = sizeof(Qzmf_RCPL0100_t) +

Recipient_Length;RcpntP -> SPIN_Length = SPIN_Length;RcpntP -> Recipient_Displacement = sizeof(Qzmf_RCPL0100_t);RcpntP -> Addr_Length = Recipient_Length;memcpy( (RcpntP -> Addr_Type), TEST_ADDRESS_TYPE_VALUE,

sizeof(Qzmf_Type_Value_t) );RcpntP -> CCSID = DEFAULT_CCSID;RcpntP -> Reason_Code = 0;

Appendix E. An MSF Application — Example 325

Page 350: AnyMail/400 Mail Server Framework Developer Guide January 1995

RcpntP -> Diag_Code = 0;memcpy( (RcpntP -> Msg_Type), NULL_MSG_TYPE,

sizeof(Qzmf_Type_Value_t) );RcpntP -> Status = NULL_RCPT_STATUS;RcpntP -> Dist_Type = QZMF_DIST_TYPE_NORMAL; /* Assumed */

/****************************************************************//* The following assignment copies the Unique_Id field from the *//* distribution list to the individual recipient entries. The *//* assignment conveys substitution information to MSF. *//****************************************************************/RcpntP -> Unique_Id = ( (Qzmf_RCPL0100_t *)(Old_List_HdrP + 1) ) ->

Unique_Id;

RcpntP -> Reserved = 0;

/* Now, copy the actual recipient address */WalkP = (char *)(RcpntP + 1);memcpy(WalkP, Recipient, Recipient_Length);

/* Attach our test SPIN */WalkP += Recipient_Length;memcpy(WalkP, SPIN, SPIN_Length);

/* Advance the walk pointer for the next list entry */WalkP += SPIN_Length;

} /* end of Create_A_Recipient_List_Element function */

/**********************************************************************/

/**********************************************************************//* Create_A_Work_Space function *//* - creates a scratchpad user space, *//* - makes it auto-extendible, and *//* - returns its resolved space pointer. *//**********************************************************************/

static _SPCPTR Create_A_Work_Space(void

){

charScratchpad_Lib_Name[10];

_SPCPTRUser_Space_Ptr;

/* First, create a user space */#pragma exception_handler(Quit_Execution, 0, 0, _C2_MH_ESCAPE)

QUSCRTUS(WORK_SPACE_NAME

, ″ ″, WORK_SPACE_SIZE

326 AnyMail/400 MSF

Page 351: AnyMail/400 Mail Server Framework Developer Guide January 1995

, ″\0″, ″*ALL ″, ″MSF Test Scratchpad User Space″, ″*YES ″, (void *)&Chg_Error_Code, ″*USER ″

);

#pragma disable_handler

/* Make the space auto-extendible *//* We must set the variable length attributes properly */Space_Change_Attr.Num_Of_Attrb = 2;Space_Change_Attr.Attribute[0].Attr_Rec.Key = 2;Space_Change_Attr.Attribute[0].Attr_Rec.Length_Vlen_Record =

sizeof(Space_Change_Attr.Attribute[0].Data);Space_Change_Attr.Attribute[0].Data[0] = ′ \0′ ;

Space_Change_Attr.Attribute[1].Attr_Rec.Key = 3;Space_Change_Attr.Attribute[1].Attr_Rec.Length_Vlen_Record =

sizeof(Space_Change_Attr.Attribute[0].Data);Space_Change_Attr.Attribute[1].Data[0] = ′ 1 ′ ;

#pragma exception_handler(Quit_Execution, 0, 0, _C2_MH_ESCAPE)

QUSCUSAT(Scratchpad_Lib_Name /* The Lib-name is not used */

, WORK_SPACE_NAME, (void *)&Space_Change_Attr, (void *)&Chg_Error_Code

);

#pragma disable_handler

/* Now, get the pointer to the previously mentioned space. */#pragma exception_handler(Quit_Execution, 0, 0, _C2_MH_ESCAPE)

QUSPTRUS(WORK_SPACE_NAME

, &User_Space_Ptr, (void *)&Chg_Error_Code

);

#pragma disable_handler

return (User_Space_Ptr);

} /* end of Create_A_Work_Space function */

/**********************************************************************/

/**********************************************************************//**********************************************************************//**************** main ****************************************/

Appendix E. An MSF Application — Example 327

Page 352: AnyMail/400 Mail Server Framework Developer Guide January 1995

/**********************************************************************//**********************************************************************/

void main(int argc, char *argv[]){

/*******************************************************************//* The argv vector contains all the information passed by MSF *//* to the exit point program. *//* *//* Assume that the present program will get triggered *//* by MSF due to the message created in the earlier example. *//* Recall that the address types of all the relevant message list *//* entries are TEST_ADDRESS_TYPE. A particular message identifier *//* can be checked by using argv[2] *//* -- the passed message ID. *//*******************************************************************/

/*******************************************************************//* Set the return code address, the number of passed message *//* attributes, and the number of message attributes that we are *//* going to change in the program. *//*******************************************************************/

long int*Return_Code = (long int *)(*(argv + 6))

, Passed_Num_Attrbts = *(long int *)(*(argv + 4)), Num_Of_Changed_Attributes = 1;

short intindx = 0;

/* Set a pointer to the passed message descriptor attribute array */Qzmf_Msg_Desc_Attrbt_Entity_t

*Passed_Msg_Desc_AttrP =(Qzmf_Msg_Desc_Attrbt_Entity_t *)(*(argv + 3))

, Msg_Desc_Attr_Array[NUM_CHNGD_ATTRBT];

/* Set the default return code for MSF */*Return_Code = QZMF_END_MSG_PROCESSING;

/* Specify exceptions should be signalled from the API *//* rather than using return codes. */Chg_Error_Code.Error.Bytes_Provided = 0;

/* Locate the message descriptor corresponding to the *//* recipient list. */while ( indx < Passed_Num_Attrbts ){

if ( !memcmp( (Passed_Msg_Desc_AttrP + indx) ->Msg_Desc_Format_Name,

QZMF_RECIPIENT_LIST_FMT,QZMF_MSG_DESC_FMT_LENGTH ) )

{/* Set the recipient list header pointer */Old_List_HdrP = (Qzmf_Msg_Desc_Hdr0100_t *)

( (Passed_Msg_Desc_AttrP + indx) -> Msg_Desc_Ptr );

328 AnyMail/400 MSF

Page 353: AnyMail/400 Mail Server Framework Developer Guide January 1995

break;}++indx;

} /* end of while loop over the passed message descriptor array */

if (indx == Passed_Num_Attrbts){

printf(″Failed to locate the recipient list; quitting\n″ ) ;exit(1);

}

/*******************************************************************//* Now, expand the test distribution list to three *//* recipient entries. Though it is possible to use the space *//* returned by MSF to place the expanded lists, for portability *//* across different OS/400 releases, we suggest you do not do so *//* when the new message descriptor array is greater than its *//* original size (returned in *//* argv[indx] -> Msg_Desc_Length). *//* *//* For an increased Msg_Desc_Length, create a new space. *//* Use malloc to obtain the new space from the system heap *//* when the maximum size requirement is known in advance. *//* For other instances, it is better to create an auto-extendible *//* user space. Because the list expansion exit point program *//* may have to determine the recipients by using a directory *//* search, the size of the recipient list cannot be *//* determined beforehand. *//* *//* To illustrate the general concept, this example uses *//* a user space to place the expanded list. This example *//* creates a space in QTEMP whose life span is the same as *//* the life span of the MSF job. If necessary for any *//* particular application, a permanent space can also be *//* created in a library other than QTEMP. *//* *//* For better performance, the task of obtaining the space pointer *//* can be done only once during the first invocation of the *//* exit point program. *//* The resolved pointer can be referred to in subsequent *//* invocations by declaring it as a global variable in a *//* semi-permanent activation group. *//*******************************************************************/

/* First, set up the two known values in the *//* Msg_Descriptor_Attr_Array element */

Msg_Desc_Attr_Array -> Msg_Desc_Ptr = Create_A_Work_Space();memcpy( (Msg_Desc_Attr_Array -> Msg_Desc_Format_Name),

QZMF_RECIPIENT_LIST_FMT, QZMF_MSG_DESC_FMT_LENGTH );

/*******************************************************************//* Now, create the new recipient history list in the space *//* that was created earlier. *//* (A typical application will probably call directory search *//* functions at this point to create the expanded distribution *//* list.) *//*******************************************************************/

Appendix E. An MSF Application — Example 329

Page 354: AnyMail/400 Mail Server Framework Developer Guide January 1995

/* Set up the new recipient list header pointer */New_List_HdrP = (Qzmf_Msg_Desc_Hdr0100_t *)

(Msg_Desc_Attr_Array -> Msg_Desc_Ptr);

/******************************************************************//* Create the three successive recipient entries using the *//* Walk-and-Cast methodology (walk the pointer through the *//* list and use the cast operator to set the appropriate type *//* for the pointer). The following function returns *//* the total length of the recipient list that is created. *//* Using that length, fill the list header and the Length *//* field of the message descriptor array. *//******************************************************************/

New_List_HdrP -> Msg_Desc_Total_Length =sizeof(Qzmf_Msg_Desc_Hdr0100_t) +Create_Expanded_List();

New_List_HdrP -> Bytes_Available = 0;memcpy( (New_List_HdrP -> Msg_Desc_Format_Name),

QZMF_RECIPIENT_LIST_FMT, QZMF_MSG_DESC_FMT_LENGTH );New_List_HdrP -> First_Entry_Offset = sizeof(Qzmf_Msg_Desc_Hdr0100_t);New_List_HdrP -> Total_Num_Of_Entries = 3;New_List_HdrP -> Reserved = 0;

Msg_Desc_Attr_Array -> Msg_Desc_Length =New_List_HdrP -> Msg_Desc_Total_Length;

/* We have created the message descriptor. Next invoke *//* the Change Mail Message API to change the MSF message. */

#pragma exception_handler(Quit_Execution, 0, 0, _C2_MH_ESCAPE)

QzmfChgMailMsg((void *)(*(argv + 2))

, (void *)Msg_Desc_Attr_Array, &Num_Of_Changed_Attributes, QZMF_CHG_MAIL_MSG_FORMAT, (void *)(&Chg_Error_Code)

);

#pragma disable_handler

/* Destroy the workspace */#pragma exception_handler(Quit_Execution, 0, 0, _C2_MH_ESCAPE)QUSDLTUS(

WORK_SPACE_NAME, &Chg_Error_Code

);#pragma disable_handler

/* Set the proper return code for MSF job before finishing */*Return_Code = QZMF_CONTINUE;

} /* end of main */

330 AnyMail/400 MSF

Page 355: AnyMail/400 Mail Server Framework Developer Guide January 1995

/**********************************************************************//************ end of file TLSTEXPN *********************************//**********************************************************************/

Address Resolution Exit Point Program — ExampleThe TADDRSLN file is a sample MSF address resolution exit point program. Itplaces proper message type and status fields in the recipient list as expanded bythe sample list expansion program. The sample list expansion program expandsthe distribution list into three recipients. The first two recipients′ statuses areset to local by this sample address resolution program. The status of the thirdrecipient is set to remote delivery. Test_Msg_Type is used for all threerecipients.

The program consists of a single module. To create this program, follow thesteps in “Creating a Module and Program in ILE C/400 — Example” on page 199.

/*********************************************************************//* *//* Example: Address resolution exit point program *//* *//* File: TADDRSLN *//* *//*********************************************************************/

#pragma strings(readonly)

#include <stdio.h>#include <string.h>#include <stdlib.h>

#include <except.h>#include <pointer.h>

#include <qusec.h>

#include <qzmfasrv.h>

#include ″testtype.h″#include ″testmsg.h″

typedef struct{ Qus_EC_t Error; char Exception_Data[1];} Error_Code_t; /* We will expect exceptions to be */

/* signalled and not care about *//* the returned codes */

/*--------------------------------------------------------------------*//* File-scoped variables *//*--------------------------------------------------------------------*/

static const intNUM_CHNGD_ATTRBT = 1 /* We are going to change */; /* only the recipient list */

/* descriptor */

Appendix E. An MSF Application — Example 331

Page 356: AnyMail/400 Mail Server Framework Developer Guide January 1995

static Error_Code_tChg_Error_Code;

/*--------------------------------------------------------------------*//* File-scoped functions *//*--------------------------------------------------------------------*/

static void Quit_Execution(void

);

/*--------------------------------------------------------------------*//* Executable code *//*--------------------------------------------------------------------*/

/**********************************************************************//* General exception handler function. The program ends *//* prematurely after outputting a general error statement. *//**********************************************************************/

static void Quit_Execution(void

){

printf(″Unexpected CPFxxxx exception encountered; quitting\n″ ) ;exit(1);

} /* end of Quit_Execution Exception Handler */

/**********************************************************************/

/**********************************************************************//**********************************************************************//**************** main ****************************************//**********************************************************************//**********************************************************************/

void main(int argc, char *argv[]){

/*******************************************************************//* The argv vector contains all the information that is passed *//* by MSF to the exit point program. *//* *//* For simplicity, we are assuming that the present program will *//* get triggered by MSF due to the message created in the earlier *//* example. Recall the address types of all the relevant message *//* list entries are TEST_ADDRESS_TYPE. A particular message *//* identifier can be checked by using argv 2 -- the passed *//* message ID. *//*******************************************************************/

Qzmf_Msg_Desc_Hdr0100_t*List_HdrP

332 AnyMail/400 MSF

Page 357: AnyMail/400 Mail Server Framework Developer Guide January 1995

;

Qzmf_RCPL0100_t*RcpntP;

long int*Return_Code = (long int *)(*(argv + 6))

, Passed_Num_Attrbts = *(long int *)(*(argv + 4)), Num_Of_Changed_Attributes = NUM_CHNGD_ATTRBT, Temp_Num_Entries;

short intDesc_Indx = 0

, Elem_Indx = 1;

/* Set a pointer to the passed message descriptor attribute array */Qzmf_Msg_Desc_Attrbt_Entity_t

*Passed_Msg_Desc_AttrP =(Qzmf_Msg_Desc_Attrbt_Entity_t *)(*(argv + 3))

;

/* Set the default return code to MSF */*Return_Code = QZMF_END_MSG_PROCESSING;

/* Specify exceptions should be signalled from the API *//* rather than using return codes. */Chg_Error_Code.Error.Bytes_Provided = 0;

/* Locate the message descriptor corresponding to the *//* recipient list. */while ( Desc_Indx < Passed_Num_Attrbts ){

if ( !memcmp( (Passed_Msg_Desc_AttrP + Desc_Indx) ->Msg_Desc_Format_Name,

QZMF_RECIPIENT_LIST_FMT,QZMF_MSG_DESC_FMT_LENGTH ) )

{/* Set the recipient list header pointer */List_HdrP = (Qzmf_Msg_Desc_Hdr0100_t *)

( (Passed_Msg_Desc_AttrP + Desc_Indx) -> Msg_Desc_Ptr );break;

}++Desc_Indx;

} /* end of while loop (over the passed message descriptor array) */

if (Desc_Indx == Passed_Num_Attrbts){

printf(″Failed to locate the Recipient List; quitting\n″ ) ;exit(1);

}

/*******************************************************************//* Now set the message type and status fields of all the *//* individual entries in the recipient list. In a typical *//* application, this task will be performed by a system *//* distribution directory search. We are not using */

Appendix E. An MSF Application — Example 333

Page 358: AnyMail/400 Mail Server Framework Developer Guide January 1995

/* any SPIN in this sample program. Therefore, the size of the *//* changed recipient list will be same as that of the old one. *//* *//* In a situation like this, where the size of the changed message *//* list is less than or equal to the size of the original message *//* list, the space returned by MSF can be used to invoke the *//* Change API. Any other work space can also be used, *//* but there is no benefit of using a separate space. Selection *//* of the same space may also save some coding effort because you *//* do not have to copy the unchanged information from the existing *//* message list. *//*******************************************************************/

/*******************************************************************//* Because no extra space is needed we will not create a separate *//* message descriptor array. Pass the existing descriptor *//* (Passed_Msg_Desc_AttrP + Desc_Indx) to the Change Mail *//* Message API. *//*******************************************************************/

/* Set up recipient list header pointer */List_HdrP = (Qzmf_Msg_Desc_Hdr0100_t *)

( (Passed_Msg_Desc_AttrP + Desc_Indx) -> Msg_Desc_Ptr );

/* Set up the pointer to the first recipient list entry */RcpntP = (Qzmf_RCPL0100_t *)

((char *)List_HdrP + List_HdrP -> First_Entry_Offset);

/*******************************************************************//* Now change the intended fields in all the recipient list entries*//*******************************************************************/

Temp_Num_Entries = List_HdrP -> Total_Num_Of_Entries;while ( Elem_Indx <= Temp_Num_Entries ){

/**************************************************************//* At this point a typical MSF application may have to *//* consult the system distribution directory to extract the *//* values of message type and status corresponding to *//* this particular recipient. *//* Just for example, the status fields of the first two *//* recipients are set for local delivery. The last *//* recipient is destined for a remote system. *//**************************************************************/memcpy( (RcpntP -> Msg_Type), TEST_MESSAGE_TYPE_VALUE,

sizeof(Qzmf_Type_Value_t) );if (Elem_Indx < 3)

RcpntP -> Status = QZMF_STATUS_LOCAL;else

RcpntP -> Status = QZMF_STATUS_FORWARDED;

/* Advance the recipient list entry pointer */RcpntP = (Qzmf_RCPL0100_t *)

( (char *)RcpntP + (RcpntP -> Entry_Length) );++Elem_Indx;

} /* end of while loop (over all the recipient entries) */

334 AnyMail/400 MSF

Page 359: AnyMail/400 Mail Server Framework Developer Guide January 1995

/*****************************************************************//* We have now finished changing the recipient list of the MSF *//* message. Now call the Change Mail Message API to *//* change the MSF message. *//*****************************************************************/

#pragma exception_handler(Quit_Execution, 0, 0, _C2_MH_ESCAPE)

QzmfChgMailMsg((void *)(*(argv + 2))

, (void *)(Passed_Msg_Desc_AttrP + Desc_Indx), &Num_Of_Changed_Attributes, QZMF_CHG_MAIL_MSG_FORMAT, (void *)(&Chg_Error_Code)

);

#pragma disable_handler

/* Set the proper return code to MSF job before finishing */*Return_Code = QZMF_CONTINUE;

} /* end of main */

/**********************************************************************//************ end of file TADDRSLN *********************************//**********************************************************************/

Retrieval Exit Point Program — ExampleThe TRTVMSG file is a sample MSF program that extracts information from theMSF message list entries. The sample program extracts the following from anMSF message:

• Originator information.• Envelope information.• Recipient information.• Recipient history information.• Message type information in the recipient list.

From an exit point program, different methods of message attribute extraction isavailable. The following retrieval program demonstrates all of them and pointsout the most efficient and natural retrieval processes that correspond to thedifferent kinds of MSF message attributes. The process of extraction isillustrated by sample print statements.

The program consists of a single module. To create this program, follow thesteps in “Creating a Module and Program in ILE C/400 — Example” on page 199.

/*********************************************************************//* *//* Example: Retrieve Message Program. *//* *//* It can be snapped in the local delivery or message forwarding *//* exit points. *//* *//* File Name: TRTVMSG */

Appendix E. An MSF Application — Example 335

Page 360: AnyMail/400 Mail Server Framework Developer Guide January 1995

/* *//*********************************************************************/

#pragma strings(readonly)

#include <stdio.h>#include <string.h>#include <stdlib.h>

#include <except.h>#include <pointer.h>

#include <qusec.h>#include <qus.h>#include <quscrtus.h>#include <quscusat.h>#include <qusptrus.h>#include <qusdltus.h>

#include <qzmfasrv.h>

#include ″testtype.h″#include ″testmsg.h″

#define NUM_RTRVD_ATTRBT 2 /* We will retrieve two *//* message descriptors */

typedef struct{ Qus_EC_t Error; char Exception_Data[1];} Error_Code_t; /* We will expect exceptions to be */

/* signalled and not care about *//* the returned codes */

typedef struct{

Qus_Vlen_Rec_3_t Attr_Rec;char Data[1];

} Attr_Rec_t;

typedef struct{

long int Num_Of_Attrb;Attr_Rec_t Attribute[2];

} Change_Attr_t;

/*--------------------------------------------------------------------*//* file-scoped variables *//*--------------------------------------------------------------------*/

static const intHEAP_SPACE_SIZE = 500 /* Rough estimate for a */

; /* malloc′ ed space */

static Change_Attr_tSpace_Change_Attr;

336 AnyMail/400 MSF

Page 361: AnyMail/400 Mail Server Framework Developer Guide January 1995

static Error_Code_tRtv_Error_Code;

static char*Separator =

″===================+++++++++++++++++++++++++=======================″;

/*--------------------------------------------------------------------*//* file-scoped functions *//*--------------------------------------------------------------------*/

static void Quit_Execution(void

);

static _SPCPTR Create_A_Work_Space(void

);

static void Print_A_GET(Qzmf_GET_t*

);

/*--------------------------------------------------------------------*//* Executable code *//*--------------------------------------------------------------------*/

/**********************************************************************//* General exception handler function. The program ends *//* prematurely after printing a general error statement. *//**********************************************************************/

static void Quit_Execution(void

){

printf(″Unexpected CPFxxxx exception; quitting\n″ ) ;

/****************************************************************//* For simplicity, this does not attempt to delete the QTEMP *//* user space. If the space has already been created, it *//* remains until the end of the MSF job. For permanent spaces *//* and for your applications, you should have code to delete *//* the user spaces in relevent exception handlers. *//****************************************************************/

exit(1);

} /* end of Quit_Execution Exception Handler */

/*********************************************************************/

/*********************************************************************/

Appendix E. An MSF Application — Example 337

Page 362: AnyMail/400 Mail Server Framework Developer Guide January 1995

/* Create_A_Work_Space function: */ /* - creates a user space */ /* - makes it auto-extendible, and */ /* - returns the resolved space pointer to the created space. */ /*********************************************************************/

static _SPCPTR Create_A_Work_Space(void

){

charScratchpad_Lib_Name[10];

_SPCPTRUser_Space_Ptr;

/* First create a user space */#pragma exception_handler(Quit_Execution, 0, 0, _C2_MH_ESCAPE)QUSCRTUS(

WORK_SPACE_NAME, ″ ″, WORK_SPACE_SIZE, ″\0″, ″*ALL ″, ″MSF Test Scratchpad User Space″, ″*YES ″, (void *)&Rtv_Error_Code, ″*USER ″

);#pragma disable_handler

/* Make the space auto-extendible *//* We must set the varaiable length attributes properly */Space_Change_Attr.Num_Of_Attrb = 2;Space_Change_Attr.Attribute[0].Attr_Rec.Key = 2;Space_Change_Attr.Attribute[0].Attr_Rec.Length_Vlen_Record =

sizeof(Space_Change_Attr.Attribute[0].Data);

Space_Change_Attr.Attribute[0].Data[0] = ′ \0′ ;

Space_Change_Attr.Attribute[1].Attr_Rec.Key = 3;Space_Change_Attr.Attribute[1].Attr_Rec.Length_Vlen_Record =

sizeof(Space_Change_Attr.Attribute[0].Data);Space_Change_Attr.Attribute[1].Data[0] = ′ 1 ′ ;

#pragma exception_handler(Quit_Execution, 0, 0, _C2_MH_ESCAPE)QUSCUSAT(

Scratchpad_Lib_Name /* The Lib name is not used */, WORK_SPACE_NAME, (void *)&Space_Change_Attr, (void *)&Rtv_Error_Code

);#pragma disable_handler

/* Now, get the pointer to the previously mentioned user space */#pragma exception_handler(Quit_Execution, 0, 0, _C2_MH_ESCAPE)QUSPTRUS(

338 AnyMail/400 MSF

Page 363: AnyMail/400 Mail Server Framework Developer Guide January 1995

WORK_SPACE_NAME, &User_Space_Ptr, (void *)&Rtv_Error_Code

);#pragma disable_handler

return (User_Space_Ptr);

} /* end of Create_A_Work_Space function */

/**********************************************************************/

/**********************************************************************//* The Print_A_GET function prints out selected GET attributes: *//* subject, priority, and sensitivity. The function can be easily *//* expanded to handle all the different kinds of GET attributes. *//**********************************************************************/

void Print_A_GET(Qzmf_GET_t *GETP

){

Qzmf_GET_Generic_Attrbt_t*GET_Gen_AttrP;

Qzmf_GET_Subject_Attrbt_t*GET_SubjectP;

Qzmf_GET_Int_Attrbt_t*GET_IntP;

intGET_Attrbt_Indx = 1

, GET_Num_Of_Attrbt = GETP -> Num_Of_Attributes, GET_Int_Val, GET_Attribute_Id;

printf(″GET Length: %d, GET Number of Attributes: %d\n″ ,GETP -> GET_Length, GET_Num_Of_Attrbt);

GET_Gen_AttrP = (Qzmf_GET_Generic_Attrbt_t *)( (char *)GETP +

GETP -> First_Attribute_Offset );

/* Loop through all the contiguous GET attribute elements */while (GET_Attrbt_Indx <= GET_Num_Of_Attrbt){

GET_Attribute_Id = GET_Gen_AttrP -> Attribute_Id;switch(GET_Attribute_Id){

case Qzmf_GET_Subject_Id:GET_SubjectP = (Qzmf_GET_Subject_Attrbt_t *)GET_Gen_AttrP;printf(″GET Subject: %.*s\n″ ,

GET_SubjectP -> Subject_Length,( (char *)GET_SubjectP +

Appendix E. An MSF Application — Example 339

Page 364: AnyMail/400 Mail Server Framework Developer Guide January 1995

sizeof(Qzmf_GET_Subject_Attrbt_t) ) );break;

case Qzmf_GET_Priority_Type_Id:GET_IntP = (Qzmf_GET_Int_Attrbt_t *)(GET_Gen_AttrP);GET_Int_Val = (GET_IntP -> Qzmf_GET_Int_Attrbt_Info).

GET_Priority_Info;printf(″GET Priority: ″ ) ;switch (GET_Int_Val){

case Qzmf_Normal_Priority:printf(″Normal Priority\n″ ) ;break;

case Qzmf_Non_Urgent_Priority:printf(″Non_Urgent Priority\n″ ) ;break;

case Qzmf_Urgent_Priority:printf(″Urgent Priority\n″ ) ;break;

default:printf(″Unknown Value in GET Priority field: %d; ″

″quitting\n″ , GET_Int_Val);exit(1);

} /* end of switch on different Priority values */break;

case Qzmf_GET_Sensitivity_Type_Id:GET_IntP = (Qzmf_GET_Int_Attrbt_t *)(GET_Gen_AttrP);GET_Int_Val = (GET_IntP -> Qzmf_GET_Int_Attrbt_Info).

GET_Priority_Info;printf(″GET Sensitivity: ″ ) ;switch (GET_Int_Val){

case Qzmf_Not_Sensitive:printf(″Not Sensitive\n″ ) ;break;

case Qzmf_Personal:printf(″Personal\n″ ) ;break;

case Qzmf_Private:printf(″Private\n″ ) ;break;

case Qzmf_Confidential:printf(″Confidential\n″ ) ;break;

default:printf(″Unknown Value in GET Sensitivity field; %d; ″

″quitting\n″ , GET_Int_Val);exit(1);

} /* end of switch (on different Sensitivity values) */break;

default:printf(″Cannot handle <%d> GET Attribute at this moment\n″ ,

GET_Attribute_Id);break;

} /* end of switch (on different GET attributes) */

340 AnyMail/400 MSF

Page 365: AnyMail/400 Mail Server Framework Developer Guide January 1995

/* Advance the GET General Attribute Pointer */GET_Gen_AttrP = (Qzmf_GET_Generic_Attrbt_t *)

( (char *)GET_Gen_AttrP +GET_Gen_AttrP -> Attribute_Length );

++GET_Attrbt_Indx;} /* end of while loop (on GET attributes) */

} /* end of Print_A_GET function */

/**********************************************************************/

/**********************************************************************//**********************************************************************//**************** main ****************************************//**********************************************************************//**********************************************************************/

void main(int argc, char *argv[]){

/*******************************************************************//* The argv vector contains all the information that is passed *//* by MSF to the exit point program. *//* *//* For simplicity, assume that the present program will get *//* triggered by MSF due to the message that was created in the *//* earlier example. Recall that the address types of all the *//* relevant message list entries are of TEST_ADDRESS_TYPE. *//* A particular message identifier can be checked by *//* using argv 2 -- the passed message ID. *//*******************************************************************/

long int*Return_Code = (long int *)(*(argv + 6))

, Passed_Num_Attrbts = *(long int *)(*(argv + 4)), Num_Of_Retrieved_Attributes = NUM_RTRVD_ATTRBT, Temp_SPIN_Length = 0, Temp_Num_Entries;

short intDesc_Indx = 0

, Elem_Indx = 1;

/* Set a pointer to the passed message descriptor attribute array */Qzmf_Msg_Desc_Attrbt_Entity_t

*Passed_Msg_Desc_AttrP =(Qzmf_Msg_Desc_Attrbt_Entity_t *)(*(argv + 3))

, Msg_Desc_Attr_Array[NUM_RTRVD_ATTRBT];

/* Some pointer declarations for handling message lists */Qzmf_Msg_Desc_Hdr0100_t

*List_HdrP;

Appendix E. An MSF Application — Example 341

Page 366: AnyMail/400 Mail Server Framework Developer Guide January 1995

Qzmf_ORGL0100_t*OrgP;

Qzmf_ENVL0100_t*EnvP;

Qzmf_RCPL0100_t*RcpntP;

Qzmf_RCHL0100_t*Rcpnt_HistP;

Qzmf_MSGL0100_t*Rcpnt_Msg_TypP;

/* Set the default return code to MSF */*Return_Code = QZMF_END_MSG_PROCESSING;

/* Specify exceptions should be signalled from the API *//* rather than using return codes. */Rtv_Error_Code.Error.Bytes_Provided = 0;

/* Output MSF exit point name */printf( ″I got invoked at: %.20s\n″ , *(argv+1) );

/******************************************************************//* MSF passes a non-empty set of message descriptor *//* attributes to exit point programs. The passed descriptor array*//* contains a variety of message descriptors, depending *//* on the MSF exit point. The Retrieve API can retrieve any *//* number of descriptors. However, the main purpose of the API is*//* for collecting information about those message descriptors *//* that are not passed by MSF in the message descriptor array. *//* *//* A typical MSF application should behave in the following *//* manner: *//* *//* Assume an application is interested in descriptors *//* D1 to D5 in an MSF exit point P, and MSF passes only D1, D2, *//* and D3 in the message descriptor array in MSF exit point P. *//* *//* (a) Use the message descriptor array to extract D1, *//* D2, and D3 from argv[3], *//* and *//* (b) Use the Retrieve API to extract D4 and D5 *//* *//* In our example program: *//* P = Local delivery or message forwarding *//* exit point *//* D1 = Originator descriptor *//* D2 = Envelope decsriptor *//* D3 = Recipient descriptor *//* D4 = Recipient history descriptor *//* D5 = Recipient message type descriptor *//******************************************************************/

/* First, locate the originator descriptor = D1 in the */

342 AnyMail/400 MSF

Page 367: AnyMail/400 Mail Server Framework Developer Guide January 1995

/* passed descriptor array */while ( Desc_Indx < Passed_Num_Attrbts ){

if ( !memcmp( (Passed_Msg_Desc_AttrP + Desc_Indx) ->Msg_Desc_Format_Name,

QZMF_ORIGINATOR_LIST_FMT,QZMF_MSG_DESC_FMT_LENGTH ) )

{/* Set the originator list header pointer */List_HdrP = (Qzmf_Msg_Desc_Hdr0100_t *)

( (Passed_Msg_Desc_AttrP + Desc_Indx) -> Msg_Desc_Ptr );break;

}++Desc_Indx;

} /* end of while loop over the passed message descriptor array */

if (Desc_Indx == Passed_Num_Attrbts){

printf(″Failed to locate the Originator List; quitting\n″ ) ;exit(1);

}

/*******************************************************************//* We can extract all the originator information from the *//* originator list. As a simple demonstration, we will print the *//* originator names. *//*******************************************************************/

OrgP = (Qzmf_ORGL0100_t *)( (char *)List_HdrP + List_HdrP -> First_Entry_Offset);

printf(″%s\nFollowing is the Originator Information::\n″ , Separator);

Temp_Num_Entries = List_HdrP -> Total_Num_Of_Entries;while ( Elem_Indx <= Temp_Num_Entries ){

printf( ″Originator <%d>: %.*s\n″ , Elem_Indx,(OrgP -> Addr_Length),

((char *)OrgP + OrgP -> Displacement) );OrgP = (Qzmf_ORGL0100_t *)

( (char *)OrgP + (OrgP -> Entry_Length) );++Elem_Indx;

}

/* Now, locate the envelope decsriptor = D2 */Desc_Indx = 0;while ( Desc_Indx < Passed_Num_Attrbts ){

if ( !memcmp( (Passed_Msg_Desc_AttrP + Desc_Indx) ->Msg_Desc_Format_Name,

QZMF_ENVELOPE_LIST_FMT,QZMF_MSG_DESC_FMT_LENGTH ) )

{/* Set the envelope list header pointer */List_HdrP = (Qzmf_Msg_Desc_Hdr0100_t *)

( (Passed_Msg_Desc_AttrP + Desc_Indx) -> Msg_Desc_Ptr );break;

}++Desc_Indx;

Appendix E. An MSF Application — Example 343

Page 368: AnyMail/400 Mail Server Framework Developer Guide January 1995

} /* end of while loop over the passed message descriptor Array */

if (Desc_Indx == Passed_Num_Attrbts){

printf(″Failed to locate the Envelope List; quitting\n″ ) ;exit(1);

}

/*******************************************************************//* Extract all the envelope information from the descriptor. *//* In this example program, we print out the sample GET (recall *//* TCRTMOD module) attributes. *//*******************************************************************/

EnvP = (Qzmf_ENVL0100_t *)( (char *)List_HdrP + List_HdrP -> First_Entry_Offset);

printf(″%s\nFollowing is the Envelope Information::\n″ , Separator);

Elem_Indx = 1;Temp_Num_Entries = List_HdrP -> Total_Num_Of_Entries;while ( Elem_Indx <= Temp_Num_Entries){

printf(″Envelope <%d> follows::\n″ , Elem_Indx);if (

!memcmp( (EnvP -> Envelope_Type), GET_ENVELOPE_TYPE_VALUE,sizeof(Qzmf_Type_Value_t) )

)Print_A_GET(

(Qzmf_GET_t *)( (char *)EnvP + EnvP -> Displacement )

);else{

printf(″A Non_GET Envelope passed\n″ ) ;printf(″%.*s\n″ , (EnvP -> Envelope_Length),

((char *)EnvP + EnvP -> Displacement) );}

EnvP = (Qzmf_ENVL0100_t *)( (char *)EnvP + (EnvP -> Entry_Length) );

++Elem_Indx;} /* end of while loop over all the envelope list entries */

/*******************************************************************//* Similarly, after locating the recipient descriptor = D3 in *//* the message descriptor array, extract all the recipient *//* information from the recipient list. As a demonstration, *//* print the recipient names and SPIN. *//*******************************************************************/

Desc_Indx = 0;while ( Desc_Indx < Passed_Num_Attrbts ){

if ( !memcmp( (Passed_Msg_Desc_AttrP + Desc_Indx) ->Msg_Desc_Format_Name,

QZMF_RECIPIENT_LIST_FMT,QZMF_MSG_DESC_FMT_LENGTH ) )

344 AnyMail/400 MSF

Page 369: AnyMail/400 Mail Server Framework Developer Guide January 1995

{/* Set the recipient list header pointer */List_HdrP = (Qzmf_Msg_Desc_Hdr0100_t *)

( (Passed_Msg_Desc_AttrP + Desc_Indx) -> Msg_Desc_Ptr );break;

}++Desc_Indx;

} /* end of while loop over the passed message descriptor array */

if (Desc_Indx == Passed_Num_Attrbts){

printf(″Failed to locate the Recipient List; quitting\n″ ) ;exit(1);

}

RcpntP = (Qzmf_RCPL0100_t *)( (char *)List_HdrP + List_HdrP -> First_Entry_Offset);

printf(″%s\nFollowing is the Recipient Information::\n″ , Separator);

Elem_Indx = 1;Temp_Num_Entries = List_HdrP -> Total_Num_Of_Entries;while ( Elem_Indx <= Temp_Num_Entries){

printf( ″Recipient <%d>: %.*s\n″ , Elem_Indx,(RcpntP -> Addr_Length),

((char *)RcpntP + RcpntP -> Recipient_Displacement) );

Temp_SPIN_Length = RcpntP -> SPIN_Length;if (Temp_SPIN_Length > 0)

printf( ″SPIN <%d>: %.*s\n″ , Elem_Indx, Temp_SPIN_Length,((char *)RcpntP + RcpntP -> SPIN_Displacement) );

RcpntP = (Qzmf_RCPL0100_t *)( (char *)RcpntP + (RcpntP -> Entry_Length) );

++Elem_Indx;}

/*******************************************************************//* Call the Retrieve API to get addressability to D4 and *//* D5. We have to create sufficient spaces for storing the *//* retrieved lists. If the maximum amount of space can be *//* calculated beforehand, the malloc function can be used. *//* Otherwise, creation of an auto-extendible space is suggested. *//* *//* This example uses both methods for creating message list *//* storage areas. For the recipient history list, create a *//* user space. For recepient message type, use the system heap. *//*******************************************************************/

/* Set up the local message descriptor array to be passed to API */

/* The first array element is for recipient history */Msg_Desc_Attr_Array -> Msg_Desc_Ptr = Create_A_Work_Space();Msg_Desc_Attr_Array -> Msg_Desc_Length = AUTO_EXTEND_INDCTR;memcpy( (Msg_Desc_Attr_Array -> Msg_Desc_Format_Name),

QZMF_RECIPIENT_HIST_FMT, QZMF_MSG_DESC_FMT_LENGTH );

Appendix E. An MSF Application — Example 345

Page 370: AnyMail/400 Mail Server Framework Developer Guide January 1995

/* The second array element is for Recepient_Message_Type */if (

( (Msg_Desc_Attr_Array + 1) -> Msg_Desc_Ptr =(_SPCPTR)malloc(HEAP_SPACE_SIZE) ) == NULL

){

printf(″malloc problem while creating space for MSGL; ″″quitting\n″ ) ;

exit(1);}

(Msg_Desc_Attr_Array + 1) -> Msg_Desc_Length = HEAP_SPACE_SIZE;memcpy( (Msg_Desc_Attr_Array + 1) -> Msg_Desc_Format_Name,

QZMF_MSG_TYPE_LIST_FMT, QZMF_MSG_DESC_FMT_LENGTH );

/* We have completed the creation of the message descriptor. *//* Invoke the Retrieve Message API. */

#pragma exception_handler(Quit_Execution, 0, 0, _C2_MH_ESCAPE)

QzmfRtvMailMsg((void *)(*(argv + 2))

, (void *)Msg_Desc_Attr_Array, &Num_Of_Retrieved_Attributes, QZMF_RTV_MAIL_MSG_FORMAT, (void *)(&Rtv_Error_Code)

);

#pragma disable_handler

/* Now extract the retrieved information */

/******************************************************************//* Because we have used an auto-extendible space, the Retrieve *//* Mail Message API will extend the space if needed. *//* Normally, there is no need to check the completeness of the *//* retrieved information. *//******************************************************************/

/* Set the header pointer */List_HdrP = (Qzmf_Msg_Desc_Hdr0100_t *)

( (Msg_Desc_Attr_Array) -> Msg_Desc_Ptr );

/*******************************************************************//* Extract all the entry information from the recipient *//* history list. As a demonstration, print some of the *//* information from the list entries. *//*******************************************************************/

Rcpnt_HistP = (Qzmf_RCHL0100_t *)( (char *)List_HdrP + List_HdrP -> First_Entry_Offset);

printf(″%s\nFollowing is the Recipient History Information::\n″ ,Separator);

Elem_Indx = 1;Temp_Num_Entries = List_HdrP -> Total_Num_Of_Entries;

346 AnyMail/400 MSF

Page 371: AnyMail/400 Mail Server Framework Developer Guide January 1995

while ( Elem_Indx <= Temp_Num_Entries){

printf( ″Recipient-Hist Element <%d>: %.*s\n″ , Elem_Indx,(Rcpnt_HistP -> Addr_Length),

((char *)Rcpnt_HistP + Rcpnt_HistP -> Recipient_Displacement) );

Temp_SPIN_Length = Rcpnt_HistP -> SPIN_Length;if (Temp_SPIN_Length > 0)

printf( ″SPIN <%d>: %.*s\n″ , Elem_Indx, Temp_SPIN_Length,((char *)Rcpnt_HistP + Rcpnt_HistP -> SPIN_Displacement) );

Rcpnt_HistP = (Qzmf_RCHL0100_t *)( (char *)Rcpnt_HistP +(Rcpnt_HistP -> Entry_Length) );

++Elem_Indx;}

/* Destroy the user space */#pragma exception_handler(Quit_Execution, 0, 0, _C2_MH_ESCAPE)

QUSDLTUS(WORK_SPACE_NAME

, (void *)&Rtv_Error_Code);

#pragma disable_handler

/*******************************************************************//* Finally, extract all the Recepient_Message_Type information from*//* the Recepient_Message_Type list. *//* *//* Though we have enough heap space to start with, it is quite *//* possible that the provided space is not sufficient *//* for a particular message descriptor. *//* *//* It is advisable for fixed retrieval spaces (malloc′ ed or non- *//* auto-extendible user space) to check for the completeness using *//* the Msg_Desc_Total_Length and Bytes_Available fields of the list*//* header. In case of insufficient space given to the Retrieve *//* API, a partial list entry can appear in the retrieved list. *//* And blind pointer manipulation in a partial list can lead to *//* application error. *//*******************************************************************/

/* Set the header pointer */List_HdrP = (Qzmf_Msg_Desc_Hdr0100_t *)

( (Msg_Desc_Attr_Array + 1) -> Msg_Desc_Ptr );

/* Check for completeness */ if (

(List_HdrP -> Msg_Desc_Total_Length) !=(List_HdrP -> Bytes_Available)

){

/*********************************************************//* Incomplete information! We simply quit in this *//* example program. *//* Your application may set up a space of at *//* least (List_HdrP -> Bytes_Available) bytes and call */

Appendix E. An MSF Application — Example 347

Page 372: AnyMail/400 Mail Server Framework Developer Guide January 1995

/* the Retrieve API again to retrieve the full list. *//*********************************************************/printf(″Insufficiant space given to Retrieve-Msg API; ″

″quitting\n″ ) ;exit(1);

}

Rcpnt_Msg_TypP = (Qzmf_MSGL0100_t *)( (char *)List_HdrP + List_HdrP -> First_Entry_Offset);

printf(″%s\nFollowing is the Recipient Message Type Information::\n″ ,Separator);

Elem_Indx = 1;Temp_Num_Entries = List_HdrP -> Total_Num_Of_Entries;while ( Elem_Indx <= Temp_Num_Entries){

printf( ″Recipient Msg Type <%d>: %.*s\n″ , Elem_Indx,sizeof(Qzmf_Type_Value_t),(Rcpnt_Msg_TypP -> Msg_Type) );

Rcpnt_Msg_TypP += 1;++Elem_Indx;

}

/* If needed, you can free the heap space now */free( (void *)((Msg_Desc_Attr_Array + 1) -> Msg_Desc_Ptr) );

/* Set the proper return code to MSF job before finishing */*Return_Code = QZMF_CONTINUE;

} /* end of main */

/**********************************************************************//************ end of file TRTVMSG ********************************//**********************************************************************/

Integrating the ProgramsThe programs created earlier are intended to be MSF exit point programs.Remember that the Change Mail Message API and the Retrieve Mail MessageAPI can only be called from exit point programs.

The process of registering MSF exit point programs is explained in Chapter 3,“Mail Server Framework Configuration” on page 18. The sample exit pointprograms are to get activated for the test messages only. You do not want tointerfere with the normal mail messages flowing through MSF. For this reason,you want to do the following:

• Use the sample data type values as exit point program data.• As a cautious approach, configure the sample exit point programs with a

smaller program number than the programs already configured at that exitpoint. In this example, 1 is the value for the program number parameter ofthe Add Exit Program (ADDEXITPGM) command. However, you can chooseany other value as long as there is no other catch-all11 exit point program

11 an MSF exit point program with SPCL01009999 as its data.

348 AnyMail/400 MSF

Page 373: AnyMail/400 Mail Server Framework Developer Guide January 1995

configured with a smaller program number than the sample exit pointprograms.

Table 32 shows the exit program data and MSF exit point associated with eachof the sample exit point programs.

Table 32. Example MSF Exit Point Programs

Exit PointProgram

MSF Exit Point Exit Program Data

TLSTEXPN List Expansion SPCL010001TV

TADDRSLN Address Resolution SPCL010001TV

TRTVMSG Local Delivery SPCL010002TV

TRTVMSG Message Forwarding SPCL010002TV

After registering the sample exit point programs using the Work withRegistration Info (WRKREGINF) command, you must restart MSF by issuing theEnd Mail Server Framework (ENDMSF) command followed by the Start MailServer Framework (STRMSF) command. Restarting MSF updates the MSFconfiguration with the sample exit point programs and the sample data typesthat were added in “Type Configuration Program — Example” on page 297.

Running the Sample ProgramsTo test the sample exit point programs, call the TCRTMSG program to create atest MSF message. The test message will flow through MSF and be processedby the sample exit point programs.

There can be more than one MSF job running in your system. You can locatethe jobs by using the Work with Active Jobs (WRKACTJOB) command andlooking for the QMSF jobs in the QSYSWRK subsystem. The test MSF messageis processed by one of the QMSF jobs. The printf statements of our TRTVMSGexit point program will get written in QPRINT files, and only one QMSF job willhave those QPRINT files. There will be one QPRINT file for the local delivery exitpoint program and one for the message forwarding exit point program. TheQPRINT files can be located by using option 8 (Work with spooled files) in frontof the QMSF jobs on the Work with Active Jobs (WRKACTJOB) display.

The first QPRINT file should look like this:

I got invoked at: QIBM_QZMFMSF_LCL_DEL===================+++++++++++++++++++++++++=======================Following is the Originator Information::Originator <1>: MIKE WILLIAMS===================+++++++++++++++++++++++++=======================Following is the Envelope Information::Envelope <1> follows::GET Length: 71, GET Number of Attributes: 3GET Priority: Normal PriorityGET Sensitivity: Not SensitiveGET Subject: Team Meeting Notice===================+++++++++++++++++++++++++=======================Following is the Recipient Information::Recipient <1>: MARY RICHARDSSPIN <1>: MARY RICHARDS: ROCHESTER MachineRecipient <2>: JOHN SMITH

Appendix E. An MSF Application — Example 349

Page 374: AnyMail/400 Mail Server Framework Developer Guide January 1995

SPIN <2>: JOHN SMITH: ROCHESTER Machine===================+++++++++++++++++++++++++=======================Following is the Recipient History Information::Recipient-Hist Element <1>: DEPT44ARecipient-Hist Element <2>: MARY RICHARDSSPIN <2>: MARY RICHARDS: ROCHESTER MachineRecipient-Hist Element <3>: JOHN SMITHSPIN <3>: JOHN SMITH: ROCHESTER MachineRecipient-Hist Element <4>: CHARLES RICESPIN <4>: CHARLES RICE: NEWYORK Machine===================+++++++++++++++++++++++++=======================Following is the Recipient Message Type Information::Recipient Msg Type <1>: 02TV

Only the first two recipients (which have statuses of local) are passed on to thelocal delivery exit point program by MSF. The entire set of recipients and theoriginal distribution list are in the recipient history list.

The second QPRINT file should look like this:

I got invoked at: QIBM_QZMFMSF_MSG_FWD===================+++++++++++++++++++++++++=======================Following is the Originator Information::Originator <1>: MIKE WILLIAMS===================+++++++++++++++++++++++++=======================Following is the Envelope Information::Envelope <1> follows::GET Length: 71, GET Number of Attributes: 3GET Priority: Normal PriorityGET Sensitivity: Not SensitiveGET Subject: Team Meeting Notice===================+++++++++++++++++++++++++=======================Following is the Recipient Information::Recipient <1>: CHARLES RICESPIN <1>: CHARLES RICE: NEWYORK Machine===================+++++++++++++++++++++++++=======================Following is the Recipient History Information::Recipient-Hist Element <1>: DEPT44ARecipient-Hist Element <2>: MARY RICHARDSSPIN <2>: MARY RICHARDS: ROCHESTER MachineRecipient-Hist Element <3>: JOHN SMITHSPIN <3>: JOHN SMITH: ROCHESTER MachineRecipient-Hist Element <4>: CHARLES RICESPIN <4>: CHARLES RICE: NEWYORK Machine===================+++++++++++++++++++++++++=======================Following is the Recipient Message Type Information::Recipient Msg Type <1>: 02TV

Note that MSF passed only the third recipient (which has a status of remote) tothe message forwarding exit point program.

Program to Reserve and Query Message — ExampleThe TRSRVMSG file is an MSF program that uses the following MSF APIs.

• Reserve Mail Message Identifier (QzmfRsvMailMsgId).• Create Mail Message (QzmfCrtMailMsg).• Query Mail Message Identifier (QzmfQryMailMsgId).• Complete Creation Sequence (QzmfCrtCmpMailMsg).

350 AnyMail/400 MSF

Page 375: AnyMail/400 Mail Server Framework Developer Guide January 1995

• Remove Reserved Mail Message Identifier (QzmfRmvRsvMailMsgId).

To create the program, you need to bind this module with the TCRTMOD moduleshown in “Module and Program to Create MSF Messages — Example” onpage 308.

/*********************************************************************//* Example: Reserve Mail Message Identifier (QzmfRsvMailMsgId) API *//* *//* Sample program that demonstrates the use of reserved *//* message identifiers. *//* *//* The APIs considered are *//* (a) Reserve Mail Message Identifier, *//* (b) Create Mail Message, *//* (c) Query Mail Message Identifier, *//* (d) Remove Reserved Mail Message Identifier, and *//* (e) Complete Creation Sequence *//* *//* File Name: TRSRVMSG *//* *//*********************************************************************/

#pragma strings(readonly)

#include <stdio.h>#include <string.h>#include <stdlib.h>

#include <except.h>

#include <qusec.h>

#include <qzmfasrv.h>

typedef struct{ Qus_EC_t Error; char Exception_Data[1];} Error_Code_t; /* We will expect exceptions to be */

/* signalled and not care about *//* the returned codes */

/*-------------------------------------------------------------------*//* Imported functions *//*-------------------------------------------------------------------*/

extern void Create_A_Reserved_Message(Qzmf_Msg_Id_t

);

/*--------------------------------------------------------------------*//* File-scoped functions *//*--------------------------------------------------------------------*

static void Quit_Execution(void

);

Appendix E. An MSF Application — Example 351

Page 376: AnyMail/400 Mail Server Framework Developer Guide January 1995

static void Print_Qry_Status(Qzmf_Msg_Id_Qry_Status_t

);

/*--------------------------------------------------------------------*//* Executable code *//*--------------------------------------------------------------------*/

/**********************************************************************//* General exception handler function. The program ends *//* prematurely after printing a general error statement. *//**********************************************************************/

static void Quit_Execution(void

){

printf(″Unexpected CPFxxxx exception from MSF Create Message ″″API invocation; quitting\n″ ) ;

exit(1);} /* end of Quit_Execution Exception Handler */

/**********************************************************************/

/**********************************************************************//* The Print_Qry_Status function prints the result of an MSF message *//* query in a readable form. *//**********************************************************************/

static void Print_Qry_Status(Qzmf_Msg_Id_Qry_Status_t Msg_Qry_Status

){

switch (Msg_Qry_Status){

case QZMF_MSG_ID_UNKNOWN:printf(″Message ID is unknown to MSF.\n″ ) ;break;

case QZMF_MSG_ID_CREATED:printf(″Message ID has been created by MSF.\n″ ) ;break;

case QZMF_MSG_ID_RSVRD_AND_CREATED:printf(″Message ID has been reserved and created.\n″ ) ;break;

case QZMF_MSG_ID_RSVRD_AND_PROCSSD:printf(″Message ID has been created, and″

″processed by MSF, but not yet removed.\n″ ) ;break;

case QZMF_MSG_ID_RESERVED:

352 AnyMail/400 MSF

Page 377: AnyMail/400 Mail Server Framework Developer Guide January 1995

printf(″Message ID has been reserved but not yet created.\n″ ) ;break;

default:printf(″Unknown Status passed: %c; quitting″ , Msg_Qry_Status);exit(1);

} /* end of switch on different Query statuses */

} /* end of Print_Qry_Status function */

/**********************************************************************/

/**********************************************************************//**********************************************************************//**************** main ****************************************//**********************************************************************//**********************************************************************/

void main(void){

Qzmf_Msg_Id_tMsg_Id

, Msg_Id_To_Remove;

Qzmf_Msg_Id_Qry_Status_tMsg_Qry_Status

, Msg_Qry_Status1;

Error_Code_tReserve_Error_Code;

/* Specify exceptions should be signalled from the API *//* rather than using return codes. */Reserve_Error_Code.Error.Bytes_Provided = 0;

/* Reserve two MSF message identifiers */#pragma exception_handler(Quit_Execution, 0, 0, _C2_MH_ESCAPE)

QzmfRsvMailMsgId((void*)Msg_Id

, QZMF_RSV_MAIL_MSG_FORMAT, (void *)(&Reserve_Error_Code)

);

QzmfRsvMailMsgId((void*)Msg_Id_To_Remove

, QZMF_RSV_MAIL_MSG_FORMAT, (void *)(&Reserve_Error_Code)

);

#pragma disable_handler

/* Print the reserved message IDs */

Appendix E. An MSF Application — Example 353

Page 378: AnyMail/400 Mail Server Framework Developer Guide January 1995

printf(″The First Reserved Msg Id: %.32s\n″ , Msg_Id);printf(″The Second Reserved Msg Id: %.32s\n″ , Msg_Id_To_Remove);

/* Create an MSF message with Msg_Id as its ID */Create_A_Reserved_Message(

Msg_Id);

/* Inquire about the reserved messages′ statuses in MSF */#pragma exception_handler(Quit_Execution, 0, 0, _C2_MH_ESCAPE)

QzmfQryMailMsgId((void *)Msg_Id

, QZMF_QRY_MAIL_MSG_FORMAT, &Msg_Qry_Status, (void *)(&Reserve_Error_Code)

);

QzmfQryMailMsgId((void *)Msg_Id_To_Remove

, QZMF_QRY_MAIL_MSG_FORMAT, &Msg_Qry_Status1, (void *)(&Reserve_Error_Code)

);

#pragma disable_handler

Print_Qry_Status(Msg_Qry_Status

);

Print_Qry_Status(Msg_Qry_Status1

);

/****************************************************************//* Now we are ready to remove the reserved message IDs from MSF.*//* For the unused reserved message ID, call the Remove Reserved *//* Mail Message Identifier API. For the other MSF message, *//* we need to use the Complete Creation Sequence API. *//****************************************************************/

#pragma exception_handler(Quit_Execution, 0, 0, _C2_MH_ESCAPE)

QzmfCrtCmpMailMsg((void *)Msg_Id

, QZMF_CRT_CMP_MAIL_MSG_FORMAT, (void *)(&Reserve_Error_Code)

);

#pragma disable_handler

#pragma exception_handler(Quit_Execution, 0, 0, _C2_MH_ESCAPE)

QzmfRmvRsvMailMsgId((void *)Msg_Id_To_Remove

, QZMF_RMV_RSV_MAIL_MSG_FORMAT, (void *)(&Reserve_Error_Code)

);

354 AnyMail/400 MSF

Page 379: AnyMail/400 Mail Server Framework Developer Guide January 1995

#pragma disable_handler

} /* end of main */

/**********************************************************************//************ end of file TRSRVMSG ******************************//**********************************************************************/

The TRSRVMSG program can be ran interactively. A run of the program shouldproduce something similar to the following on your display.

The First Reserved Msg Id: ID 10007259410251604060000000008The Second Reserved Msg Id: ID 10007259410251604060000000009Message ID has been reserved and created.Message ID has been reserved but not yet created.Press ENTER to end terminal session.

Removal of Test TypesAfter testing the sample exit point programs, you may want to remove thesample data types and sample exit point programs from your MSF configuration.To remove the data types, re-create the TCFGTYPE program after youuncomment the exit(0) statement. The exit(0) statement in the TCFGTYPE file isshown on page 305 and appears as follows:

/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*//* For deleting the added test data types, the following exit *//* statement can be uncommented before creating the test type *//* cleanup program. *//* *//* exit(0); *//* *//*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/

Name the newly created program TDLTCFG. To restore your MSF configurationto the state you had before the start of testing, do the following:

1. Follow the guidelines of Chapter 3, “Ma i l Server Framework Configuration”on page 18 to unregister the sample exit point programs.

2. Run program TDLTCFG to remove the sample data types. 3. Restart MSF by issuing the ENDMSF command followed by the STRMSF

command.

Appendix E. An MSF Application — Example 355

Page 380: AnyMail/400 Mail Server Framework Developer Guide January 1995

Appendix F. Qzmf Header File

This appendix contains the Qzmf header file. This header file contains typedefinitions which are provided for use with the mail server framework.

#ifndef _QZMF_H#define _QZMF_H

/*** START HEADER FILE SPECIFICATIONS ********************************//* *//* Header File Name: H/QZMF *//* *//* Descriptive Name: Mail Server Framework (MSF) API and Exit Pgm. *//* *//* 5763-SS1 (C) Copyright IBM Corp. 1994,1994 *//* All rights reserved. *//* US Government Users Restricted Rights - *//* Use, duplication or disclosure restricted *//* by GSA ADP Schedule Contract with IBM Corp. *//* *//* Licensed Materials-Property of IBM *//* *//* Description: Include header file for the common structures and *//* constants for MSF APIs and Exit Programs. *//* *//* Header Files Included: *//* H/POINTER *//* H/LIMITS *//* *//* Macros List: None. *//* *//* Structure List: *//* *//* Qzmf_Exit_Pgm_Lib_Name_t *//* Qzmf_Date_t *//* Qzmf_Time_t *//* Qzmf_System_Timestamp_t *//* *//* Qzmf_GET_GMT_Delta_t *//* Qzmf_GET_Timestamp_t *//* Qzmf_GET_t *//* Qzmf_GET_Generic_Attrbt_t *//* Qzmf_GET_Int_Attrbt_t *//* Qzmf_GET_Timestamp_Attrbt_t *//* Qzmf_GET_Subject_Attrbt_t *//* Qzmf_GET_Signtr_Attrbt_t *//* Qzmf_GET_Note_Attrbt_t *//* Qzmf_GET_Appl_UId__Attrbt_t *//* Qzmf_GET_Appl_Rf_UId_Attrbt_t *//* Qzmf_GET_Ref_Attrbt_t *//* Qzmf_GET_Attach_Attrbt_t *//* *//* Qzmf_FSO_t *//* *//* Qzmf_Msg_Desc_Attrbt_Entity_t *//* Qzmf_Msg_Desc_Hdr0100_t *//* *//* Qzmf_ORGL0100_t */

356 Copyright IBM Corp. 1995

Page 381: AnyMail/400 Mail Server Framework Developer Guide January 1995

/* Qzmf_ENVL0100_t *//* Qzmf_RCPL0100_t *//* Qzmf_ROAL0100_t *//* Qzmf_RTAL0100_t *//* Qzmf_RPYL0100_t *//* Qzmf_ORCL0100_t *//* Qzmf_ATTL0100_t *//* Qzmf_MSGL0100_t *//* *//* Qzmf_Orgntr0100_Msg_Desc_t *//* Qzmf_Envlp0100_Msg_Desc_t *//* Qzmf_Rcpt0100_Msg_Desc_t *//* Qzmf_Rpt_O_Addr0100_Msg_Desc_t *//* Qzmf_Rpt_T_Addr0100_Msg_Desc_t *//* Qzmf_Rply_T_Addr0100_Msg_Desc_t *//* Qzmf_Org_Rcp_Addr0100_Msg_Desc_t *//* Qzmf_Attch0100_Msg_Desc_t *//* Qzmf_Msg_Type0100_Msg_Desc_t *//* *//* Function Prototype List: None *//* *//* Change Activity: *//* *//* CFD List: *//* *//* FLAG REASON LEVEL DATE PGMR CHANGE DESCRIPTION *//* ---- ------------ ----- ------ ------- ------------------------ *//* $A0= D9129400 3D10 940408 BANER : New Include for V3R1 *//* $A1= P3967695 3P10 940920 FGOH : Add reply requested flag *//* *//* End CFD List. *//* *//* Additional notes about the Change Activity *//* *//* End Change Activity. *//* *//*** END HEADER FILE SPECIFICATIONS **********************************/

#include <pointer.h>#include <limits.h>

typedef char Qzmf_Type_Value_t[4];typedef char Qzmf_Format_Name_t[8];typedef char Qzmf_Msg_Id_t[32];typedef long int Qzmf_CCSID_t;typedef char Qzmf_Exit_Point_t[20];

typedef _Packed struct Qzmf_Exit_Pgm_Lib_Name{

char Program_Name[10];char Library_Name[10];

} Qzmf_Exit_Pgm_Lib_Name_t;

typedef char Qzmf_Type_Group_t[2];typedef char Qzmf_Type_Name_t[8];typedef char Qzmf_User_Space_t[20];

Appendix F. Qzmf Header File 357

Page 382: AnyMail/400 Mail Server Framework Developer Guide January 1995

typedef _Packed struct Qzmf_Date{

char Year[2];char Month[2];char Day[2];

} Qzmf_Date_t;

typedef _Packed struct Qzmf_Time{

char Hour[2];char Minute[2];char Second[2];

} Qzmf_Time_t;

typedef _Packed struct Qzmf_System_Timestamp{

char Century_Digit;Qzmf_Date_t Date;Qzmf_Time_t Time;char Milli_Second[3];

} Qzmf_System_Timestamp_t;

typedef char Qzmf_Msg_Id_Qry_Status_t;

/*-------------------------------------------------------------------*//*** Following are the Valid MSF Configuration API Type Groups ***//*-------------------------------------------------------------------*/

#define QZMF_ADDR_TYPE_GROUP ″01″#define QZMF_MSG_TYPE_GROUP ″02″#define QZMF_ENV_TYPE_GROUP ″03″#define QZMF_ATTACH_TYPE_GROUP ″04″

#define QZMF_LST_SEL_NO_TYPE_GROUP ″ ″

#define QZMF_TYPE_GROUP_LENGTH (sizeof(Qzmf_Type_Group_t))

/*-------------------------------------------------------------------*//*** Following are the Valid MSF Configuration API Format Names ***//*-------------------------------------------------------------------*/

#define QZMF_ADD_CONFIG_FORMAT ″ADDC0100″#define QZMF_DEL_CONFIG_FORMAT ″DLTC0100″#define QZMF_LST_SELECTION_FORMAT ″LSTC0100″#define QZMF_LST_RECEIVER_FORMAT ″LSTL0100″

#define QZMF_MSF_CONFIG_FMT_LENGTH (sizeof(Qzmf_Format_Name_t))

/*-------------------------------------------------------------------*//*** Following are the Valid MSF Messaging API Format Names ***//*-------------------------------------------------------------------*/

#define QZMF_CRT_MAIL_MSG_FORMAT ″CRTM0100″#define QZMF_RTV_MAIL_MSG_FORMAT ″RTVM0100″#define QZMF_CHG_MAIL_MSG_FORMAT ″CHGM0100″

358 AnyMail/400 MSF

Page 383: AnyMail/400 Mail Server Framework Developer Guide January 1995

#define QZMF_RSV_MAIL_MSG_FORMAT ″RSVF0100″#define QZMF_QRY_MAIL_MSG_FORMAT ″QRYF0100″#define QZMF_RMV_RSV_MAIL_MSG_FORMAT ″RMVF0100″#define QZMF_CRT_CMP_MAIL_MSG_FORMAT ″CCMP0100″

#define QZMF_MSF_MSG_API_FMT_LENGTH (sizeof(Qzmf_Format_Name_t))

/*-------------------------------------------------------------------*//** Various Format definitions of the Message Descriptor Structure **//*-------------------------------------------------------------------*/

#define QZMF_ORIGINATOR_LIST_FMT ″ORGL0100″#define QZMF_ENVELOPE_LIST_FMT ″ENVL0100″#define QZMF_RECIPIENT_LIST_FMT ″RCPL0100″#define QZMF_RECIPIENT_HIST_FMT ″RCHL0100″#define QZMF_REPORT_ON_ADDR_FMT ″ROAL0100″#define QZMF_REPORT_TO_ADDR_FMT ″RTAL0100″#define QZMF_REPLY_TO_ADDR_FMT ″RPYL0100″#define QZMF_ORIGINAL_RECIPIENT_FMT ″ORCL0100″#define QZMF_ATTACH_REF_FMT ″ATTL0100″#define QZMF_MSG_TYPE_LIST_FMT ″MSGL0100″#define QZMF_USR_EXT_HIST_FMT ″EXCH0100″#define QZMF_CRTN_ATTRB_FMT ″CRTA0100″

#define QZMF_MSG_DESC_FMT_LENGTH (sizeof(Qzmf_Format_Name_t))

/*-------------------------------------------------------------------*//***** Different Distribution Types associated with Recipients ****//*-------------------------------------------------------------------*/

#define QZMF_DIST_TYPE_NORMAL 0#define QZMF_DIST_TYPE_CC 1#define QZMF_DIST_TYPE_BCC 2

/*-------------------------------------------------------------------*//******* Different Statuses associated with Recipient Entries ******//*-------------------------------------------------------------------*/

#define QZMF_STATUS_FORWARDED 1#define QZMF_STATUS_IGNORE 2#define QZMF_STATUS_LOCAL 3#define QZMF_STATUS_NON_DELV 4#define QZMF_STATUS_SECRTY_VIOLATION 5#define QZMF_STATUS_REPROCESS -1

/*-------------------------------------------------------------------*//****** Different Recipient Statuses (see RCHL0100 Format) *****//*-------------------------------------------------------------------*/

#define QZMF_STATUS_CHILDREN 0#define QZMF_STATUS_PARENT 1

/*-------------------------------------------------------------------*//**** Change Indicator Possible Values (see EXCH0100 Format) ****//*-------------------------------------------------------------------*/

Appendix F. Qzmf Header File 359

Page 384: AnyMail/400 Mail Server Framework Developer Guide January 1995

#define QZMF_MSG_UNCHANGED ′ 0 ′#define QZMF_MSG_CHANGED ′ 1 ′

/*-------------------------------------------------------------------*//**** Possible values of Msg-Id Status (see QzmfQryMailMsgId API) ****//*-------------------------------------------------------------------*/

#define QZMF_MSG_ID_UNKNOWN ′ 0 ′#define QZMF_MSG_ID_CREATED ′ 1 ′#define QZMF_MSG_ID_RSVRD_AND_CREATED ′ 2 ′#define QZMF_MSG_ID_RSVRD_AND_PROCSSD ′ 3 ′#define QZMF_MSG_ID_RESERVED ′ 4 ′

/*-------------------------------------------------------------------*//**** Addition Indicator value in the Unique_Id ****//* (see QzmfChgMailMsg API) *//*-------------------------------------------------------------------*/

#define QZMF_UNIQUE_ID_ADD_ENTRY -1

/*-------------------------------------------------------------------*//**** Following are some Maximum values allowed for various ****//* Message Descriptor Entries *//*-------------------------------------------------------------------*/

#define QZMF_MAX_MSG_DESC_SIZE 16000000#define QZMF_MAX_RECIPIENT_ENTRIES 32768#define QZMF_MAX_ADDRESS_LENGTH 1024#define QZMF_MAX_SPIN_LENGTH 256

/*-------------------------------------------------------------------*//**** Following are the Valid SNAPIN Exit Point Names ****//*-------------------------------------------------------------------*/

#define QZMF_LIST_EXPANSION ″QIBM_QZMFMSF_LST_EXP″#define QZMF_ADDRESS_RESOLUTION ″QIBM_QZMFMSF_ADR_RSL″#define QZMF_ENVELOPE_PROCESSING ″QIBM_QZMFMSF_ENL_PSS″#define QZMF_ATTACHMENT_CONVERSION ″QIBM_QZMFMSF_ATT_CNV″#define QZMF_SECURITY_AND_AUTHORITY ″QIBM_QZMFMSF_SEC_AUT″#define QZMF_LOCAL_DELIVERY ″QIBM_QZMFMSF_LCL_DEL″#define QZMF_MESSAGE_FORWARDING ″QIBM_QZMFMSF_MSG_FWD″#define QZMF_NON_DELIVERY ″QIBM_QZMFMSF_NON_DEL″#define QZMF_ATTACHMENT_MANAGEMENT ″QIBM_QZMFMSF_ATT_MGT″#define QZMF_ACCOUNTING ″QIBM_QZMFMSF_ACT ″

/*-------------------------------------------------------------------*//**** Following two are the remaining User Exit Point Names ****//*-------------------------------------------------------------------*/

#define QZMF_VALIDATE_DATA ″QIBM_QZMFMSF_VLD_TYP″#define QZMF_TRACK_MAIL_CHANGE ″QIBM_QZMFMSF_TRK_CHG″

#define QZMF_EXIT_POINT_LENGTH (sizeof(Qzmf_Exit_Point_t))

360 AnyMail/400 MSF

Page 385: AnyMail/400 Mail Server Framework Developer Guide January 1995

/*-------------------------------------------------------------------*//**** Following are the MSF Exit Point/Program-Data Formats ****//*-------------------------------------------------------------------*/

#define QZMF_EXIT_POINT_FORMAT ″MSFF0100″#define QZMF_SNAPIN_FORMAT ″SPCL0100″#define QZMF_VALIDATE_DATA_FORMAT ″VDFF0100″#define QZMF_TRACK_MAIL_CHANGE_FORMAT ″TCMM0100″

#define QZMF_EXIT_FMT_LENGTH (sizeof(Qzmf_Format_Name_t))

/*-------------------------------------------------------------------*//**** Following can be the returned code after a SNAPIN Call ****//*-------------------------------------------------------------------*/

#define QZMF_CONTINUE 0#define QZMF_BACKOUT_CHANGE 1#define QZMF_END_MSF_JOB 2#define QZMF_END_MSG_PROCESSING 3

/*-------------------------------------------------------------------*//**** Following can be the returned code from Track Change Exit *****//*-------------------------------------------------------------------*/

#define QZMF_TRACK_OK 0#define QZMF_TRACK_INVALID_DATA 1#define QZMF_TRACK_SEVERE_ERR 2

/*********************************************************************//**** Following are some constants and type definitions ****//**** pertaining to the IBM GET (Generic Envelope Type) ****//*********************************************************************/

#define QZMF_GET_INT_ATTRIBUTE_LENGTH \sizeof(Qzmf_GET_Int_Attrbt_t)#define QZMF_GET_TIMESTAMP_ATTRIBUTE_LENGTH \sizeof(Qzmf_GET_Timestamp_Attrbt_t)

/*-------------------------------------------------------------------*//**** Following are the valid values for GMT Delta Indicator in ****//**** IBM GET ****//*-------------------------------------------------------------------*/

#define QZMF_GET_GMT_DELTA_POSITIVE ′ 0 ′#define QZMF_GET_GMT_DELTA_NEGATIVE ′ 1 ′#define QZMF_GET_GMT_DELTA_UNSPECIFIED ′ 2 ′

/*-------------------------------------------------------------------*//**** Following are the predefined Attachment Types in IBM GET ****//*-------------------------------------------------------------------*/

Appendix F. Qzmf Header File 361

Page 386: AnyMail/400 Mail Server Framework Developer Guide January 1995

#define QZMF_GET_CMC_ATTACHMENT ″CMC″#define QZMF_GET_OID_ATTACHMENT ″OID″#define QZMF_GET_BLT_ATTACHMENT ″BLT″

/*-------------------------------------------------------------------*//**** Following are the valid GET Attribute Types ****//*-------------------------------------------------------------------*/

enum Qzmf_GET_Attrbt_Type{

Qzmf_GET_Subject_Id = 1,Qzmf_GET_Creation_Tmstmp_Id = 2,

Qzmf_GET_Expiration_Tmstmp_Id = 3, Qzmf_GET_Reply_By_Tmstmp_Id = 4, Qzmf_GET_Delivery_Type_Id = 5, Qzmf_GET_Priority_Type_Id = 6, Qzmf_GET_Elctrnc_Signature_Id = 7, Qzmf_GET_Sensitivity_Type_Id = 8, Qzmf_GET_Return_Contents_Id = 9, Qzmf_GET_Non_Delivery_Id = 10, Qzmf_GET_Delivery_Report_Id = 11, Qzmf_GET_Receipt_Notif_Id = 12, Qzmf_GET_Forward_Notif_Id = 13, Qzmf_GET_Encryption_Id = 14, Qzmf_GET_Conversion_Id = 15, Qzmf_GET_No_Loss_Conv_Id = 16, Qzmf_GET_Disclose_Rcpnts_Id = 17, Qzmf_GET_Alternate_Rcpnts_Id = 18, Qzmf_GET_Reassign_Rcpnts_Id = 19, Qzmf_GET_Expand_Dist_List_Id = 20, Qzmf_GET_Note_Content_Id = 21, Qzmf_GET_Msg_Size_Id = 22, Qzmf_GET_Appl_Uniq_Id_Id = 23, Qzmf_GET_Appl_Ref_Uniq_Id_Id = 24, Qzmf_GET_Reference_Id = 25, Qzmf_GET_Attachment_Id = 26, Qzmf_GET_Importance_Id = 27, Qzmf_GET_ODF_Id = 98};

/*-------------------------------------------------------------------*//**** Following Type Definitions are used to define various IBM ****//**** GET Attributes ****//*-------------------------------------------------------------------*/

typedef enum Qzmf_GET_Delv_Type_Values{

Qzmf_New_Message = 0,Qzmf_Del_Report = 1,Qzmf_Non_Del_Report = 2,Qzmf_Receipt_Notify = 3,Qzmf_Forward_Notify = 4,Qzmf_Delv_Long_Force = LONG_MAX

} Qzmf_GET_Delv_Type_Values_t;

typedef enum Qzmf_GET_Priority_Values{

Qzmf_Normal_Priority = 0,

362 AnyMail/400 MSF

Page 387: AnyMail/400 Mail Server Framework Developer Guide January 1995

Qzmf_Non_Urgent_Priority = 1,Qzmf_Urgent_Priority = 2,Qzmf_Prio_Long_Force = LONG_MAX

} Qzmf_GET_Priority_Values_t;

typedef enum Qzmf_GET_Sensitivity_Values{

Qzmf_Not_Sensitive = 0,Qzmf_Personal = 1,Qzmf_Private = 2,Qzmf_Confidential = 3,Qzmf_Senstv_Long_Force = LONG_MAX

} Qzmf_GET_Sensitivity_Values_t;

typedef enum Qzmf_GET_Rtrn_Cntnts_Values{ Qzmf_Dont_Return_Contents = 0, Qzmf_Return_Contents = 1, Qzmf_Ret_Cnt_Long_Force = LONG_MAX} Qzmf_GET_Rtrn_Cntnts_Values_t;

typedef enum Qzmf_GET_Non_Delv_Values{

Qzmf_No_Non_Delv_Report = 0,Qzmf_Non_Delv_Report = 1,Qzmf_Non_Delv_Long_Force = LONG_MAX

} Qzmf_GET_Non_Delv_Values_t;

typedef enum Qzmf_GET_Delv_Rpt_Values{

Qzmf_No_Delivery_Report = 0,Qzmf_Delivery_Report = 1,Qzmf_Delv_Rep_Long_Force = LONG_MAX

} Qzmf_GET_Delv_Rpt_Values_t;

typedef enum Qzmf_GET_Rcpt_Notif_Values{

Qzmf_No_Receipt_Notif = 0,Qzmf_Receipt_Notif = 1,Qzmf_Rcpt_Ntf_Long_Force = LONG_MAX

} Qzmf_GET_Rcpt_Notif_Values_t;

typedef enum Qzmf_GET_Frwrd_Notif_Values{

Qzmf_No_Forward_Notif = 0,Qzmf_Forward_Notif = 1,

Qzmf_Frwrd_Ntf_Long_Force = LONG_MAX} Qzmf_GET_Frwrd_Notif_Values_t;

typedef enum Qzmf_GET_Encryption_Values{

Qzmf_Not_Encrypted = 0,Qzmf_Encrypted = 1,Qzmf_Encryption_Force = LONG_MAX

} Qzmf_GET_Encryption_Values_t;

typedef enum Qzmf_GET_Conversion_Values{

Qzmf_Allow_Conversion = 0,

Appendix F. Qzmf Header File 363

Page 388: AnyMail/400 Mail Server Framework Developer Guide January 1995

Qzmf_Prohibit_Conversion = 1,Qzmf_Cnv_Long_Force = LONG_MAX

} Qzmf_GET_Conversion_Values_t;

typedef enum Qzmf_GET_Loss_Cnvrsn_Values{

Qzmf_Allow_Loss_Conv = 0,Qzmf_Not_Allow_Loss_Conv = 1,Qzmf_Loss_Cnv_Long_Force = LONG_MAX

} Qzmf_GET_Loss_Cnvrsn_Values_t;

typedef enum Qzmf_GET_Dscl_Rcpnts_Values{

Qzmf_Disclose_Rcpnts = 0,Qzmf_Not_Disclose_Rcpnts = 1,Qzmf_Discl_Long_Force = LONG_MAX

} Qzmf_GET_Dscl_Rcpnts_Values_t;

typedef enum Qzmf_GET_Alt_Rcpnts_Values{

Qzmf_Alternate_Rcpnts = 0,Qzmf_No_Alternate_Rcpnts = 1,

Qzmf_Alt_Rcpnt_Long_Force = LONG_MAX} Qzmf_GET_Alt_Rcpnts_Values_t;

typedef enum Qzmf_GET_Rsgn_Rcpnts_Values{

Qzmf_Reassign_Rcpnts = 0,Qzmf_No_Reassign_Rcpnts = 1,Qzmf_Rsgn_Rcpnt_Long_Force = LONG_MAX

} Qzmf_GET_Rsgn_Rcpnts_Values_t;

typedef enum Qzmf_GET_Expand_DL_Values{

Qzmf_Expand_Dist_List = 0,Qzmf_No_Expand_Dist_List = 1,Qzmf_Expnd_DL_Long_Force = LONG_MAX

} Qzmf_GET_Expand_DL_Values_t;

typedef enum Qzmf_GET_Importance_Values{

Qzmf_Importance_Normal = 0,Qzmf_Importance_Low = 1,Qzmf_Importance_High = 2,Qzmf_Importance_Long_Force = LONG_MAX

} Qzmf_GET_Importance_Values_t;

typedef _Packed struct Qzmf_GET_GMT_Delta{

char Delta_Hour[2];char Delta_Minute[2];

} Qzmf_GET_GMT_Delta_t;

typedef _Packed struct Qzmf_GET_Timestamp{

char Century_Digit;Qzmf_Date_t Date;Qzmf_Time_t Time;char GMT_Delta_Indctr;

364 AnyMail/400 MSF

Page 389: AnyMail/400 Mail Server Framework Developer Guide January 1995

Qzmf_GET_GMT_Delta_t GMT_Delta;} Qzmf_GET_Timestamp_t;

/*********************************************************************//* Type Definition for the GET Envelope *//**** ****//* NOTE: The following type definition only defines the fixed *//* portion of the format. Any varying length field will *//* have to be defined by the user. *//*********************************************************************/

typedef _Packed struct Qzmf_GET{

long int GET_Length;long int First_Attribute_Offset;long int Num_Of_Attributes;

/*char GET_Attribute[];*/ /* varying length */} Qzmf_GET_t;

/*********************************************************************//* Type Definition for the GET Generic Attribute Structure *//**** ****//* NOTE: The following type definition only defines the fixed *//* portion of the format. Any varying length field will *//* have to be defined by the user. *//*********************************************************************/

typedef _Packed struct Qzmf_GET_Generic_Attrbt{

long int Attribute_Length;long int Attribute_Id;

/*char Attribute[];*/ /* varying length */} Qzmf_GET_Generic_Attrbt_t;

/*-------------------------------------------------------------------*//**** Type definitions for the Integral Type GET Attributes ****//*-------------------------------------------------------------------*/

typedef _Packed struct Qzmf_GET_Int_Attrbt{

long int Attribute_Length;long int Attribute_Id;union{

Qzmf_GET_Delv_Type_Values_t GET_Delivery_Info;Qzmf_GET_Priority_Values_t GET_Priority_Info;Qzmf_GET_Sensitivity_Values_t GET_Sensitivity_Info;Qzmf_GET_Rtrn_Cntnts_Values_t GET_Return_Contents_Info;Qzmf_GET_Non_Delv_Values_t GET_Non_Delv_Report_Info;Qzmf_GET_Delv_Rpt_Values_t GET_Delivery_Report_Info;Qzmf_GET_Rcpt_Notif_Values_t GET_Receipt_Notif_Info;Qzmf_GET_Frwrd_Notif_Values_t GET_Forward_Notif_Info;Qzmf_GET_Encryption_Values_t GET_Encryption_Info;Qzmf_GET_Conversion_Values_t GET_Conversion_Info;Qzmf_GET_Loss_Cnvrsn_Values_t GET_No_Loss_Conversion_Info;Qzmf_GET_Dscl_Rcpnts_Values_t GET_Disclose_Rcpnts_Info;

Appendix F. Qzmf Header File 365

Page 390: AnyMail/400 Mail Server Framework Developer Guide January 1995

Qzmf_GET_Alt_Rcpnts_Values_t GET_Alternate_Rcpnts_Info;Qzmf_GET_Rsgn_Rcpnts_Values_t GET_Reassign_Rcpnts_Info;Qzmf_GET_Expand_DL_Values_t GET_Expand_DLs_Info;Qzmf_GET_Importance_Values_t GET_Importance_Info;long int GET_Msg_Size_In_KBytes_Info;

} Qzmf_GET_Int_Attrbt_Info;} Qzmf_GET_Int_Attrbt_t;

/*-------------------------------------------------------------------*//**** Type definitions for the Timestamp Type GET Attributes ****//*-------------------------------------------------------------------*/

typedef _Packed struct Qzmf_GET_Timestamp_Attrbt{

long int Attribute_Length;long int Attribute_Id;union{

Qzmf_GET_Timestamp_t GET_Creation_Timestamp;Qzmf_GET_Timestamp_t GET_Expiration_Timestamp;Qzmf_GET_Timestamp_t GET_Reply_By_Timestamp;

} Qzmf_GET_Tmstmp_Attrbt_Info;} Qzmf_GET_Timestamp_Attrbt_t;

/*********************************************************************//* Type Definitions for the Character-Array Type GET Attributes *//**** ****//* NOTE: The following type definitions only define the fixed *//* portion of the Attributes. Any varying length field will *//* have to be defined by the user. *//*********************************************************************/

typedef _Packed struct Qzmf_GET_Subject_Attrbt{

long int Attribute_Length;long int Attribute_Id;Qzmf_CCSID_t CCSID;long int Subject_Length;

/*char Subject[];*/ /* varying length */} Qzmf_GET_Subject_Attrbt_t;

typedef _Packed struct Qzmf_GET_Signtr_Attrbt{

long int Attribute_Length;long int Attribute_Id;long int Signature_Length;

/*char Elctrnc_Signtr[];*/ /* varying length */} Qzmf_GET_Signtr_Attrbt_t;

typedef _Packed struct Qzmf_GET_Note_Attrbt{

long int Attribute_Length;long int Attribute_Id;Qzmf_CCSID_t CCSID;long int Note_Content_Length;

/*char Note_Content[];*/ /* varying length */} Qzmf_GET_Note_Attrbt_t;

366 AnyMail/400 MSF

Page 391: AnyMail/400 Mail Server Framework Developer Guide January 1995

typedef _Packed struct Qzmf_GET_Appl_UId_Attrbt{

long int Attribute_Length;long int Attribute_Id;long int Appl_Unique_Id_Length;

/*char Appl_Unique_Id[];*/ /* varying length */} Qzmf_GET_Appl_UId_Attrbt_t;

typedef _Packed struct Qzmf_GET_Appl_Rf_UId_Attrbt{

long int Attribute_Length;long int Attribute_Id;long int Appl_Ref_Unique_Id_Length;

/*char Appl_Ref_Unique_Id[];*/ /* varying length */} Qzmf_GET_Appl_Rf_UId_Attrbt_t;

typedef _Packed struct Qzmf_GET_Ref_Attrbt{

long int Attribute_Length;long int Attribute_Id;Qzmf_CCSID_t CCSID;long int Ref_Data_Length;

/*char Ref_Data[];*/ /* varying length */} Qzmf_GET_Ref_Attrbt_t;

typedef _Packed struct Qzmf_GET_Attach_Attrbt{

long int Attribute_Length;long int Attribute_Id;long int Attach_Entry_Length;

/*char Attach_Entry[];*/ /* varying length */} Qzmf_GET_Attach_Attrbt_t;

/*********************************************************************//**** Following are the constants and type definitions ****//**** pertaining to FSO object Attachment Reference ****//*********************************************************************/

#define QZMF_FSO_PROD_ID ″QMSFPRD″

/*********************************************************************//* Type Definition for the FSO Attachment Structure *//*********************************************************************/

typedef _Packed struct Qzmf_FSO{

long int Attach_Ref_Length;long int Reserved1;char FSO_Handle[32];char Access_ID[8];char Product_ID[7];char Reserved2;long int Data_Length;long int FS_Name_Length;char FS_Name[64];long int Resume_Position;

} Qzmf_FSO_t;

Appendix F. Qzmf Header File 367

Page 392: AnyMail/400 Mail Server Framework Developer Guide January 1995

/*********************************************************************//* Type Definition for the Message Descriptor Attribute Entity *//*********************************************************************/

typedef _Packed struct Qzmf_Msg_Desc_Attrbt_Entity{

_SPCPTR Msg_Desc_Ptr;long int Msg_Desc_Length;Qzmf_Format_Name_t Msg_Desc_Format_Name;long int Reserved;

} Qzmf_Msg_Desc_Attrbt_Entity_t;

/*********************************************************************//* Type Definition for the Message Descriptor Common Header *//* for all the relevant XXXX0100 Format Structures *//*********************************************************************/

typedef _Packed struct Qzmf_Msg_Desc_Hdr0100{

long int Msg_Desc_Total_Length;long int Bytes_Available;Qzmf_Format_Name_t Msg_Desc_Format_Name;long int First_Entry_Offset;long int Total_Num_Of_Entries;long int Reserved;

} Qzmf_Msg_Desc_Hdr0100_t;

/*********************************************************************//* Type Definition for the ORGL0100 Format *//**** ****//* NOTE: The following type definition only defines the fixed *//* portion of the format. Any varying length field will *//* have to be defined by the user. *//*********************************************************************/

typedef _Packed struct Qzmf_ORGL0100{

long int Entry_Length;long int Displacement;long int Addr_Length;Qzmf_Type_Value_t Addr_Type;Qzmf_CCSID_t CCSID;long int Unique_Id;long int Ref_Unique_Id;long int Reserved;

/*char Origin_Addr[];*/ /* varying length */} Qzmf_ORGL0100_t;

/*********************************************************************//* Type Definition for the ENVL0100 Format *//**** ****//* NOTE: The following type definition only defines the fixed */

368 AnyMail/400 MSF

Page 393: AnyMail/400 Mail Server Framework Developer Guide January 1995

/* portion of the format. Any varying length field will *//* have to be defined by the user. *//*********************************************************************/

typedef _Packed struct Qzmf_ENVL0100{

long int Entry_Length;long int Displacement;long int Envelope_Length;Qzmf_Type_Value_t Envelope_Type;long int Unique_Id;long int Ref_Unique_Id;long int Reserved;

/*char Envelope[];*/ /* varying length */} Qzmf_ENVL0100_t;

/*********************************************************************//* Type Definition for the RCPL0100 Format *//**** ****//* NOTE: The following type definition only defines the fixed *//* portion of the format. Any varying length field will *//* have to be defined by the user. *//*********************************************************************/

typedef _Packed struct Qzmf_RCPL0100{

long int Entry_Length;long int SPIN_Displacement;long int SPIN_Length;long int Recipient_Displacement;long int Addr_Length;Qzmf_Type_Value_t Addr_Type;Qzmf_CCSID_t CCSID;long int Reason_Code;long int Diag_Code;Qzmf_Type_Value_t Msg_Type;long int Status;long int Dist_Type;long int Unique_Id;long int Reserved;

/*char Recipient_Addr[];*/ /* varying length */ /*char SPIN[];*/ /* varying length */ } Qzmf_RCPL0100_t;

/*********************************************************************//* Type Definition for the ROAL0100 Format *//**** ****//* NOTE: The following type definition only defines the fixed *//* portion of the format. Any varying length field will *//* have to be defined by the user. *//*********************************************************************/

typedef _Packed struct Qzmf_ROAL0100{

long int Entry_Length;long int SPIN_Displacement;long int SPIN_Length;

Appendix F. Qzmf Header File 369

Page 394: AnyMail/400 Mail Server Framework Developer Guide January 1995

long int Report_Displacement;long int Addr_Length;Qzmf_Type_Value_t Addr_Type;Qzmf_CCSID_t CCSID;long int Reason_Code;long int Diag_Code;long int Unique_Id;long int Ref_Unique_Id;long int Reserved;

/*char Report_On_Addr[];*/ /* varying length */ /*char SPIN[];*/ /* varying length */} Qzmf_ROAL0100_t;

/*********************************************************************//* Type Definition for the RTAL0100 Format *//**** ****//* NOTE: The following type definition only defines the fixed *//* portion of the format. Any varying length field will *//* have to be defined by the user. *//*********************************************************************/

typedef _Packed struct Qzmf_RTAL0100{

long int Entry_Length;long int Displacement;long int Addr_Length;Qzmf_Type_Value_t Addr_Type;Qzmf_CCSID_t CCSID;long int Unique_Id;long int Ref_Unique_Id;long int Reserved;

/*char Report_To_Addr[];*/ /* varying length */} Qzmf_RTAL0100_t;

/*********************************************************************//* Type Definition for the RPYL0100 Format *//**** ****//* NOTE: The following type definition only defines the fixed *//* portion of the format. Any varying length field will *//* have to be defined by the user. *//*********************************************************************/

typedef _Packed struct Qzmf_RPYL0100{

long int Entry_Length;long int Displacement;long int Addr_Length;Qzmf_Type_Value_t Addr_Type;Qzmf_CCSID_t CCSID;long int Unique_Id;long int Ref_Unique_Id;long int Reserved;

/*char Reply_To_Addr[];*/ /* varying length */} Qzmf_RPYL0100_t;

370 AnyMail/400 MSF

Page 395: AnyMail/400 Mail Server Framework Developer Guide January 1995

/*********************************************************************//* Type Definition for the ORCL0100 Format *//**** ****//* NOTE: The following type definition only defines the fixed *//* portion of the format. Any varying length field will *//* have to be defined by the user. *//*********************************************************************/

typedef _Packed struct Qzmf_ORCL0100{

long int Entry_Length;long int Displacement;long int Addr_Length;Qzmf_Type_Value_t Addr_Type;Qzmf_CCSID_t CCSID;long int Dist_Type;long int Reply_Req_Flag;long int Unique_Id;long int Ref_Unique_Id;long int Reserved;

/*char Org_Rcpnt_Addr[];*/ /* varying length */} Qzmf_ORCL0100_t;

/*********************************************************************//* Type Definition for the ATTL0100 Format *//**** ****//* NOTE: The following type definition only defines the fixed *//* portion of the format. Any varying length field will *//* have to be defined by the user. *//*********************************************************************/

typedef _Packed struct Qzmf_ATTL0100{

long int Entry_Length;long int Displacement;long int Attach_Length;Qzmf_Type_Value_t Attach_Type;long int Unique_Id;long int Ref_Unique_Id;long int Reserved;

/*char Attach_Ref[];*/ /* varying length */} Qzmf_ATTL0100_t;

/*********************************************************************//* Type Definition for the MSGL0100 Format *//*********************************************************************/

typedef _Packed struct Qzmf_MSGL0100{

Qzmf_Type_Value_t Msg_Type;} Qzmf_MSGL0100_t;

/*********************************************************************//* Type Definition for the ORGL0100 Message Descriptor */

Appendix F. Qzmf Header File 371

Page 396: AnyMail/400 Mail Server Framework Developer Guide January 1995

/**** ****//* NOTE: The following type definition only defines the fixed *//* portion of the format. Any varying length field will *//* have to be defined by the user. *//*********************************************************************/

typedef _Packed struct Qzmf_Orgntr0100_Msg_Desc{

Qzmf_Msg_Desc_Hdr0100_t Msg_Desc_Hdr; /*Qzmf_ORGL0100_t Originator[];*/ /* varying length */} Qzmf_Orgntr0100_Msg_Desc_t;

/*********************************************************************//* Type Definition for the ENVL0100 Message Descriptor *//**** ****//* NOTE: The following type definition only defines the fixed *//* portion of the format. Any varying length field will *//* have to be defined by the user. *//*********************************************************************/

typedef _Packed struct Qzmf_Envlp0100_Msg_Desc{

Qzmf_Msg_Desc_Hdr0100_t Msg_Desc_Hdr; /*Qzmf_ENVL0100_t Envelope[];*/ /* varying length */} Qzmf_Envlp0100_Msg_Desc_t;

/*********************************************************************//* Type Definition for the RCPL0100 Message Descriptor *//**** ****//* NOTE: The following type definition only defines the fixed *//* portion of the format. Any varying length field will *//* have to be defined by the user. *//*********************************************************************/

typedef _Packed struct Qzmf_Rcpt0100_Msg_Desc{

Qzmf_Msg_Desc_Hdr0100_t Msg_Desc_Hdr; /*Qzmf_RCPL0100_t Recipient[];*/ /* varying length */} Qzmf_Rcpt0100_Msg_Desc_t;

/*********************************************************************//* Type Definition for the ROAL0100 Message Descriptor *//**** ****//* NOTE: The following type definition only defines the fixed *//* portion of the format. Any varying length field will *//* have to be defined by the user. *//*********************************************************************/

typedef _Packed struct Qzmf_Rpt_O_Addr0100_Msg_Desc{

Qzmf_Msg_Desc_Hdr0100_t Msg_Desc_Hdr; /*Qzmf_ROAL0100_t Report_On_Addr[];*/ /* varying length */} Qzmf_Rpt_O_Addr0100_Msg_Desc_t;

372 AnyMail/400 MSF

Page 397: AnyMail/400 Mail Server Framework Developer Guide January 1995

/*********************************************************************//* Type Definition for the RTAL0100 Message Descriptor *//**** ****//* NOTE: The following type definition only defines the fixed *//* portion of the format. Any varying length field will *//* have to be defined by the user. *//*********************************************************************/

typedef _Packed struct Qzmf_Rpt_T_Addr0100_Msg_Desc{

Qzmf_Msg_Desc_Hdr0100_t Msg_Desc_Hdr; /*Qzmf_RTAL0100_t Report_To_Addr[];*/ /* varying length */} Qzmf_Rpt_T_Addr0100_Msg_Desc_t;

/*********************************************************************//* Type Definition for the RPYL0100 Message Descriptor *//**** ****//* NOTE: The following type definition only defines the fixed *//* portion of the format. Any varying length field will *//* have to be defined by the user. *//*********************************************************************/

typedef _Packed struct Qzmf_Rply_T_Addr0100_Msg_Desc{

Qzmf_Msg_Desc_Hdr0100_t Msg_Desc_Hdr; /*Qzmf_RPYL0100_t Reply_To_Addr[];*/ /* varying length */} Qzmf_Rply_T_Addr0100_Msg_Desc_t;

/*********************************************************************//* Type Definition for the ORCL0100 Message Descriptor *//**** ****//* NOTE: The following type definition only defines the fixed *//* portion of the format. Any varying length field will *//* have to be defined by the user. *//*********************************************************************/

typedef _Packed struct Qzmf_Org_Rcp_Addr0100_Msg_Desc{

Qzmf_Msg_Desc_Hdr0100_t Msg_Desc_Hdr; /*Qzmf_ORCL0100_t Org_Rcpt_Addr[];*/ /* varying length */} Qzmf_Org_Rcp_Addr0100_Msg_Desc_t;

/*********************************************************************//* Type Definition for the ATTL0100 Message Descriptor *//**** ****//* NOTE: The following type definition only defines the fixed *//* portion of the format. Any varying length field will *//* have to be defined by the user. *//*********************************************************************/

typedef _Packed struct Qzmf_Attch0100_Msg_Desc{

Qzmf_Msg_Desc_Hdr0100_t Msg_Desc_Hdr; /*Qzmf_ATTL0100_t Attch_Ref[];*/ /* varying length */} Qzmf_Attch0100_Msg_Desc_t;

Appendix F. Qzmf Header File 373

Page 398: AnyMail/400 Mail Server Framework Developer Guide January 1995

/*********************************************************************//* Type Definition for the MSGL0100 Message Descriptor *//**** ****//* NOTE: The following type definition only defines the fixed *//* portion of the format. Any varying length field will *//* have to be defined by the user. *//*********************************************************************/

typedef _Packed struct Qzmf_Msg_Type0100_Msg_Desc{

Qzmf_Msg_Desc_Hdr0100_t Msg_Desc_Hdr;/*Qzmf_MSGL0100_t Message_Type[];*/ /* varying length */} Qzmf_Msg_Type0100_Msg_Desc_t;

#endif /*_QZMF_H*/

374 AnyMail/400 MSF

Page 399: AnyMail/400 Mail Server Framework Developer Guide January 1995

Appendix G. Qzmfasrv Header File

This appendix contains the Qzmfasrv header file. This header file containsdefinitions of the parameter list which are used for the mail server frameworkAPIs.

#ifndef _QZMFASRV_H#define _QZMFASRV_H

/*** START HEADER FILE SPECIFICATIONS ********************************//* *//* Header File Name: H/QZMFASRV *//* *//* Descriptive Name: Mail Server Framework (MSF) APIs. *//* *//* 5763-SS1 (C) Copyright IBM Corp. 1994,1994 *//* All rights reserved. *//* US Government Users Restricted Rights - *//* Use, duplication or disclosure restricted *//* by GSA ADP Schedule Contract with IBM Corp. *//* *//* Licensed Materials-Property of IBM *//* *//* Description: Include header file containing the structure *//* definitions and prototypes for MSF APIs of QZMFASRV *//* Service Program. *//* *//* Header Files Included: *//* H/QZMF *//* *//* Macros List: None. *//* *//* Structure List: *//* Qzmf_ADDC0100_t *//* Qzmf_DLTC0100_t *//* Qzmf_LSTC0100_t *//* Qzmf_RCHL0100_t *//* Qzmf_EXCH0100_t *//* Qzmf_CRTA0100_t *//* *//* Qzmf_Rcpt_Hist0100_Msg_Desc_t *//* Qzmf_Ext_Hist0100_Msg_Desc_t *//* Qzmf_Crtn_Attr0100_Msg_Desc_t *//* *//* Qzmf_LSTL0100_t *//* *//* *//* Function Prototype List: *//* QzmfAddMailCfg *//* QzmfRmvMailCfg *//* QzmfLstMailCfg *//* QzmfCrtMailMsg *//* QzmfRtvMailMsg *//* QzmfChgMailMsg *//* QzmfRsvMailMsgId *//* QzmfQryMailMsgId *//* QzmfRmvRsvMailMsgId *//* QzmfCrtCmpMailMsg */

Copyright IBM Corp. 1995 375

Page 400: AnyMail/400 Mail Server Framework Developer Guide January 1995

/* *//* *//* Change Activity: *//* *//* CFD List: *//* *//* FLAG REASON LEVEL DATE PGMR CHANGE DESCRIPTION *//* ---- ------------ ----- ------ ------- ------------------------ *//* $A0= D9129400 3D10 940304 BANER : New Include for V3R1 *//* *//* End CFD List. *//* *//* Additional notes about the Change Activity *//* *//* End Change Activity. *//* *//*** END HEADER FILE SPECIFICATIONS **********************************/

#ifdef __ILEC400__#include <qzmf.h>

#else#include ″qzmf.cleinc″

#endif

/*********************************************************************//* Type Definition for the ADDC0100 Format *//*********************************************************************/

typedef _Packed struct Qzmf_ADDC0100{

long int Param_List_Length;Qzmf_Type_Group_t Type_Group;Qzmf_Type_Value_t Type_Value;Qzmf_Type_Name_t Type_Name;char Reserved[2];Qzmf_CCSID_t CCSID;char Type_Text[100];

} Qzmf_ADDC0100_t;

/*********************************************************************//* Type Definition for the DLTC0100 Format *//*********************************************************************/

typedef _Packed struct Qzmf_DLTC0100{

long int Param_List_Length;Qzmf_Type_Group_t Type_Group;Qzmf_Type_Value_t Type_Value;Qzmf_Type_Name_t Type_Name;

} Qzmf_DLTC0100_t;

/*********************************************************************//* Type Definition for the LSTC0100 Format *//*********************************************************************/

typedef _Packed struct Qzmf_LSTC0100{

376 AnyMail/400 MSF

Page 401: AnyMail/400 Mail Server Framework Developer Guide January 1995

long int Sel_List_Length;Qzmf_Type_Group_t Type_Group;Qzmf_Type_Value_t Type_Value;Qzmf_Type_Name_t Type_Name;

} Qzmf_LSTC0100_t;

/*********************************************************************//* Type Definition for the RCHL0100 Format *//**** ****//* NOTE: The following type definition only defines the fixed *//* portion of the format. Any varying length field will *//* have to be defined by the user. *//*********************************************************************/

typedef _Packed struct Qzmf_RCHL0100{

long int Entry_Length;long int SPIN_Displacement;long int SPIN_Length;long int Recipient_Displacement;long int Addr_Length;Qzmf_Type_Value_t Addr_Type;Qzmf_CCSID_t CCSID;Qzmf_Type_Value_t Msg_Type;long int Status;long int Dist_Type;long int Unique_Id;long int Recipient_Status_Flag;long int Parent_Unique_Id;long int Reserved;

/*char Recipient_Addr[];*/ /* varying length */ /*char SPIN[];*/ /* varying length */} Qzmf_RCHL0100_t;

/*********************************************************************//* Type Definition for the EXCH0100 Format *//*********************************************************************/

typedef _Packed struct Qzmf_EXCH0100{

Qzmf_Exit_Point_t MSF_Exit_Point;Qzmf_Exit_Pgm_Lib_Name_t MSF_Exit_Program;long int MSF_Exit_Program_Num;

Qzmf_System_Timestamp_t Exit_Call_Tmstmp; Qzmf_System_Timestamp_t Exit_Rtn_Tmstmp; long int Exit_Program_Retcode; char Change_Indctr; char Reserved[3];} Qzmf_EXCH0100_t;

/*********************************************************************//* Type Definition for the CRTA0100 Format *//*********************************************************************/

Appendix G. Qzmfasrv Header File 377

Page 402: AnyMail/400 Mail Server Framework Developer Guide January 1995

typedef _Packed struct Qzmf_CRTA0100{ Qzmf_System_Timestamp_t Msg_Crtn_Tmstmp; Qzmf_Type_Value_t Crtn_Msg_Type;} Qzmf_CRTA0100_t;

/*********************************************************************//* Type Definition for the RCHL0100 Message Descriptor *//**** ****//* NOTE: The following type definition only defines the fixed *//* portion of the format. Any varying length field will *//* have to be defined by the user. *//*********************************************************************/

typedef _Packed struct Qzmf_Rcpt_Hist0100_Msg_Desc{ Qzmf_Msg_Desc_Hdr0100_t Msg_Desc_Hdr; /*Qzmf_RCHL0100_t Recipient_History[];*/ /* varying length */} Qzmf_Rcpt_Hist0100_Msg_Desc_t;

/*********************************************************************//* Type Definition for the EXCH0100 Message Descriptor *//**** ****//* NOTE: The following type definition only defines the fixed *//* portion of the format. Any varying length field will *//* have to be defined by the user. *//*********************************************************************/

typedef _Packed struct Qzmf_Ext_Hist0100_Msg_Desc{ Qzmf_Msg_Desc_Hdr0100_t Msg_Desc_Hdr; /*Qzmf_EXCH0100_t User_Exit_Call_Hist[];*//* varying length */} Qzmf_Ext_Hist0100_Msg_Desc_t;

/*********************************************************************//* Type Definition for the CRTA0100 Message Descriptor *//**** ****//* NOTE: The following type definition only defines the fixed *//* portion of the format. Any varying length field will *//* have to be defined by the user. *//*********************************************************************/

typedef _Packed struct Qzmf_Crtn_Attr0100_Msg_Desc{ Qzmf_Msg_Desc_Hdr0100_t Msg_Desc_Hdr; /*Qzmf_CRTA0100_t Creation_Attribute[];*/ /* varying length */ } Qzmf_Crtn_Attr0100_Msg_Desc_t;

/*********************************************************************//* Prototype for calling Add Mail Server Framework Configuration *//* (QzmfAddMailCfg) API *//*********************************************************************/

378 AnyMail/400 MSF

Page 403: AnyMail/400 Mail Server Framework Developer Guide January 1995

extern void QzmfAddMailCfg(void *, /* Type Configuration */char *, /* Format Name */void * /* API Returned Error */

);

/*********************************************************************//* Prototype for calling Remove Mail Server Framework Configuration *//* (QzmfRmvMailCfg) API *//*********************************************************************/

extern void QzmfRmvMailCfg(void *, /* Type Configuration */char *, /* Format Name */void * /* API Returned Error */

);

/*********************************************************************//* Prototype for calling List Mail Server Framework Configuration *//* (QzmfLstMailCfg) API *//*********************************************************************/

extern void QzmfLstMailCfg(void *, /* User Space Name */char *, /* List Format Name */char *, /* Format Name */void *, /* Type Configuration */void * /* API Returned Error */

);

/*********************************************************************//* Type Definition for the LSTL0100 Format *//*********************************************************************/

typedef _Packed struct Qzmf_LSTL0100{

Qzmf_Type_Group_t Type_Group;Qzmf_Type_Value_t Type_Value;Qzmf_Type_Name_t Type_Name;char Reserved[2];Qzmf_CCSID_t CCSID;char Type_Text[100];

} Qzmf_LSTL0100_t;

/*********************************************************************//* Prototype for calling Create Mail Message (QzmfCrtMailMsg) API *//*********************************************************************/

extern void QzmfCrtMailMsg(void *, /* Mail Messge Ident. */void *, /* Reservd Mail Msg Id */char *, /* Creation Msg. Type */void *, /* Msg Desc Attr List */long int *, /* Num Msg Desc Attrbts*/char *, /* Format Name */void * /* API Returned Error */

Appendix G. Qzmfasrv Header File 379

Page 404: AnyMail/400 Mail Server Framework Developer Guide January 1995

);

/*********************************************************************//* Prototype for calling Retrieve Mail Message (QzmfRtvMailMsg) API *//*********************************************************************/

extern void QzmfRtvMailMsg(void *, /* Mail Messge Ident. */void *, /* Msg Desc Attr List */long int *, /* Num Msg Desc Attrbts*/char *, /* Format Name */void * /* API Returned Error */

);

/*********************************************************************//* Prototype for calling Change Mail Message (QzmfChgMailMsg) API *//*********************************************************************/

extern void QzmfChgMailMsg(void *, /* Mail Messge Ident. */void *, /* Msg Desc Attr List */long int *, /* Num Msg Desc Attrbts*/char *, /* Format Name */void * /* API Returned Error */

);

/*********************************************************************//* Prototype for calling Reserve Mail Message Identifier *//* (QzmfRsvMailMsgId) API *//*********************************************************************/

extern void QzmfRsvMailMsgId(void *, /* Reservd Mail Msg Id */char *, /* Format Name */void * /* API Returned Error */

);

/*********************************************************************//* Prototype for calling Query Mail Message Identifier *//* (QzmfQryMailMsgId) API *//*********************************************************************/

extern void QzmfQryMailMsgId(void *, /* Mail Message Ident. */char *, /* Format Name */char *, /* Status */void * /* API Returned Error */

);

/*********************************************************************//* Prototype for calling Remove Reserved Mail Message Identifier *//* (QzmfRmvRsvMailMsgId) API *//*********************************************************************/

extern void QzmfRmvRsvMailMsgId(void *, /* Reservd Mail Msg Id */char *, /* Format Name */void * /* API Returned Error */

380 AnyMail/400 MSF

Page 405: AnyMail/400 Mail Server Framework Developer Guide January 1995

);/*********************************************************************//* Prototype for calling Complete Creation Sequence *//*(QzmfCrtCmpMailMsg) API *//*********************************************************************/

extern void QzmfCrtCmpMailMsg(void *, /* Reservd Mail Msg Id */char *, /* Format Name */void * /* API Returned Error */

);

#endif /*_QZMFASRV_H*/

Appendix G. Qzmfasrv Header File 381

Page 406: AnyMail/400 Mail Server Framework Developer Guide January 1995

Glossary

This glossary includes terms and definitions from:

• The American National Dictionary for InformationSystems, ANSI X3.172-1990, copyright 1990 by theAmerican National Standards Institute (ANSI).Copies may be purchased from the AmericanNational Standards Institute, 1430 Broadway, NewYork, New York 10018. Definitions are identifiedby the symbol (A) after the definition.

• The Information Technology Vocabulary,developed by Subcommittee 1, Joint TechnicalCommittee 1, of the International Organization forStandardization and the InternationalElectrotechnical Committee (ISO/IEC JTC1/SC1).Definitions of published parts of this vocabularyare identified by the symbol (I) after the definition;definitions taken from draft internationalstandards, committee drafts, and working papersbeing developed by ISO/IEC JTC1/SC1 areidentified by the symbol (T) after the definition,indicating that final agreement has not yet beenreached among participating National Bodies ofSC1.

• The IBM Dictionary of Computing, New York:McGraw-Hill, 1994.

activation group . A substructure of a job in whichIntegrated Language Environment* (ILE*) programsand service programs are activated. Thissubstructure contains the resources necessary to runthe program. These resources include: static andautomatic program variables, dynamic storage,temporary data management resources, certain typesof exception handlers and ending procedures.

activation group number . A 4-byte number thatuniquely identifies an activation group within the job.

active . The state of a resource when it has beenactivated and is operational.

address . (1) A unique code assigned to each deviceor system connected in a network. (2) The secondpart of a two-part user identification used to senddistributions. See also user ID/address.

address type . A value used to define the format andcontents of an address field. Address types areassociated with the originator address, the recipientaddress, and the reply-to address information. Theaddress types supported by a system are definedwhen the mail server framework is configured. Thevalue associated with an address type must be aunique type value.

American National Standard Code for InformationInterchange (ASCII) . The code developed by the

American National Standards Institute for informationexchange among data processing systems, datacommunications systems, and associated equipment.The ASCII character set consists of 7-bit controlcharacters and symbolic characters, plus one paritybit.

American National Standards Institute (ANSI) . Anorganization sponsored by the Computer andBusiness Equipment Manufacturers Association forestablishing voluntary industry standards.

ANSI . See American National Standards Institute(ANSI).

AnyMail/400 . A set of mail-related functions thatprovide open and flexible interfaces to support mailon the AS/400.

AnyMail/400 mail server framework (MSF) . An openstructure for electronic mail distribution that isprovided with OS/400. It is the distribution frameworkof AnyMail/400.

AnyNet* . An IBM implementation of the MultiprotocolTransport Network (MPTN) architecture. AnyNet*capability allows applications and associated servicesthat use application programming interfaces, such assockets, ICF, or CPI-Communications, the flexibility touse alternative network protocols, such as SNA orTCP/IP, and a variety of subnetwork types, such as aLAN, frame-relay, and ISDN.

API . See application program interface (API).

application . (1) A collection of software componentsused to perform specific types of user-oriented workon a computer. (2) A particular business task, suchas inventory control or accounts receivable.

application program . A program used to perform aparticular data processing task, such as inventorycontrol or payroll.

application program interface (API) . A functionalinterface supplied by the operating system or aseparately orderable licensed program that allows anapplication program written in a high-level languageto use specific data or functions of the operatingsystem or the licensed program.

Application System/400* (AS/400*) . One of a familyof general purpose systems with a single operatingsystem, Operating System/400*, that providesapplication portability across all models.

ASCII . See American National Standard Code forInformation Interchange (ASCII).

382 Copyright IBM Corp. 1995

Page 407: AnyMail/400 Mail Server Framework Developer Guide January 1995

asynchronous . (1) Not occurring in a regular orpredictable pattern. (2) Without a regular timerelationship.

asynchronous operation . An operation that occurswithout a regular or predictable time relationship to aspecified event.

asynchronous processing . A series of operations thatare done separately from the job in which they wererequested; for example, submitting a batch job froman interactive job at a work station.

attachment . A separate unit of informationassociated with a message.

attachment reference . A string of data representinga reference to an attachment. The format andcontents of the attachment reference are defined bythe attachment reference type.

attachment reference type . A value used to definethe format and contents of an attachment reference,so that the programs that work with specific types ofattachment references are supported. Theattachment reference types supported on a systemare defined when the mail server framework isconfigured. The value associated with an attachmentreference type must be a unique type value.

attribute . (1) A characteristic or trait of one or moreitems.

authorization list . A list of two or more user IDs andtheir authorities for system resources. Thesystem-recognized identifier for the object type is*AUTL.

authorize . To permit or give authority to.

autostart . Pertaining to a system activity that startsautomatically, usually based on the start or end ofsome other activity.

autostart job . A batch job doing repetitive work orone-time initialization work that is associated with aparticular subsystem. The autostart jobs associatedwith a subsystem are automatically started each timethe subsystem is started.

batch . Pertaining to a group of jobs to be run on acomputer sequentially with the same program withlittle or no operator action. Contrast with interactive.

batch job . A predefined group of processing actionssubmitted to the system to be performed with litt le orno interaction between the user and the system.

batch processing . A method of running a program ora series of programs in which one or more records (abatch) are processed with little or no action from theuser or operator. Contrast with interactiveprocessing.

call cycle . See data type evaluation and call cycle.

CCITT. The International Telegraph and TelephoneConsultative Committee. As of March 1, 1993, theCCITT has changed its name to TelecommunicationStandardization Sector (ITU-T). Recommendationsmade after March 1, 1993 are called ITU-TRecommendations.

CCSID. See coded character set identifier (CCSID).

change authority . An object authority that allows auser to perform all operations on the object exceptthose limited to the owner or controlled by objectexistence authority, object management authority,object alter authority, and object reference authority.The user can add, change, and delete entries in anobject, or read the contents of an entry in the object.Change authority combines object operationalauthority and all the data authorities.

CL . See control language (CL).

C language . A language used to develop applicationprograms in compact, efficient code that can be runon different types of computers with minimal change.

coded character set identifier (CCSID) . A 16-bitnumber identifying a specific set of encoding schemeidentifiers, character set identifiers, code pageidentifiers, and other relevant information thatuniquely identifies the coded graphic characterrepresentation used.

control language (CL) . The set of all commands withwhich a user requests system functions.

control language (CL) program . A program that iscreated from source statements consisting entirely ofcontrol language commands.

database . (1) A collection of data with a givenstructure for accepting, storing, and providing, ondemand, data for multiple users. (T)

data file . A group of related data records organizedin a specific order. A data file can be created by thespecification of FILETYPE(*DATA) on the createcommands. Contrast with source file.

data integrity . The condition that exists as long asaccidental or intentional destruction, alteration, orloss of data does not occur.

data type . A category of data used by the mailserver framework. The data type indicates the typeof information in an MSF message and the format ofthe information. See also mail server framework datatype.

data type evaluation and call cycle . An algorithmused by MSF to determine which exit point programsto call at the MSF exit points.

Glossary 383

Page 408: AnyMail/400 Mail Server Framework Developer Guide January 1995

debugger . A tool used to detect and trace errors incomputer programs.

default . A value that is automatically supplied orassumed by the system or program when no value isspecified by the user.

directory . A special object in a file system that isused to locate objects by user-recognized names. Adirectory contains a list of objects belonging to thatdirectory.

distribution . A piece of electronic mail.

distribution services . The support provided by theoperating system to receive, forward, and sendelectronic mail in an SNA network.

domain . A characteristic of an object that controlswhich programs can access the object. See systemdomain object and user domain object.

electronic mail (E-mail) . Correspondence in the formof messages transmitted between user workstationsover a computer network.

envelope . A string of data representing informationabout a message aside from the attachments and itsrecipients.

envelope type . A value used to define the formatand contents of an envelope, so that the programsthat work with specific types of envelopes aresupported. The envelope types supported on asystem are defined when the mail server frameworkis configured. The valued associated with anenvelope type must be a unique type value.

exit point . A specific point in a system function orprogram where control may be passed to one or morespecified exit programs.

exit point program . A program to which control ispassed from an exit point.

external message queue . A message queue used byall programs and procedures running within a job tosend and to receive messages outside a job, forexample, between an interactive job and theworkstation user.

external object . An object that has a defined objecttype (such as *FILE or *PGM). In general, externalobjects can be displayed by a user. See also object.Contrast with internal object.

facsimile machine . A functional unit that convertsimages to signals for transmission over a telephonesystem or that converts received signals back toimages. (T)

fax . (1) The printed copy received from a facsimilemachine. (T) (2) To transmit an image using atelephone system and facsimile machines. (T) (3) The

use of a telephone system for the electronictransmission and receipt of hard-copy images. (T)

fax machine . Synonym for facsimile machine. Seefacsimile machine.

file server object . An internal system object thatcontains MSF attachment data. A file server objectcan be manipulated with the SNADS file server objectAPIs.

file server object access ID . An identifier assigned toa file server object. The access ID protects a fileserver object from being deleted. After a fi le serverobject has been created, an access ID must beassigned using the SNADS File Server Object AssignAccess ID (QZDASNID) API.

final-form text (FFT) . A data stream defined bydocument content architecture that is used toexchange resolved documents (which can be printeddirectly by most printers or displayed) betweensystems. Contrast with revisable-form text (RFT).

FSO. See file server object.

gateway . A program used to connect two systemsthat use different communications protocols.

generic envelope type (GET) . A mail serverframework envelope type that may be used by anymail protocol. The contents of this envelope arepublished so that it can be used as a commoninterchange format.

GET. See generic envelope type (GET).

group profile . A user profile that provides the sameauthority to a group of users.

GMT. Greenwich Mean Time.

IBM Integrated Language Environment C/400 Version3 (ILE C/400) . An IBM licensed program that is aSystems Application Architecture* platform Cprogramming language. The ILE C/400 licensedprogram uses the ILE model on the system.

IBM OfficeVision/400 . The IBM licensed program thatallows users to prepare, send, and receive mail;schedule items on calendars; maintain directories ofnames and addresses; file and retrieve documents;and create and maintain distribution lists.

IBM Operating System/400* Version 3 (OS/400) .Pertaining to the IBM licensed program that can beused as the operating system for the AS/400 system.

identifier . (1) The name of something. (2) In the Clanguage, a sequence of letters, digits, andunderscores used to identify a data object or function.

initial program load (IPL) . The process that loads thesystem programs from the system auxil iary storage,

384 AnyMail/400 MSF

Page 409: AnyMail/400 Mail Server Framework Developer Guide January 1995

checks the system hardware, and prepares thesystem for user operations.

ILE . See Integrated Language Environment (ILE).

ILE C/400 . See IBM Integrated LanguageEnvironment C/400 Version 3 (ILE C/400).

Integrated Language Environment (ILE) . A set ofconstructs and interfaces that provides a commonrun-time environment and run-time bindableapplication program interfaces (APIs) for allILE-conforming high-level languages.

integrity protection . The set of controls that preventsusers from accessing or changing any objects on thesystem, including user data, except by using thesystem-provided interfaces that enforce authorityrules.

interactive . Pertaining to the dialog-like exchange ofinformation between people and a computer.Contrast with batch.

interactive job . A job started for a person who signson to a work station. In the capacity planning tool,interactive jobs cause interactive and non-interactivetransactions. Contrast with batch job.

interactive processing . A processing method in whicheach operator action causes a response from theprogram or the system. Contrast with batchprocessing.

internal object . An object that the system programuses to store the information needed to perform somesystem functions. Internal objects cannot bedisplayed by a user. For example, you cannot use adisplay command (like the Display Library [DSPLIB]command) to display internal objects. Contrast withexternal object.

internet address . In TCP/IP, the address used inInternet networks. The address is the formnnn.nnn.nnn.nnn, and each 3-digit part is a valuebetween 0 and 255.

IPL . See initial program load (IPL).

job . (1) A unit of work separately run by a computer.Also called a process. (2) In the Integrated LanguageEnvironment (ILE) model, a collection of resourcesand data that consists of one or more activationgroups. See also activation group.

job control authority . A special authority that allowsa user to: change, delete, display, hold, and releaseall files on output queues; hold, release, and clear jobqueues and output queues; start writers to outputqueues; hold, release, change, and end other users’jobs; change the class attributes of a job; endsubsystems; and start (do an IPL of) the system.

job description . A system object that defines how ajob is to be processed. The system-recognizedidentifier for the object type is *JOBD.

job log . A record of requests submitted to thesystem by a job, the messages related to therequests, and the actions performed by the system onthe job. The job log is maintained by the systemprogram.

job message queue . A message queue that iscreated for each job. A job message queue receivesrequests to be processed (such as commands) andsends messages that result from processing therequests. A job message queue consists of anexternal message queue and a set of programmessage queues. See also external message queueand program message queue.

job name . The name of the job as identified to thesystem. For an interactive job, the job is assignedthe name of the work station at which the job wasstarted; for a batch job, the name is specified in thecommand used to submit the job. Contrast withqualified job name.

journal . A system object that identifies the objectsbeing journaled, the current journal receiver, and allthe journal receivers on the system for the journal.The system-recognized identifier for the object type is*JRN. See also journal receiver.

journal code . A 1-character code in a journal entrythat identifies the category of the journal entry. Forexample, F identifies an operation on a file; Ridentifies an operation on a record, and so forth. Seealso journal entry.

journal entry . A record in a journal receiver thatcontains information about a journaled change orother activity that is journaled. See also journal codeand journal entry type.

journal entry type . A 2-character field in a journalentry that identifies the type of operation of asystem-generated journal entry or the type of journalentry of a user-generated journal entry; for example,PT is the entry type for a write operation. See alsojournal code.

journaling . The process of recording, in a journal, thechanges made to objects, such as physical filemembers or access paths, or the depositing of journalentries by system or user functions.

journal receiver . A system object that containsjournal entries added when events occur that arejournaled, such as changes to a database file,changes to other journaled objects, orsecurity-relevant events. The object type is *JRNRCV.See also journal .

Glossary 385

Page 410: AnyMail/400 Mail Server Framework Developer Guide January 1995

library . A system object that serves as a directory toother objects. A library groups related objects, andallows the user to find objects by name. Thesystem-recognized identifier for the object type is*LIB.

library list . A list that indicates which libraries are tobe searched and the order in which they are to besearched. The system-recognized identifier is *LIBL.

licensed program (LP) . A separately orderableprogram, supplied by IBM, that performs functionsrelated to processing user data. Examples of licensedprograms are IBM OfficeVision/400 and IBMIntegrated Language Environment C/400.

lock . The process by which integrity of data isensured by preventing more than one user fromaccessing or changing the same data or object at thesame time.

LP. See licensed program (LP).

mail server framework (MSF) . A set of user exitpoints and application program interfaces (APIs) thatembody an abstract design for solutions to a numberof related communications problems. The mail serverframework is the distribution framework ofAnyMail/400.

mail server framework data type . A category of dataused by the mail server framework. The data typeindicates the type of information in an MSF messageand the format of the information.

mail server framework message . A collection ofinformation handled by the mail server framework.An MSF message contains information about a pieceof electronic mail.

MAPI . See messaging application program interface(MAPI).

message . (1) A communication sent from a personor program to another person or program. (2) Acollection of information handled by the mail serverframework. An MSF message contains informationabout a piece of electronic mail. See also mail serverframework message. (3) In OSI X.400, a piece ofelectronic mail in the format of the X.400 CCITTstandard. An X.400 message can be an AS/400document, note, message, or file. (4) In systemprogramming, information intended for the systemoperator.

message envelope . The information associated witha message aside from attachments and recipients.

message handling system (MHS) . In OSI X.400, acollection of message transfer agents and user agentsthat provide support for sending and receivingmessages.

message object . An abstraction of the datastructures or system objects that store mail serverframework message information.

message priority . An attribute of a message that canaffect the order in which messages on a queue areretrieved and whether a trigger event is generated.

message store (MS) . A component that is usuallyassociated with the local delivery exit. The messagestore provides application program interfaces (APIs)for maintaining mailboxes, and it provides pointers tomessage objects.

message transfer agent (MTA) . In OSI X.400, one oftwo basic parts of electronic mail. A messagetransfer agent is a program that accepts the mailfrom user agents, delivers messages to user agents,and forwards messages to other MTAs.

message transfer system (MTS) . In OSI X.400, acollection of message transfer agents. A messagetransfer system provides the means by which useragents can exchange messages.

message type . A value used to define the type ofdata sent for a distribution to a recipient. Themessage types supported on a system are definedwhen the mail server framework is configured. Thevalue associated with the message type must be aunique type value.

messaging application program interface (MAPI) . Anapplication program interface (API) defined byMicrosoft Corporation.

mnemonic . A symbol or abbreviation chosen to helpthe user remember the significance or meaning of thesymbol. For example, CRTUSRPRF is a mnemonic forthe Create User Profile command.

MSF. See mail server framework (MSF).

MTA . See message transfer agent (MTA).

MTS. See message transfer system (MTS).

multimedia . Material presented in a combination oftext, graphics, video, animation, and sound.

nest . To incorporate a structure or structures into astructure of the same kind; for example, one callinstruction (nested call) within another call instruction(nesting call) or one subroutine (nested subroutine)within another subroutine (nesting subroutine).

network . A collection of data processing productsconnected by communications lines for exchanginginformation between stations.

network administrator . A person who defines thenetwork configuration and other network-relatedinformation. This person controls how an enterpriseor system uses its network resources.

386 AnyMail/400 MSF

Page 411: AnyMail/400 Mail Server Framework Developer Guide January 1995

network management . The process of planning,organizing, and controll ing a communications-orientedsystem.

network protocol . A communications protocol fromthe Network Layer of the Open Systems Interconnect(OSI) network architecture, such as the InternetProtocol (IP).

node . One of the systems or devices in a network.

object . A named storage space that consists of a setof characteristics that describe itself and, in somecases, data. An object is anything that exists in andoccupies space in storage and on which operationscan be performed. Some examples of objects areprograms, files, libraries, and folders.

object authority . A specific authority that controlswhat a system user can do with an entire object. Forexample, object authority includes deleting, moving,or renaming an object. There are five types of objectauthorities: object operational, object management,object existence, object alter, and object reference.

object distribution . A function that allows a user tosend source and data files, save files, job streams,spooled files, and messages to another user, eitherlocally or on an SNADS network.

object owner . A user who creates an object or towhom the ownership of an object was reassigned.The object owner has complete control over theobject.

Office . See IBM OfficeVision/400.

OfficeVision . See IBM OfficeVision/400.

originator address . A string of data representing theaddress of the originator of the message. Thecontents and format of the string are not defined bythe mail server framework. The address typeassociated with the originator address is assumed todefine the contents of the originator address field.

originator/recipient name (O/R name) . In OSI X.400,the name of the user (the originator and recipient ofmessages) and other attributes.

OSI protocols . The set of rules for exchanging datadefined by the ISO in accordance with the OSIreference model.

OSI reference model . The seven-layer basicreference model that ISO 7498 (CCITT X.200) uses todescribe how open systems should act and interact.The three primary kinds of interactions described inthat reference model are the interactions: (a) insidelayers, (b) between layers, and (c) between opensystems. (I)

OS/400. See IBM Operating System/400 Version 3(OS/400).

owner . The user who creates an object (or is namedthe owner of an object).

owner authority . The authority that the object′sowner has to the object. Contrast with primary groupauthority, private authority, and public authority.

parameter . (1) A value supplied to a command orprogram that is used either as input or to control theactions of the command or program. (2) In theIntegrated Language Environment (ILE), an identifierthat defines the types of arguments that are passedto a called procedure.

primary group . A group profile whose authority to anobject is stored with that object. Primary groupauthority may provide better performance thanprivate group authority.

primary group authority . The authority that theprimary group has to the object. Contrast with ownerauthority, private authority, and public authority.

private authority . The authority specifically given toa user for an object that overrides any otherauthorities, such as the authority of a user’s groupprofile or an authorization list. Contrast with ownerauthority, private group authority, and public authority.

processing . The action of performing operations andcalculations on data.

profile . Data that describes the characteristics of auser, program, device, or remote location.

program . (1) A sequence of instructions that acomputer can interpret and run. (2) In the IntegratedLanguage Environment (ILE) model, the runable objectthat results from binding modules together.

program message queue . An object used to holdmessages that are sent between program calls of arouting step. The program message queue is part ofthe job message queue.

protocol . A set of rules controlling thecommunication and transfer of data between two ormore devices or systems in a communicationsnetwork.

public authority . The authority given to users who donot have any specific (private) authority to an object,who are not on the authorization list (if one isspecified for the object), and whose group profile hasno specific authority to the object. Contrast withowner authority, primary group, and private authority.

QSYS. (1) The library shipped with the system thatcontains objects, such as authorization lists anddevice descriptions created by a user, and the systemcommands and other system objects required to runthe system. The system identifier is QSYS. (2) The

Glossary 387

Page 412: AnyMail/400 Mail Server Framework Developer Guide January 1995

IBM-supplied user profile that owns mostIBM-supplied objects.

qualified job name . A job name and its associateduser name and a system-assigned job number.Contrast with job name.

qualified name . The name of the library containingthe object and the name of the object.

queue . A list of messages, jobs, files, or requestswaiting to be read, processed, printed, or distributedin a predetermined order.

recipient . The user to whom mail is sent.

recipient address . A string of data that representsthe address associated with the recipient of themessage. The contents and format of the string arenot defined by the mail server framework. Theaddress type associated with the recipient address isassumed to define the contents of the recipientaddress field.

recipient history tree . A structure that represents thechanges to the recipient list, so that a recipient canbe traced back to the recipient entry in the originalrecipient list passed using the Create Mail Messageapplication program interface (API).

registration facility . A service that provides storageand retrieval operations for OS/400 and non-OS/400exit points and exit programs.

remote system . Any other system in the networkwith which your system can communicate.

reply message . A type of message used for repliesto request messages.

reply-to address . A string of data that represents theaddress to be replied to. The contents and format ofthe string are not defined by the mail serverframework. The address type associated with thereply-to address is assumed to define the contents ofthe reply-to address field.

resource . Any part of the system required by a jobor task, including main storage, devices, theprocessing unit, programs, files, libraries, and folders.

revisable-form text (RFT) . A data stream defined bydocument content architecture that is used toexchange unresolved documents (which cannot bedirectly printed or displayed) between systems.Contrast with final-form text (FFT).

save file . A file allocated in auxiliary storage that canbe used to store saved data on disk (without requiringdiskettes or tapes), to do I/O operations from ahigh-level language program, or to receive objectssent through the network. The system-recognizedidentifier for the object type is *FILE.

security administrator authority . A special authoritythat allows a user to add users to the systemdistribution directory, to create and change userprofiles, to add and remove access codes, and toperform office tasks, such as delete documents,folders, and document lists, and change distributionlists for other users.

security officer . A person assigned to control all ofthe security authorizations provided with the system.A security officer can, for example, remove passwordor resource security; or add, change, or removesecurity information about any system user.

sequence . To arrange in order.

Simple Mail Transfer Protocol (SMTP) . In TCP/IP, anapplication protocol for transferring mail among usersin the internet environment. SMTP specifies the mailexchange sequences and message format. SMTPassumes that the Transmission Control Protocol is theunderlying protocol.

Simple Network Management Protocol (SNMP) . Aprotocol used by network hosts to exchangeinformation used in the management of networks.SNMP network management is based on theclient/server model. Each host that is to be managedruns a process called an agent. The agent is a serverprocess that maintains the Management InformationBase (MIB) database for the host.

SMTP. See Simple Mail Transfer Protocol (SMTP).

SNA . See Systems Network Architecture (SNA).

SNA distribution services (SNADS) . An IBMasynchronous distribution service that defines a set ofrules to receive, route, and send electronic mail in anetwork of systems.

SNADS . See SNA distribution services (SNADS).

SNADS receiver . A user-configured (using theADDCMNE command) batch job that is started in thesubsystem specified on the communications entrywhen the system receives SNADS distribution from asending system in the SNADS network. Contrast withSNADS sender. See also SNADS router.

SNADS routing function . The SNADS exit pointprograms that are registered in the mail serverframework.

SNADS sender . A user-configured (by using theCFGDSTSRV command to add the SNADS distributionqueue) batch job that is started in the QSNADSsubsystem, and sends distributions to another systemin the SNADS network. Contrast with SNADSreceiver. See also SNADS router.

SNA network . The part of the user applicationnetwork that conforms to the formats and protocols of

388 AnyMail/400 MSF

Page 413: AnyMail/400 Mail Server Framework Developer Guide January 1995

Systems Network Architecture. The SNA networkconsists of network addressable units, boundaryfunction parts, and the path control network.

snap-in . A registered user exit program that isspecifically for mail server framework user exit points.It is these exit point programs that affect MSFmessage flow by manipulating information associatedwith the message.

snap-in provided information (SPIN) . An area wheresnap-in user exit points programs can storeinformation that other snap-ins can use. SPINprovides a place where information relating to aspecific recipient can be stored and used by snap-insin the same user exit point or in different user exitpoints. The information that is stored in snap-inprovided information is completely user defined andinterpreted data.

SNMP. See Simple Network Management Protocol(SNMP).

source file . A file of programming code that is notcompiled into machine language. A source file can becreated by the specification of FILETYPE(*SRC) on theCreate command. A source file can contain sourcestatements for such items as high-level languageprograms and data description specifications.Contrast with data file.

SPIN. See snap-in provided information (SPIN).

spooled file . A file that holds output data waiting tobe processed, such as information waiting to beprinted. Also known as spooled output file.

state . The attribute of a program that determines thedomain of objects it can access directly. See alsodomain, system domain object, user domain object,system state program, and user state program.

subsystem . An operating environment, defined by asubsystem description, where the system coordinatesprocessing and resources.

subsystem description . A system object thatcontains information defining the characteristics of anoperating environment controlled by the system. Thesystem-recognized identifier for the object type is*SBSD.

synchronous processing . A series of operations thatare done as part of the job in which they wererequested; for example, calling a program in aninteractive job at a work station. Contrast withasynchronous processing.

system distribution directory . A list of user IDs andidentifying information, such as network addresses,used to send distributions.

system domain object . An object on the system thatcan be accessed only by a system state program.The object types that can be either system domain oruser domain are: *USRSPC, *USRIDX, *USRQ, *PGM,*SQLPKG. All other object types are system domain.See also user domain object, user state program, andsystem state program.

system group . In SNADS, the second part of asystem name in the system distribution directory.

system library . The library shipped with the systemthat contains objects, such as authorization lists anddevice descriptions created by a user, and the systemcommands and other system objects required to runthe system. The system identifier is QSYS.

system object . A machine object classification. Anyof the machine objects shipped with the system orany of the operating system objects created by thesystem.

system operator message queue . A special messagequeue to which the system sends messages regardingchanges in the status of the system, devices, andjobs, and messages indicating a condition that needsoperator intervention. This message queue isidentified by the name QSYSOPR.

Systems Network Architecture distribution services .See SNA distribution services (SNADS).

Systems Network Architecture (SNA) . In IBMnetworks, the description of the layered logicalstructure, formats, protocols, and operationalsequences that are used for transmitting informationunits through networks, as well as controlling theconfiguration and operation of networks.

system state program . A program that can access auser domain object or a system domain object. Thesystem state is reserved for IBM-supplied programs.See also system domain object, user domain object,and user state program.

throughput . (1) The measure of the amount of workperformed by a computer over a period of time, forexample, number of jobs per day. (2) In datacommunications, the total traffic between stationsover a period of time.

time stamp . (1) To apply the current system time.(2) The value of an object that indicates the systemtime at some critical point in the object′s history.

topology . The schematic arrangement of the linksand nodes of a network.

Transmission Control Protocol/Internet Protocol(TCP/IP). A set of communications protocols thatsupport peer-to-peer connectivity functions for bothlocal and wide area networks.

Glossary 389

Page 414: AnyMail/400 Mail Server Framework Developer Guide January 1995

use authority . An object authority that allows theuser to run a program or to display the contents of afile. Use authority combines object operationalauthority, read authority, and execute authority.

user domain object . An object on the system thatcan be accessed directly by a user state program.The object types that can be either system domain oruser domain are: *USRSPC, *USRIDX, *USRQ, *PGM,*SQLPKG. All other object types are system domain.See also system domain object, user state program,and system state program.

user ID/address . The two-part network name used inthe system distribution directory and in the officeapplications to uniquely identify a user.

user message queue . A user-created object used toreceive messages sent from the system, other users,and application programs.

user profile . An object with a unique name thatcontains the user’s password, the list of specialauthorities assigned to a user, and the objects theuser owns. The system-recognized identifier for theobject type is *USRPRF.

user space . In OS/400 application programminginterfaces, an object consisting of a collection of bytesthat can be used for storing any user-definedinformation. The system-recognized identifier for theobject type is *USRSPC.

user state program . A program that can accessobjects in the user domain. All user programs on thesystem are user domain. A user state program cancall only another user state program. See alsosystem domain object, user domain object, and systemstate program.

value . Data (numbers or character strings) enteredin any entry field, and data supplied in parameters ofCL commands.

variable . A name used to represent data that can bechanged while the program or procedure is running.

Vendor Independent Messaging (VIM) . An applicationprogram interface (API) defined by Apple Computer,Inc.; Borland International, Inc.; Lotus DevelopmentCorporation; and Novell, Inc.

wildcard . A special character such as an asterisk (*)or a question mark (?) that can be used to representone or more characters. Any character or set ofcharacters can replace a pattern-matching character.Synonymous with global character, wildcardcharacter.

write authority . An object authority that allows theuser to add, change, and delete entries in an object.Write authority combines object operational authority,add authority, update authority, and delete authority.The system-recognized identifier is *W.

write/execute authority . An object authority thatallows the user to add, change, and delete entries inan object, run a program, and search a library ordirectory. Write/execute authority combines objectoperational authority, add authority, update authority,delete authority, and execute authority. Thesystem-recognized identifier is *WX.

X.400. A CCITT Recommendation for internationalelectronic mail (messages).

X.500. A CCITT Recommendation for OSI directoryservice.

390 AnyMail/400 MSF

Page 415: AnyMail/400 Mail Server Framework Developer Guide January 1995

Index

Aaccess ID, file server object 258Add Mail Server Framework Configuration

(QzmfAddMailCfg) API 137address type

definit ion 5IBM-supplied 20

addressing groupspecial properties 101

addressing group exit pointsaddress resolution 6list expansion 6

alertable message 211alternate recipient allowed 236AnyMail/400

definit ion 1API (application programming interface)

Assign SNADS File Server Object Access ID(QZDASNID) 257

Change Mail Message (QzmfChgMailMsg) 172Complete Creation Sequence

(QzmfCrtCmpMailMsg) 184configuration 133Create Mail Message (QzmfCrtMailMsg) 163Create SNADS File Server Object

(QZDCRFSO) 247List SNADS File Server Object Access IDs

(QZDLSTID) 261message 134name 206Query Mail Message Identifier

(QzmfQryMailMsgId) 187Read SNADS File Server Object (QZDRDFSO) 253Remove Reserved Mail Message Identif ier

(QzmfRmvRsvMailMsgId) 182Reserve Mail Message Identif ier

(QzmfRsvMailMsgId) 179Retrieve Mail Message (QzmfRtvMailMsg) 168Retrieve SNADS File Server Object Access ID

(QZDRTVID) 265Revoke SNADS File Server Object Access ID

(QZDRVKID) 259Write to SNADS File Server Object

(QZDWTFSO) 249application packaging 203application process 199application programming interface (API)

Assign SNADS File Server Object Access ID(QZDASNID) 257

Change Mail Message (QzmfChgMailMsg) 172Complete Creation Sequence

(QzmfCrtCmpMailMsg) 184configuration 133Create Mail Message (QzmfCrtMailMsg) 163

application programming interface (API) (continued)Create SNADS File Server Object

(QZDCRFSO) 247List SNADS File Server Object Access IDs

(QZDLSTID) 261message 134name 206Query Mail Message Identifier

(QzmfQryMailMsgId) 187Read SNADS File Server Object (QZDRDFSO) 253Remove Reserved Mail Message Identif ier

(QzmfRmvRsvMailMsgId) 182Reserve Mail Message Identif ier

(QzmfRsvMailMsgId) 179Retrieve Mail Message (QzmfRtvMailMsg) 168Retrieve SNADS File Server Object Access ID

(QZDRTVID) 265Revoke SNADS File Server Object Access ID

(QZDRVKID) 259Write to SNADS File Server Object

(QZDWTFSO) 249application reference unique ID 237application unique ID 237applications, MSF

debugging 202install ing 203testing 202

AS/400 program authority 205Assign SNADS File Server Object Access ID

(QZDASNID) API 257attachment 238attachment reference list

definit ion 13using 62

attachment reference list entry 63attachment reference type

definit ion 6IBM-supplied 21

authori tyAS/400 program 205MSF program 205object 205

BBCC (blind carbon copy) 64blind carbon copy (BCC) 64

CC code example

system distribution directory 280carbon copy (CC) 64CC (carbon copy) 64

Copyright IBM Corp. 1995 391

Page 416: AnyMail/400 Mail Server Framework Developer Guide January 1995

CF journal entry 214Change Mail Message (QzmfChgMailMsg) API 172changing a mail message 172CL command

End Mail Server Framework (ENDMSF) 37ENDMSF (End Mail Server Framework) 37Start Mail Server Framework (STRMSF) 29STRMSF (Start Mail Server Framework) 29

code examplesystem distribution directory 280

code S 213command, CL

End Mail Server Framework (ENDMSF) 37ENDMSF (End Mail Server Framework) 37Start Mail Server Framework (STRMSF) 29STRMSF (Start Mail Server Framework) 29

common header format 50common list entry format 52common problems 227Complete Creation Sequence (QzmfCrtCmpMailMsg)

API 184configuration API

Add Mail Server Framework Configuration(QzmfAddMailCfg) 21

descriptions 133List Mail Server Framework Configuration

(QzmfLstMailCfg) 21QzmfAddMailCfg (Add Mail Server Framework

Configuration) 21QzmfLstMailCfg (List Mail Server Framework

Configuration) 21QzmfRmvMailCfg (Remove Mail Server Framework

Configuration) 21Remove Mail Server Framework Configuration

(QzmfRmvMailCfg) 21configuration, MSF 18continuation access ID, file server object 262conversion allowed 236copying the MSF configuration 30correlation, fi le server object 258CPF messages 211Create ILE C/400 Module (CRTCMOD) command 199Create Mail Message (QzmfCrtMailMsg) API 163Create SNADS File Server Object (QZDCRFSO)

API 247creating a mail message 163creating a message

using MSF message lists 153creating an MSF program in ILE C/400 199creating ILE C/400 module 199creating MSF messages 13, 46creation date/t ime 233CRTCMOD (Create ILE C/400 Module) command 199

Ddata type

address 19attachment reference 19

data type (continued)envelope 19message 19MSF 18order of exit point programs 93selecting exit point programs 90, 98, 101using address type 98, 101using message type 98, 101

data type definition 19data type value

definit ion 19reserved 19

date and time attributes 233debugging

MSF application 208debugging MSF applications interactively 202delivery group exit points

local delivery 10message forwarding 10

delivery report 235delivery type 233DIA file server 245disclose recipients 236displaying

entries 217journal 214

Eelectronic signature 238encryption 236End Mail Server Framework (ENDMSF) command 37envelope list

definit ion 13using 56

envelope list entry 57envelope type

definit ion 6IBM-supplied 20

ER journal entry 214error conditions

Change Mail Message (QzmfChgMailMsg) API 173Complete Creation Sequence

(QzmfCrtCmpMailMsg) API 185Create Mail Message (QzmfCrtMailMsg) API 165Query Mail Message Identifier (QzmfQryMailMsgId)

API 189Remove Reserved Mail Message Identif ier

(QzmfRmvRsvMailMsgId) API 182Reserve Mail Message Identif ier

(QzmfRsvMailMsgId) API 180Retrieve Mail Message (QzmfRtvMailMsg)

API 169Snap-In Call exit point 198Track Mail Message Changes 195Validate Data Field exit point 193

error information 208error messages 209

392 AnyMail/400 MSF

Page 417: AnyMail/400 Mail Server Framework Developer Guide January 1995

error recovery 213errors signalled by MSF 211example

Change Mail Message (QzmfChgMailMsg) API 175changing an MSF message 114Complete Creation Sequence

(QzmfCrtCmpMailMsg) API 186Create Mail Message (QzmfCrtMailMsg) API 166exit point programs 81exit points 81journal entry fields 218List Mail Configuration API 144MSF application

header fi le 295order of exit point programs 93program using Search System Directory API 280putting back a recipient with QzmfChgMailMsg 95Query Mail Message Identifier (QzmfQryMailMsgId)

API 190QzmfChgMailMsg API 129QzmfCrtMailMsg API 127Remove Reserved Mail Message Identif ier

(QzmfRmvRsvMailMsgId) API 183Reserve Mail Message Identif ier

(QzmfRsvMailMsgId) API 180Retrieve Mail Message (QzmfRtvMailMsg)

API 170selecting exit point programs by data type 90SNADS file server APIs 267Snap-In Call exit point 198Track Mail Message Changes 195Validate Data Field exit point 127, 129, 193

example of putting back a recipient 95existing MSF messages

example 31preparing 31

exit pointaddressing group

address resolution 7list expansion 7

delivery grouplocal delivery 11message forwarding 11

example 3groups 80IBM-supplied

QIBM_QZMFMSF_ACT 22QIBM_QZMFMSF_ADR_RSL 22QIBM_QZMFMSF_ATT_CNV 22QIBM_QZMFMSF_ATT_MGT 22QIBM_QZMFMSF_ENL_PSS 22QIBM_QZMFMSF_LCL_DEL 22QIBM_QZMFMSF_LST_EXP 22QIBM_QZMFMSF_MSG_FWD 22QIBM_QZMFMSF_NON_DEL 22QIBM_QZMFMSF_SEC_AUT 22QIBM_QZMFMSF_TRK_CHG 22QIBM_QZMFMSF_VLD_TYP 22

exit point (continued)interfaces 192management group

accounting 13attachment management 12non-delivery 12

pre-delivery processing groupattachment conversion 9envelope processing 9security and authority 10

registered 81Track Mail Message Changes 194Validate Data Field 192

exit point call history list 74exit point call history list entry 75exit point program

considerations 82how to register 23IBM-supplied

QZMFSNPA 291QSYS/QZDSNPAC 22QSYS/QZDSNPAD 22QSYS/QZDSNPAM 22QSYS/QZDSNPLD 22QSYS/QZDSNPLE 22QSYS/QZDSNPMF 22QSYS/QZDSNPND 22QSYS/QZMFSNPA 22QZMFSNPA 291registering 23

exit point program registrationexample 16

exit point programsspecial considerations 199

expand distribution list 237expiration date/t ime 233

Ffeatures, ILE C/400 201fi le server

DIA fi le server 245SNADS general file server 245

file server objectaccess ID 258attachment reference 246continuation access ID 262correlation 258handle 248server name 248system object considerations 244usage count 246

file server operationsoverview 244

fixed value attributes 233format name, program data 27formatt ing

QZMF journal 214

Index 393

Page 418: AnyMail/400 Mail Server Framework Developer Guide January 1995

forward notif ication 236

Ggeneric envelope (GET)

alternate recipient allowed 236application reference unique ID 237application unique ID 237attachment 238attribute definit ion 230considerations for GET attributes 231contents 229conversion allowed 236creation date/t ime 233definit ion 228delivery report 235delivery type 233disclose recipients 236electronic signature 238encryption 236expand distribution list 237expiration date/t ime 233extensions 243forward notif ication 236header 229importance 235message size 237no loss conversion 236non-delivery report 235note content 232object distribution facil ity parameters 239prior i ty 234reassignment of recipient 237receipt notif ication 236reference 232reply-by date/t ime 233return contents 235sensit ivity 235subject 232used by object distribution facility 242used by OfficeVision/400 241

GET (generic envelope)attribute definit ion 230considerations for GET attributes 231contents 229definit ion 228extensions 243header 229used by object distribution facility 242used by OfficeVision/400 241

GET envelopeattribute definit ion 230considerations for GET attributes 231contents 229definit ion 228extensions 243header 229used by object distribution facility 242used by OfficeVision/400 241

glossary 382

Hhandle, file server object 248header fi le

exampleTESTMSG 296

Qzmf 356Qzmfasrv 375

history l ist 74

IIBM-supplied data types 19IBM-supplied exit point programs 22IBM-supplied exit points 22ILE C/400 features 201importance 235installing mail applications 207interfaces, exit point 192

Jjournal

displaying 214entries

displaying 217displaying QZMF 214type CF 225type ER 221, 222type LG 219type SY 223, 224

QZMFconfiguration changes (CF) 226description 213displaying 214error entry (ER) 222formatt ing 214logging (LG) 220support 213system level events table (SY) 224

receiverfull 214new 226

journal, MSF 213

LLG journal entry 214list entry ID 52list entry reference ID 53List Mail Server Framework Configuration

(QzmfLstMailCfg) API 142List SNADS File Server Object Access IDs

(QZDLSTID) API 261

394 AnyMail/400 MSF

Page 419: AnyMail/400 Mail Server Framework Developer Guide January 1995

Mmail applications, installing 207mail message

changing 172creating 163retr ieving information 168

mail server framework (MSF)API summary 133automatic starting 41benefits 2concepts 3configuration 18, 30data type definition

rules 19definit ion 1ending 37introduction 1job structure 39message content 44message identif iers 46message list formats 49operations 29performance 40queue 39, 43start ing 29using 2, 29

management group exit pointsaccounting 11attachment management 11non-delivery 11

messageno log entries 218

message API descriptions 133message descriptor arrays

building 152how to build example 153

message descriptorsused to retrieve information 159

message flowexample 4MSF 15

message identif iers 46message list

concepts 146defining in ILE C/400 148formats 49used to create a message 153using to change a message 161working with 146

message lists, MSFdescription 48overview 48rules 49

message size 237message type

definit ion 5IBM-supplied 20

MSF API authority 206MSF APIs, summary 133MSF application

debugging 208errors 208header fi le example 295

MSF command authority 206MSF configuration APIs

QzmfAddMailCfg 21QzmfLstMailCfg 21QzmfRmvMailCfg 21

MSF data type 18MSF exit point

definit ion 80snap-in 80

MSF exit point program data, rules 27MSF exit points

address resolution, reevaluation 104changing an MSF message 114description 80design considerations

E-Mail security 83error handling 83interaction with other exit points 84performance 82reentrant programming 83

list expansion, reevaluation 102multiple exit point programs 87order of programs 93program design 86rules 118selecting by address type 98, 101selecting by data type 90selecting by message type 98selecting by message type and status 98selection of exit point programs 87Track Changes API 123Validate Data Field API 125

MSF File authority 207MSF journal 213MSF message

cleared 34flow 15information data types 48placed on MSF queue 32reset 35resumed 34system considerations 78

MSF message listformats 49

MSF program authority 206MSG program

created in ILE C/400 199

Nno loss conversion 236non-delivery report 235

Index 395

Page 420: AnyMail/400 Mail Server Framework Developer Guide January 1995

note content 232

Oobject authori ty

definit ion 205object distribution facil ity parameters 239original recipient l ist

definit ion 13using 64

original recipient l ist entry 65originator l ist

definit ion 13using 53

originator l ist entry 54OS/400 user registration facility 22outfile format (OUTFILFMT) parameter 214OUTFILFMT (outfile format) parameter 214

Pparameters

Change Mail Message (QzmfChgMailMsg) API 172Complete Creation Sequence

(QzmfCrtCmpMailMsg) API 184Create Mail Message (QzmfCrtMailMsg) API 163Query Mail Message Identifier (QzmfQryMailMsgId)

API 187Remove Reserved Mail Message Identif ier

(QzmfRmvRsvMailMsgId) API 182Reserve Mail Message Identif ier

(QzmfRsvMailMsgId) API 179Retrieve Mail Message (QzmfRtvMailMsg)

API 169Snap-In Call exit point 197Track Mail Message Changes 194Validate Data Field exit point 192

performance, MSF 40pre-delivery processing group exit points

attachment conversion 8envelope processing 8security and authority 8

predefined data types 19predefined exit point 22predefined exit point program 22preparing existing MSF messages 31prior i ty 234processing

electronic messages 1product ID 258program data format name 27program name 206put back 95

QQIBM_QZMFMSF_TRK_CHG 123QIBM_QZMFMSF_VLD_TYP 125

QMSF jobending 41structure 39submission 36

QMSF joblog 208QSYSOPR message queue 208QSYSWRK subsystem 36, 39Query Mail Message Identifier (QzmfQryMailMsgId)

API 187QZDASNID (Assign SNADS File Server Object Access

ID) API 257QZDCRFSO (Create SNADS File Server Object)

API 247QZDLSTID (List SNADS File Server Object Access

IDs) API 261QZDRDFSO (Read SNADS File Server Object)

API 253QZDRTVID (Retrieve SNADS File Server Object

Access ID) API 265QZDRVKID (Revoke SNADS File Server Object Access

ID) API 259QZDWTFSO (Write to SNADS File Server Object)

API 249Qzmf header file 356QZMF journal 209, 213QzmfAddMailCfg (Add Mail Server Framework

Configuration) API 137Qzmfasrv header fi le 375QzmfChgMailMsgQzmfChgMailMsg (Change Mail Message) API 172QzmfCrtCmpMailMsg (Complete Creation Sequence)

API 184QzmfCrtMailMsg (Create Mail Message) API 163QzmfLstMailCfg (List Mail Server Framework

Configuration) API 142QzmfQryMailMsgId (Query Mail Message Identifier)

API 187QzmfRmvMailCfg (Remove Mail Server Framework

Configuration) API 140QzmfRmvRsvMailMsgId (Remove Reserved Mail

Message Identifier) API 182QzmfRsvMailMsgId (Reserve Mail Message Identifier)

API 179QzmfRtvMailMsg (Retrieve Mail Message) API 168QZMFSNPA exit point program

description 291

RRead SNADS File Server Object (QZDRDFSO)

API 253reassignment of recipient 237receipt notif ication 236recipient history list 76recipient history l ist entry 76recipient l ist

definit ion 13status fieldused to select exit point programs 110

396 AnyMail/400 MSF

Page 421: AnyMail/400 Mail Server Framework Developer Guide January 1995

recipient l ist (continued)using 58

recipient l ist entry 59recipient list status

used to select exit point programs 110reference 232registering exit point program 23registration facility APIs

Add Exit Program (QusAddExitProgram) 28Deregister Exit Point (QusDeregisterExitPoint) 28Register Exit Point (QusRegisterExitPoint) 28Remove Exit Program

(QusRemoveExitProgram) 28Remove Mail Server Framework Configuration

(QzmfRmvMailCfg) API 140Remove Reserved Mail Message Identif ier

(QzmfRmvRsvMailMsgId) API 182reply-by date/t ime 233reply-to list

definit ion 13using 67

reply-to l ist entry 67report-on list

definit ion 13using 71

report-on list entry 71report-to l ist

definit ion 13using 69

report-to l ist entry 69Reserve Mail Message Identifier (QzmfRsvMailMsgId)

API 179reserved data types 19reserved exit point 22reserved exit point program 22resetting an MSF message 47Retrieve Mail Message (QzmfRtvMailMsg) API 168Retrieve SNADS File Server Object Access ID

(QZDRTVID) API 265retrieving information using message

descriptors 159retrieving mail message information 168return codes 210return contents 235return value

Change Mail Message (QzmfChgMailMsg) API 173Complete Creation Sequence

(QzmfCrtCmpMailMsg) API 185Create Mail Message (QzmfCrtMailMsg) API 165Query Mail Message Identifier (QzmfQryMailMsgId)

API 188Remove Reserved Mail Message Identif ier

(QzmfRmvRsvMailMsgId) API 182Reserve Mail Message Identif ier

(QzmfRsvMailMsgId) API 180Retrieve Mail Message (QzmfRtvMailMsg)

API 169

Revoke SNADS File Server Object Access ID(QZDRVKID) API 259

rules for MSG exit point program data 27rules, data type definition 19

SS code 213Search System Directory (QOKSCHD) API 280security 205sensit ivity 235server name, fi le server object 248SNADS file server APIs 244SNADS general file server 245Snap-In Call exit point interface 197Snap-in exit point 80special exit points 123SPIN 61Start Mail Server Framework (STRMSF)

command 29starting MSF 29status

ignore 112local 110non-delivery 110remote 110security violation 113used to select exit point programs 110

subject 232SY journal entry 214system considerations for MSF messages 78system distribution directory

addresses 291code example 280commands 276description 276entry display 276helpful hints 290preferred address 291searches 280searching 279, 280, 291shadowing 276used by QZMFSNPA 291user-defined fields 279using 276

TTCRTMSG program 320terminology 382testing MSF applications interactively 202text attributes 231Track Mail Message Changes exit point interface 194type groups

address 18attachment reference 18envelope 18message 18

Index 397

Page 422: AnyMail/400 Mail Server Framework Developer Guide January 1995

type namedefinit ion 19

type textdefinit ion 19

typed information 5

Uusage count, file server object 246user registration facility, OS/400 22

VValidate Data Field exit point interface 192variable length fields 151

WWrite to SNADS File Server Object (QZDWTFSO)

API 249

398 AnyMail/400 MSF

Page 423: AnyMail/400 Mail Server Framework Developer Guide January 1995

ITSO Technical Bulletin Evaluation RED000

International Technical Support OrganizationAnyMail/400 Mail Server FrameworkDeveloper GuideJanuary 1995

Publication No. GG24-4449-00

Your feedback is very important to help us maintain the quality of ITSO Bulletins. Please fill out thisquestionnaire and return it using one of the following methods:

• Mail it to the address on the back (postage paid in U.S. only)• Give it to an IBM marketing representative for mailing• Fax it to: Your International Access Code + 1 914 432 8246• Send a note to [email protected]

Please rate on a scale of 1 to 5 the subjects below.(1 = very good, 2 = good, 3 = average, 4 = poor, 5 = very poor)

Overall Satisfaction ____

Organization of the bookAccuracy of the informationRelevance of the informationCompleteness of the informationValue of illustrations

____________________

Grammar/punctuation/spell ingEase of reading and understandingEase of finding informationLevel of technical detailPrint quality

____________________

Please answer the following questions:

a) If you are an employee of IBM or its subsidiaries:

Do you provide billable services for 20% or more of your time? Yes____ No____

Are you in a Services Organization? Yes____ No____

b) Are you working in the USA? Yes____ No____

c) Was the Bulletin published in time for your needs? Yes____ No____

d) Did this Bulletin meet your needs? Yes____ No____

If no, please explain:

What other topics would you like to see in this Bulletin?

What other Technical Bulletins would you like to see published?

Comments/Suggestions: ( THANK YOU FOR YOUR FEEDBACK! )

Name Address

Company or Organizat ion

Phone No.

Page 424: AnyMail/400 Mail Server Framework Developer Guide January 1995

Cut or FoldAlong Line

Cut or FoldAlong Line

ITSO Technical Bulletin Evaluation RED000GG24-4449-00 IBML

Fold and Tape Please do not staple Fold and Tape

NO POSTAGENECESSARYIF MAILED IN THEUNITED STATES

BUSINESS REPLY MAILFIRST-CLASS MAIL PERMIT NO. 40 ARMONK, NEW YORK

POSTAGE WILL BE PAID BY ADDRESSEE

IBM International Technical Support OrganizationDepartment 9773605 HIGHWAY 52 NORTHROCHESTER MNUSA 55901-7829

Fold and Tape Please do not staple Fold and Tape

GG24-4449-00

Page 425: AnyMail/400 Mail Server Framework Developer Guide January 1995
Page 426: AnyMail/400 Mail Server Framework Developer Guide January 1995

IBML

Printed in U.S.A.

GG24-4449-00

Page 427: AnyMail/400 Mail Server Framework Developer Guide January 1995

/XRL/1

Bookmarks

Page Bookmarks

23 Screen: SCRxx001 -- Work with Registration Information idssname uimname24 Screen: SCRxx001 -- Work with Exit Programs idssname uimname24 Screen: SCRxx001 -- Add Exit Program (ADDEXITPGM) idssname uimname25 Screen: SCRxx001 -- Add Exit Program (ADDEXITPGM) idssname uimname26 Screen: SCRxx001 -- Add Exit Program (ADDEXITPGM) idssname uimname26 Screen: SCRxx001 -- Work with Exit Programs idssname uimname215 Screen: SCRxx001 -- Display Journal (DSPJRN) idssname uimname215 Screen: SCRxx001 -- Display Journal (DSPJRN) idssname uimname216 Screen: SCRxx001 -- Display Journal (DSPJRN) idssname uimname217 Screen: SCRxx001 -- Display Journal Entries idssname uimname219 Screen: SCRxx001 -- Display Journal Entry idssname uimname221 Screen: SCRxx001 -- Display Journal Entry idssname uimname223 Screen: SCRxx001 -- Display Journal Entry idssname uimname225 Screen: SCRxx001 -- Display Journal Entry idssname uimname277 Screen: SCRxx001 -- Display Directory Entry Details idssname uimname277 Screen: SCRxx001 -- Display Directory Entry Details idssname uimname278 Screen: SCRxx001 -- Display Directory Entry Details idssname uimname278 Screen: SCRxx001 -- Display Directory Entry Details idssname uimname290 Screen: SCRxx001 -- Full name : Gordon, Gregory D. (Greg) idssname uimname

Artwork Definitions

id File Page References

ITSLOGO 4449SUi i

LERS Definitions

id File Page References

UXIAPI 4449SUi 163, 168, 172, 179, 181, 184, 187, 192, 194, 197

Table Definitions

id File Page References

FRMBODY 4449SUi i, 50, 54, 57, 59, 63, 65, 67, 69, 71, 75, 76

FRMHEAD 4449SUi 50, 54, 57, 59, 63, 65, 67, 69, 71, 75, 76

EPTT1 4449EPTO118

EPTT2 4449EPTO119

EPTT3 4449EPTO119

EPTT4 4449EPTO120

EPTT5 4449EPTO121

ADDCTAB 4449CAPI137 137, 137, 137

ADDCHED 4449CAPI137 137

DLTCTAB 4449CAPI140 140, 140

DLTCHED 4449CAPI140 140

LSTLTAB 4449CAPI143 143, 143

LSTLHED 4449CAPI143 143

LSTCTAB 4449CAPI143 143, 143

LSTCHED 4449CAPI143 143

FFD 4449DBGJ220 220, 222, 224, 226

FSOBODY 4449FSO1

Page 428: AnyMail/400 Mail Server Framework Developer Guide January 1995

/XRL/2

248 248, 248, 262, 263, 263, 263FSOHEAD 4449FSO1

248 248, 262, 263, 263, 263

Figures

id File Page References

TROART1 4449TRO1 1

1CAPART1 4449CAP

3 23

CAPART2 4449CAP5 3

4EPTARG3 4449CAP

6 4EPTARG4 4449CAP

8 5EPTARG5 4449CAP

10 6EPTARG7 4449CAP

12 7CAPART3 4449CAP

14 815

CAPP168 4449CAP16 9

16BIGCFG 4449CFG

18 1018

WUEPT4 4449CFG23 11

23WUEPG5 4449CFG

24 1223

ADDEPG6 4449CFG24 13

24ADDEPG7 4449CFG

25 1424

ADDEPG8 4449CFG26 15

25WEPG8 4449CFG

26 1626

OPRARTC 4449OPR30 17

30OPRART1 4449OPR

32 1831

OPRART2 4449OPR33 19

32OPRART6 4449OPR

34 2034

OPRART4 4449OPR35 21

34OPRART5 4449OPR

36 2235

OPRARTA 4449OPR37 23

36, 36, 39OPRARTE 4449OPR

39 2438

OPRART3 4449OPR41 25

40MSGART1 4449MSG

45 2644, 45

MSGART2 4449MSG

Page 429: AnyMail/400 Mail Server Framework Developer Guide January 1995

/XRL/3

47 2746

MAHF 4449MSGH50 28

LEHF 4449MSGH52 29

MAOL 4449MSGO53 30

54MAEL 4449MSGE

56 3156

MARL 4449MSGR59 32

58MAAL 4449MSGA

62 33MAGL 4449MSGG

64 34MALL 4449MSGY

67 3562, 67

MATL 4449MSGT69 36

MAPL 4449MSGP71 37

MAXL 4449MSGX74 38

MASL 4449MSGS76 39

EPTART1 4449EPT81 40

80, 81EPTART2 4449EPT

86 4186

EPTARTX 4449EPT87 42

87EPTARTZ 4449EPT

87 4387

MSGART3 4449EPT88 44

88EPTART3 4449EPT

90 4590, 90

EPTART4 4449EPT91 46

91EPTART5 4449EPT

92 4792

EPTART8 4449EPT93 48

93EPTART9 4449EPT

94 4994, 95

EPTART6 4449EPT96 50

96EPTART7 4449EPT

97 5195, 97

EPTARC3 4449EPT99 52

98, 100EPTARC4 4449EPT

100 53100

EPTAC3T 4449EPT102 54

102EPTAC2T 4449EPT

103 55103

EPTAC1T 4449EPT104 56

104EPTRA1T 4449EPT

105 57104, 105

EPTRA2T 4449EPT

Page 430: AnyMail/400 Mail Server Framework Developer Guide January 1995

/XRL/4

106 58106

EPTRA3T 4449EPT107 59

107, 107EPTRA4T 4449EPT

109 60109, 109

EPTARS1 4449EPT111 61

110, 112EPTARC1 4449EPT

115 62115, 124, 124

EPTARC2 4449EPT116 63

116, 117EPTARG9 4449EPT

122 64EPTTR1 4449EPTX

124 65124

EPTVA1 4449EPTX126 66

126, 126, 126EPTVA5 4449EPTX

127 67127, 127

EPTVA6 4449EPTX128 68

128, 128, 128, 129, 129, 131, 132, 132EPTVA3 4449EPTX

130 69129, 130, 130

EPTVA4 4449EPTX131 70

131, 131APIARTC 4449API

134 71134

APIARTM 4449API135 72

134LSTART1 4449LSTA

147 73147, 152

DSPJRN1 4449DBGJ215 74

DSPJRN2 4449DBGJ215 75

DSPJRN3 4449DBGJ216 76

DSPJRNE 4449DBGJ217 77

217EXENTRY 4449DBGJ

218 78218, 218, 222, 224, 226

DJLG 4449DBGJ219 79

219, 220DJER 4449DBGJ

221 80221

DJSY 4449DBGJ223 81

223DJCF 4449DBGJ

225 82225

DSPDIR1 4449DIR277 83

DSPDIR2 4449DIR277 84

DSPDIR3 4449DIR278 85

DSPDIR4 4449DIR278 86

DIRART1 4449DIR279 87

278DIRART2 4449SWI

292 88292

Page 431: AnyMail/400 Mail Server Framework Developer Guide January 1995

/XRL/5

Headings

id File Page References

NOTICES 4449FMxiv Special Notices

iiBIBL 4449PREF

xvii i Related PublicationsINTRO 4449TRO

1 Chapter 1, Introduction to AnyMail/400 Mai l ServerFramework

xvi, 3, 3TROBENE 4449TRO

2 Benefits of the Mail Server FrameworkCAPAB 4449CAP

3 Chapter 2, Mail Server Framework Conceptsxvi, 2, 18, 29, 39, 80, 80

MSFCFG 4449CAP5 Typing of MSF Data

18, 48ADREPT 4449CAP

6 Addressing Group Exit Points4

PREEPT 4449CAP8 Pre-delivery Processing Group Exit Points

4DELEPT 4449CAP

10 Delivery Group Exit Points4

MNGEPT 4449CAP11 Management Group Exit Points

4MSGCRT 4449CAP

13 Creating MSF MessagesMSFFLO 4449CAP

15 MSF Message FlowMSFDET 4449CAP

16 Determining the Exit Point Program to Call5, 59

CFGMSF 4449CFG18 Chapter 3, Mail Server Framework Configuration

xvi, 6, 16, 30, 31, 133, 133, 133, 192, 199, 348, 355CFGTYP 4449CFG

18 MSF Data Types138, 140, 280, 293

CFGRULE 4449CFG19 Rules for MSF Data Type Definitions

19, 138, 138, 138, 141, 141, 144, 144, 144, 144CFGIBMT 4449CFG

19 List of IBM-Supplied Data Types19

CFGAPIS 4449CFG21 MSF Configuration APIs

CFGREGF 4449CFG22 OS/400 User Registration Facility

CFGIBME 4449CFG22 IBM-Supplied Exit Points for the MSF

195EPGMNAM 4449CFG

22 IBM-Supplied Exit Point Programs for the MSFCFGREGE 4449CFG

23 Registering Exit Point ProgramsREGRULE 4449CFG

27 Rules for MSF Exit Point Program DataREGAPIS 4449CFG

28 Registration Facility APIsOPERAT 4449OPR

29 Chapter 4, Mail Server Framework Operationxvi

ACTIV 4449OPR29 Starting MSF

47, 209STRCMD 4449OPR

29 Start Mail Server Framework CommandSTART 4449OPR

30 Copying the MSF ConfigurationSTRMSG 4449OPR

31 Preparation of Existing MSF Messages29

STRSBM 4449OPR36 QMSF Job Submission

ENDING 4449OPR37 Ending MSF

ENDCMD 4449OPR

Page 432: AnyMail/400 Mail Server Framework Developer Guide January 1995

/XRL/6

37 End Mail Server Framework CommandENDOPT 4449OPR

38 Immediate or Controlled EndingMSFJOB 4449OPR

39 QMSF Job Structure37

MSFSCL 4449OPR40 MSF Scalabil ity

FIG 4449OPR41 Automatic Starting of MSF

MSFQUE 4449OPR43 MSF Queue

INMSG 4449MSG44 Chapter 5, Mail Server Framework Message

xvi, 14, 31, 85, 147, 159, 163, 168, 172, 229CRTMHDR 4449MSGH

50 MSF Message Lists Common HeaderCRTMFMT 4449MSGH

52 Common List Entry FormatCRTMID 4449MSGH

52 List Entry IDs172

CRTMRID 4449MSGH53 List Entry Reference IDs

172INEPT 4449EPT

80 Chapter 6, Mail Server Framework Exit Pointsxvi, 7, 8, 9, 9, 10, 11, 11, 12, 13, 13, 18, 22, 22, 159, 168,168, 172, 192, 197, 212

BASCHDR 4449EPT86 Basic Design of Exit Point Programs

114PUTEPT 4449EPT

87 Multiple Exit Point Programs17

DACYC 4449EPT90 Data Type Evaluation and Call Cycle

PUTBACK 4449EPT95 Using QzmfChgMailMsg to Put Back Recipients

89, 101DATAP 4449EPT

98 How MSF Uses Recipient List Address and Message TypesSPECP 4449EPT

101 Special Properties of the Addressing Group Exit Points98

STATP 4449EPT110 How MSF Uses Recipient List Status

88, 98CHGMMSG 4449EPT

114 How an Exit Point Program Changes a Message103, 106, 124

SPECX 4449EPTX123 Special Exit Points

81APISUM 4449API

133 Chapter 7, Summary of the Mai l Server Framework APIsxvi

APICFG 4449API134 Configurations APIs

APIMSG 4449API134 Message APIs

CFGAPI 4449CAPI137 Chapter 8, Mail Server Framework Configuration APIs

xvi, 21, 30CFGADD 4449CAPI

137 Add Mail Server Framework Configuration (QzmfAddMailCfg)API

ADDCFMT 4449CAPI137 ADDC0100 Format

ADDFLD 4449CAPI138 Add MSF Configuration API Field Descriptions

137CFGRMV 4449CAPI

140 Remove Mail Server Framework Configuration(QzmfRmvMailCfg) API

DLTCFMT 4449CAPI140 DLTC0100 Format

DLTFLD 4449CAPI140 Remove MSF Configuration Field Descriptions

140CFGLST 4449CAPI

142 List Mail Server Framework Configuration (QzmfLstMailCfg)API

LSTLFMT 4449CAPI143 LSTL0100 Format

Page 433: AnyMail/400 Mail Server Framework Developer Guide January 1995

/XRL/7

LSTCFMT 4449CAPI143 LSTC0100 Format

LSTFLD 4449CAPI143 List MSF Field Descriptions

143LSTAPI 4449LSTM

146 Chapter 9, Working with Mai l Message Listsxvi, 163, 168, 172

LSTBASI 4449LSTA146 MSF Message List − Introduction

LSTDEFC 4449LSTD148 Defining MSF Message Lists in ILE C/400

154LSTDO 4449LSTD

148 Defining a Recipient ListLSTPASC 4449LSTP

152 Building MSF Message Descriptor Arrays in ILE C/400154

LSTCRT 4449LSTB153 Using MSF Message Lists to Create a Message

164LSTSNAP 4449LSTS

155 Working with MSF Message Lists Passed to Exit PointPrograms

LSTRTVL 4449LSTR159 Using Message Descriptors to Retrieve Information

169LSTCHAG 4449LSTC

161 Using MSF Message Lists to Change a MessageCRTAPI 4449MCRM

163 Chapter 10, Creating a Mai l Messagexvi, 133, 154

CRTCH 4449MCRC163 Create Mail Message (QzmfCrtMailMsg) API

RTVAPI 4449MRTM168 Chapter 11, Retrieving Mai l Message Information

xvi, 133, 146, 160RTVRTN 4449MRTM

168 Information Returned by the Retrieve Mail Message APIRTVCH 4449MRTC

168 Retrieve Mail Message (QzmfRtvMailMsg) API123

CHGAPI 4449MCLM172 Chapter 12, Changing a Mai l Message

xvii, 133, 162CHGCH 4449MCLC

172 Change Mail Message (QzmfChgMailMsg) APIOTMAPI 4449MOTM

178 Chapter 13, Other Message APIsxvii, 133, 133, 133, 133

OTMUSE 4449MOTM178 How to Use These MSF APIs

RSVCH 4449MOTR179 Reserve Mail Message Identif ier (QzmfRsvMailMsgId) API

164, 164RRVCH 4449MOTD

182 Remove Reserved Mail Message Identif ier(QzmfRmvRsvMailMsgId) API

CMPCH 4449MOTC184 Complete Creation Sequence (QzmfCrtCmpMailMsg) API

QRYCH 4449MOTQ187 Query Mail Message Identif ier (QzmfQryMailMsgId) API

MEPAPI 4449MEPM192 Chapter 14, Additional Exit Point Interfaces

xvi iEPVCH 4449MEPV

192 Validate Data Field Exit Point125

EPTCH 4449MEPT194 Track Mail Message Changes Exit Point

123MEPSCE 4449MSCE

197 Chapter 15, Snap-In Call Exit Point Interfacexvii, 85, 85, 159

SCECH 4449MSCE197 Snap-In Call Exit Point

APPLC 4449APP199 Chapter 16, Creating an MSF Program in ILE C/400

xvi iAPPSTP 4449APP

199 MSF Application ProgramsAPPCRT 4449APP

199 Creating a Module and Program in ILE C/400 — Example200, 201, 201, 297, 322, 331, 335

APPSC 4449APP

Page 434: AnyMail/400 Mail Server Framework Developer Guide January 1995

/XRL/8

199 Special Considerations for MSF Exit Point Programs206

APPILE 4449APP201 Specific ILE C/400 Features and MSF Application Programs

APPAG 4449APP201 Selection of the Best Activation Group

APPCA 4449APP202 How Character Arrays are Interpreted

APPAT 4449APP202 Signal Handling Mechanism for Abnormal End

APPDBG 4449APP202 Interactive Testing and Debugging of an MSF Application

APPINST 4449APP203 Packaging an MSF Mail Application

SECINT 4449SEC205 Chapter 17, Security and Authori ty

xvii, 244SEC400 4449SEC

205 AS/400 Program AuthoritySECOBJ 4449SEC

205 Object AuthoritySECADTA 4449SEC

205 Adopting AuthoritySECMSF 4449SEC

206 MSF Program AuthoritySECCMD 4449SEC

206 MSF Command AuthoritySECAPIA 4449SEC

206 MSF API AuthoritySECFILE 4449SEC

207 MSF File AuthoritySECAPI 4449SEC

207 Mail Applications That Use MSF205

SECINST 4449SEC207 Install ing Mail Applications

DBGAPP 4449DBG208 Chapter 18, Error Handl ing in the Mail Server Framework

xvii, 41DBGLOG 4449DBG

208 Where to Look for Error InformationDBGQOPR 4449DBG

208 QSYSOPR Message QueueDBGJLOG 4449DBG

208 QMSF JoblogDBGULOG 4449DBG

209 User JoblogDBGMSFJ 4449DBG

209 MSF JournalDBGOTHR 4449DBG

209 Other PlacesDBGMSG 4449DBG

209 Error MessagesRCDBG 4449DBG

210 Setting Return Codes212

DBGJRN 4449DBGJ213 MSF Journal

209DBGJDS 4449DBGJ

213 Description of the QZMF JournalDBGJDJ 4449DBGJ

214 Displaying the QZMF JournalDISTSER 4449DBGJ

217 Displaying the Journal EntriesLGFLDS 4449DBGJ

218 Fields of a QZMF Journal EntryLGTYPE 4449DBGJ

220 Format for MSF Message Logging (LG) Entry219

ERTYPE 4449DBGJ222 Format for MSF Message Errors (ER)

221SYTYPE 4449DBGJ

224 Format for MSF System Level Events Table (SY)223

CFTYPE 4449DBGJ226 Format for MSF Configuration Changes (CF)

225DBGTIP 4449DBG

227 Common Problems Encountered When Using MSFGET 4449GET

228 Appendix A, Generic Envelope Type (GET)xvii, 9, 56

GMT 4449GET

Page 435: AnyMail/400 Mail Server Framework Developer Guide January 1995

/XRL/9

239 GET Date/Time GMT Structure75, 233

EXTGET 4449GET243 Extensions to the GET

231FSO1 4449FSO1

244 Appendix B, SNADS File Server APIsxvii, 178

ASRVKEX 4449FSO1246 Assign and Revoke APIs Example

245GFSAS 4449FSO1

257 Assign SNADS File Server Object Access ID (QZDASNID) APIGFSRVK 4449FSO1

259 Revoke SNADS File Server Object Access ID (QZDRVKID)API

257USERSPC 4449FSO1

263 Input Parameter SectionHEAD 4449FSO1

263 Header SectionLISTAC 4449FSO1

263 ACID0100 Format262

USERD 4449FSO1263 Field Descriptions

263XAMPLEA 4449FSO1

267 Creating an Attachment for an MSF Message267

XAMPLEB 4449FSO1270 Using an MSF Message with an Attachment

267XAMPLEC 4449FSO1

272 Receiving an MSF Message with an Attachment267

DIR 4449DIR276 Appendix C, Using the AS/400 System Distr ibution Directory

xvii, 15, 19DIRDSC 4449DIR

276 Description of the System Distribution DirectoryDIRUDF 4449DIR

279 User-Defined Directory Fields293

DIRAPI 4449DIR280 Search System Directory API

DIRSAM 4449DIR280 A Program that Uses the Search System Directory API —

ExampleDIRDS1 4449DIR

281 STRUCT.H Header File for Lookup.CDIRDS2 4449DIR

282 CONSTS.H Header File for Lookup.CDIRDS3 4449DIR

283 LOOKUP.C Program to Search DirectoryDIRDS4 4449DIR

290 Output from the LOOKUP.C ProgramDIRTIP 4449DIR

290 Helpful Hints about the System Distribution DirectoryDIRSWI 4449SWI

291 Appendix D, QZMFSNPA Exit Point Programxvii, 101

DIRDEC 4449SWI291 Description of the QZMFSNPA Exit Point Program

DIRUSE 4449SWI291 Use of the Preferred Address and Directory Search API

DIRSUDF 4449SWI293 Use of User-Defined Addresses

SAMPL 4449SAM294 Appendix E, An MSF Application — Example

xvii, xviii, 23, 138, 141, 144, 149, 151, 199, 199, 200SAMHDR 4449SAM

295 Header File Examples308

SAMTTY 4449SAM295 Header File Example — TESTTYPE

SAMTTE 4449SAM296 Header File Example — TESTMSG

SAMCP 4449SAM297 Type Configuration Program — Example

21, 23, 349SAMCPR 4449SAM

307 Results from the TCFGTYPE ProgramSAMCRT 4449SAM

308 Module and Program to Create MSF Messages — Example

Page 436: AnyMail/400 Mail Server Framework Developer Guide January 1995

/XRL/10

166, 320, 351SAMCRM 4449SAM

320 TCRTMSG ProgramSAMCRR 4449SAM

322 Results from the TCRTMSG ProgramSAMLE 4449SAM

322 List Expansion Exit Point Program — Example198

SAMAR 4449SAM331 Address Resolution Exit Point Program — Example

175SAMRET 4449SAM

335 Retrieval Exit Point Program — Example160, 171

SAMGLU 4449SAM348 Integrating the Programs

SAMRUN 4449SAM349 Running the Sample Programs

SAMRSV 4449SAM350 Program to Reserve and Query Message — Example

181, 183, 186, 190SAMRMV 4449SAM

355 Removal of Test TypesQZMFAP 4449QZMF

356 Appendix F, Qzmf Header Filexvii, 51, 152, 163, 164, 164, 164, 165, 169, 169, 169, 173,173, 173, 179, 179, 182, 182, 185, 185, 187, 187, 188,193, 193, 195, 197, 198, 198

QSRVAP 4449QSRV375 Appendix G, Qzmfasrv Header File

xvii, 138, 141, 144, 166, 170, 175, 180, 183, 186, 190

Index Entries

id File Page References

CLCMDA 4449OPR29 (1) command, CL

29, 29, 37, 37

Revisions

id File Page References

PUB ?? ?

30, 30

Spots

id File Page References

ZDCRFSO 4449FSO1268 Example using QZDCRFSO

249ZDWTFSO 4449FSO1

269 Example using QZDWTFSO253

ZDASNID 4449FSO1270 Example using QZDASNID

259ZDRVKID 4449FSO1

272 Example using QZDRVKID260

ZDRDFSO 4449FSO1274 Example using QZDRDFSO

257SAMCOMT 4449SAM3

305 (no text)355

Page 437: AnyMail/400 Mail Server Framework Developer Guide January 1995

/XRL/11

Tables

id File Page References

2CHAREP 4449CFG18 1

18ADDTYPE 4449CFG

20 2293

MSGTYPE 4449CFG20 3

ENVTYPE 4449CFG20 4

ATTTYPE 4449CFG21 5

IBMEPNT 4449CFG22 6

22IBMEPGM 4449CFG

22 722

DTAFMTN 4449CFG27 8

27APIT1 4449EPTO

118 10APIT2 4449EPTO

119 11APIT3 4449EPTO

119 12APIT4 4449EPTO

120 13APIT5 4449EPTO

121 14CFGTBL 4449API

133 15133

MSGTBL 4449API133 16

133PGMTBL 4449SEC

206 21201

TBLLG 4449DBGJ220 22

TBLER 4449DBGJ222 23

TBLSY 4449DBGJ224 24

TBLCF 4449DBGJ226 25

ATRTYPE 4449GET229 26

229FSNAME 4449FSO1

248 27252, 256

LSTSPC 4449FSO1262 28

HITABLE 4449SAM349 32

349

Page 438: AnyMail/400 Mail Server Framework Developer Guide January 1995

/XRL/12

Processing Options

Runtime values:Document fileid ........................................................................................... GG244449 SCRIPTDocument type ............................................................................................ USERDOCDocument style ........................................................................................... IBMXAGDProfile ........................................................................................................... EDFPRF40Service Level .............................................................................................. 0022SCRIPT/VS Release ................................................................................... 4.0.0Date .............................................................................................................. 95.01.17Time .............................................................................................................. 17:18:36Device .......................................................................................................... 3820ANumber of Passes ...................................................................................... 3Index ............................................................................................................. YESSYSVAR A .................................................................................................... NOSYSVAR D .................................................................................................... SBSYSVAR G ................................................................................................... INLINESYSVAR H ................................................................................................... NOSYSVAR S .................................................................................................... OFFSYSVAR T .................................................................................................... RIGHTSYSVAR V .................................................................................................... ITSCEVALSYSVAR X .................................................................................................... YESSYSVAR 1 .................................................................................................... NOTES

Formatting values used:Annotation .................................................................................................... NOCross reference listing .............................................................................. YESCross reference head prefix only ............................................................ NODialog ........................................................................................................... LABELDuplex .......................................................................................................... SBDVCF conditions file ................................................................................... (none)DVCF value 1 .............................................................................................. NOTESDVCF value 2 .............................................................................................. (none)DVCF value 3 .............................................................................................. (none)DVCF value 4 .............................................................................................. (none)DVCF value 5 .............................................................................................. (none)DVCF value 6 .............................................................................................. (none)DVCF value 7 .............................................................................................. (none)DVCF value 8 .............................................................................................. (none)DVCF value 9 .............................................................................................. (none)Explode ........................................................................................................ NOFigure list on new page ............................................................................. YESFigure/table number separation ............................................................... YESFolio-by-chapter .......................................................................................... NOHead 0 body text ........................................................................................ PartHead 1 body text ........................................................................................ ChapterHead 1 appendix text ................................................................................. AppendixHyphenation ................................................................................................ NOJustification ................................................................................................. NOLanguage ..................................................................................................... ENGLKeyboard ..................................................................................................... 395Layout .......................................................................................................... OFFLeader dots ................................................................................................. YESMaster index ............................................................................................... (none)Partial TOC (maximum level) .................................................................... 4Partial TOC (new page after) .................................................................... INLINEPrint example id ′s ...................................................................................... NOPrint cross reference page numbers ....................................................... YESProcess value ............................................................................................. (none)Punctuation move characters ................................................................... .,Read cross-reference fi le .......................................................................... (none)Running heading/footing rule .................................................................... NONEShow index entries ..................................................................................... NOTable of Contents (maximum level) ......................................................... 3Table list on new page .............................................................................. YESTitle page (draft) alignment ....................................................................... RIGHTWrite cross-reference fi le .......................................................................... (none)

Page 439: AnyMail/400 Mail Server Framework Developer Guide January 1995

/XRL/13

Imbed Trace

Page 0 4449SUPage 0 4449VARSPage 0 4449REFPage 0 4449FMPage i 4449EDNOPage ii 4449ABSTPage xiv 4449SPECPage xiv 4449TMKSPage xv 4449PREFPage xxi 4449ACKSPage xxii 4449TROPage 2 4449CAPPage 17 4449CFGPage 28 4449OPRPage 43 4449MSGPage 50 4449MSGHPage 53 4449MSGOPage 56 4449MSGEPage 58 4449MSGRPage 62 4449MSGAPage 64 4449MSGGPage 67 4449MSGYPage 69 4449MSGTPage 71 4449MSGPPage 74 4449MSGXPage 76 4449MSGSPage 79 4449EPTPage 118 4449EPTOPage 122 4449EPTXPage 132 4449APIPage 136 4449CAPIPage 145 4449LSTMPage 146 4449LSTAPage 147 4449LSTDPage 152 4449LSTPPage 153 4449LSTBPage 154 4449LSTSPage 159 4449LSTRPage 160 4449LSTCPage 162 4449MCRMPage 163 4449MCRCPage 167 4449MRTMPage 168 4449MRTCPage 171 4449MCLMPage 172 4449MCLCPage 177 4449MOTMPage 179 4449MOTRPage 181 4449MOTDPage 184 4449MOTCPage 187 4449MOTQPage 191 4449MEPMPage 192 4449MEPVPage 194 4449MEPTPage 196 4449MSCEPage 198 4449APPPage 203 4449SECPage 207 4449DBGPage 213 4449DBGJPage 227 4449GETPage 243 4449FSO1Page 275 4449DIRPage 281 4449DIR1Page 282 4449DIR2Page 283 4449DIR3Page 290 4449DIR4Page 290 4449SWIPage 293 4449SAMPage 295 4449SAM1Page 296 4449SAM2Page 297 4449SAM3Page 308 4449SAM4Page 320 4449SAM5Page 322 4449SAM6Page 331 4449SAM7Page 335 4449SAM8Page 351 4449SAM9Page 355 4449QZMFPage 374 4449QSRVPage 381 4449GLOSPage 398 4449EVALPage 398 RCFADDRPage 398 ITSCADDR FILE

Page 440: AnyMail/400 Mail Server Framework Developer Guide January 1995

/XRL/14

Page 399 RCFADDRPage 399 ITSCADDR FILE