Code:
- h NoMain
- h BndDir('RCHEVA1POC' :'QC2LE')
- h Option(*SrcStmt :*NoDebugIO)
- //--------------------------------------------------------------------------------------------
- // Program . . : UT1010R Author . . : Rick Chevalier
- // Date . . . . : 8/06/2009
- // Project . . :
- // Purpose . . : E-mail interface program
- //--------------------------------------------------------------------------------------------
- // Modifications:
- //
- // Project Date Developer Description
- //--------------------------------------------------------------------------------------------
- // xxxxxxxxx xx/xx/xxxx xxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
- //--------------------------------------------------------------------------------------------
- //
- //--------------------------------------------------------------------------------------------
- // File definitions
- //--------------------------------------------------------------------------------------------
- fSNDEMADR if e k Disk UsrOpn
- // Senders name and e-mail address
-
- fRCPEMADR if e k Disk UsrOpn
- // Recipients name and e-mail address
-
- fEMAILMSG if e k Disk UsrOpn
- // Pre-defined e-mail messages
-
- fRCPTYPES it f 142 Disk
- // Recipient types used as pre-runtime array
-
- //--------------------------------------------------------------------------------------------
- // External procedure prototypes
- //--------------------------------------------------------------------------------------------
-
- // Definitions for call to QtmmSendMail
- /copy qcpysrc,sendmail_h
-
- // Definitions for IFS procedures
- /copy qcpysrc,ifsio_h
-
- // C function to create a temporary file
- d CreateTempFile pr * ExtProc('_C_IFS_tmpnam')
- d string 39a Options(*Omit)
-
- //--------------------------------------------------------------------------------------------
- // Internal procedure prototypes
- //--------------------------------------------------------------------------------------------
-
- // Prototypes for exported procedures
- /include qcpysrc,ut1010cpy
-
- // Send CL e-mail message
- d SendCLMail pr
- d ErrorCode 7a
- d SenderAddrKey 32a
- d Subject 128a Varying
- d MessageType 7a
- d RecipType 7a
- d RecipKey 32a
- d RecipList 7277a
- d MessageKey 32a Varying
- d MailMessage 32000a Varying
- d Attachments 1a
- d AttachList 6402a
-
- // Write e-mail header to temp file
- d WriteMailHeader...
- d pr 5i 0
- d SenderKey 32a Const
- d RecipientsKey 32a Const Options(*Omit)
- d RecipientsList...
- d LikeDS(AdHocRecipients_t)
- d Options(*Omit)
- d Subject 128a Varying Const
-
- // Write e-mail body to temp file
- d WriteMailbody...
- d pr
- d Message 32000a Varying Const
-
- // Add any attachments to the MIME file
- d AddAttachments pr
- d Attachments LikeDS(AttachmentList_t)
-
- // Write e-mail close to temp file
- d WriteMailClose...
- d pr
-
- // Build list of recipients using the recipients file
- d AddPreDefinedRecipients...
- d pr 5i 0
- d HdrRecipients 8192a Varying
- d RecipientsKey Like(RcpLstKey) Const
-
- // Build list of recipients passed in as parameter
- d AddAdHocRecipients...
- d pr
- d HdrRecipients 8192a Varying
- d AdHocRecipients...
- d LikeDS(AdHocRecipients_t)
-
- // Report any errors
- d ReportError pr
-
- // Generate todays date in SMTP required format
- d MailDate pr 31A
-
- // Initialization routine to perform any necessary setup
- d UT1010R_Constructor...
- d pr
-
- // Shutdown routine to perform any necessary closing processing
- d UT1010R_Destructor...
- d pr
-
- //--------------------------------------------------------------------------------------------
- // Global variables
- //--------------------------------------------------------------------------------------------
-
- // MIME message boundary. Must be unique within the message.
- d Boundary c '--=_iSeries_MIME_Boundary'
-
- // List of recipients for API call
- d RecipientList ds LikeDS(ADDTO0100) Dim(25) Inz
-
- // Temporary file used to contain the mime message being sent.
- // This file is used as input by the QtmmSendMail API.
- d TempFile s 50a varying
- d TempFileDesc s 10i 0
-
- // Cross reference array of recipient types
- d RecipientTypes s 3a Dim(3) PerRcd(1)
- d FromFile(RCPTYPES)
- d APIType s 1s 0 Dim(3) Alt(RecipientTypes)
-
- // Determine if constructor has been run or not
- d ConstructorNotRun...
- d s n Inz(*On)
-
- // Miscellaneous definitions
- d CRLF c x'0d25'
-
- //--------------------------------------------------------------------------------------------
- // Send Ad-hoc mail message
- //--------------------------------------------------------------------------------------------
- p SendAdHocMail b Export
- d SendAdHocMail pi
- d ErrorCode 7a
- d SenderAddrKey 32a
- d Recipientskey 32a Options(*Omit)
- d RecipientsList...
- d LikeDS(AdHocRecipients_t)
- d Options(*Omit)
- d Subject 128a Varying
- d MailMessage 32000a Varying
- d AttachmentList...
- d LikeDS(AttachmentList_t)
-
- // API error parameter
- d NullError ds
- d BytesProv 10I 0 inz(0)
- d BytesAvail 10I 0 inz(0)
-
- // Miscellaneous definitions
- d Index s 5i 0
- d NbrAddresses s 5i 0
-
- /Free
-
- // Open files and perform any necessary setup
- If ConstructorNotRun;
- UT1010R_Constructor();
- EndIf;
-
- // create a temporary file in the IFS. This is the e-mail message.
- // mark that file as ccsid 819 (ISO 8859-1 ASCII)
- // and ask IBM i to translate EBCDIC -> ASCII
- TempFile = %str(CreateTempFile(*omit));
- unlink(TempFile);
-
- TempFileDesc = open( TempFile
- : O_CREAT+O_EXCL+O_WRONLY+O_CCSID
- +O_TEXTDATA+O_TEXT_CREAT
- : M_RDWR
- : 819
- : 0 );
-
- // Error opening the temporary file
- if (TempFileDesc = -1);
- ReportError();
- endif;
-
- // Place mail header into message temp file
- NbrAddresses = WriteMailHeader(SenderAddrKey :RecipientsKey
- :RecipientsList :Subject);
-
- // Place message body into message temp file
- WriteMailBody(MailMessage);
-
- // If there are attachments add them to the mail file
- If AttachmentList.NumberOfAttachments > 0;
- AddAttachments(AttachmentList);
- EndIf;
-
- // End the message and close the file
- WriteMailClose();
- CallP Close(TempFileDesc);
-
- // Send the message
- QtmmSendMail( TempFile
- : %Len(TempFile)
- : SenderAddr
- : %len(SenderAddr)
- : RecipientList
- : NbrAddresses
- : NullError );
-
- /End-Free
-
- p SendAdHocMail e
-
- //--------------------------------------------------------------------------------------------
- // Send pre-defined mail message
- //--------------------------------------------------------------------------------------------
- p SendPreDefinedMail...
- p b Export
- d SendPreDefinedMail...
- d pi
- d ErrorCode 7a
- d SenderAddrKey 32a
- d Recipientskey 32a Options(*Omit)
- d RecipientsList...
- d LikeDS(AdHocRecipients_t)
- d Options(*Omit)
- d Subject 128a Varying
- d MessageKey 32a Varying
- d AttachmentList...
- d LikeDS(AttachmentList_t)
-
- // API error parameter
- d NullError ds
- d BytesProv 10I 0 inz(0)
- d BytesAvail 10I 0 inz(0)
-
- // Miscellaneous definitions
- d Index s 5i 0
- d NbrAddresses s 5i 0
- d EmailTextError s 4000a Varying
- d Inz('Message text not found for')
-
- /Free
-
- // Open files and perform any necessary setup
- If ConstructorNotRun;
- UT1010R_Constructor();
- EndIf;
-
- // create a temporary file in the IFS. This is the e-mail message.
- // mark that file as ccsid 819 (ISO 8859-1 ASCII)
- // and ask IBM i to translate EBCDIC -> ASCII
- TempFile = %str(CreateTempFile(*omit));
- unlink(TempFile);
-
- TempFileDesc = open( TempFile
- : O_CREAT+O_EXCL+O_WRONLY+O_CCSID
- +O_TEXTDATA+O_TEXT_CREAT
- : M_RDWR
- : 819
- : 0 );
-
- // Error opening the temporary file
- if (TempFileDesc = -1);
- ReportError();
- endif;
-
- // Place mail header into message temp file
- NbrAddresses = WriteMailHeader(SenderAddrKey :RecipientsKey
- :RecipientsList :Subject);
-
- // Place message body into message temp file
- MessageID = MessageKey;
- Chain(E) MessageID EMAILMSG;
-
- If Not %Error and %Found(EMAILMSG);
- WriteMailBody(EmailText);
- Else;
- EmailText = EmailTextError + ' ' + MessageKey;
- WriteMailBody(EmailText);
- EndIf;
-
- // If there are attachments add them to the mail file
- If AttachmentList.NumberOfAttachments > 0;
- AddAttachments(AttachmentList);
- EndIf;
-
- // End the message and close the file
- WriteMailClose();
- CallP Close(TempFileDesc);
-
- // Send the message
- QtmmSendMail( TempFile
- : %Len(TempFile)
- : SenderAddr
- : %len(SenderAddr)
- : RecipientList
- : NbrAddresses
- : NullError );
-
- /End-Free
-
- p SendPreDefinedMail...
- p e
-
- //--------------------------------------------------------------------------------------------
- // Send CL e-mail message
- //--------------------------------------------------------------------------------------------
- p SendCLMail b Export
- d SendCLMail pi
- d ErrorCode 7a
- d SenderAddrKey 32a
- d Subject 128a Varying
- d MessageType 7a
- d RecipType 7a
- d RecipKey 32a
- d pRecipList 7277a
- d MessageKey 32a Varying
- d MailMessage 32000a Varying
- d Attachments 1a
- d AttachList 6402a
-
- // Fields for calls to mail procedures
- d RecipientsList...
- d ds LikeDS(AdHocRecipients_t) Inz
- d AttachmentList...
- d ds LikeDS(AttachmentList_t) Inz
-
- // Convert 5i character field to numeric
- d Cnv5iToNbr ds
- d Char5i 2a
- d Nbr5i 5i 0 Overlay(Cnv5iToNbr :1)
-
- // Parameter list recipient
- d ParmListRecip ds Based(ParmListRecip@) Qualified
- d Name 32a
- d Address 256a
- d Type 3a
-
- d ParmListRecipLen...
- d s 5i 0 Inz(%Size(ParmListRecip))
-
- // Parameter list attachment
- d ParmListAttach ds LikeDS(AttachmentDetails_t)
- d Based(ParmListAttach@)
-
- d ParmListAttachLen...
- d s 5i 0 Inz(%Size(ParmListAttach))
-
- // Miscellaneous definitions
- d Index s 5i 0
- d Start s 5i 0 Inz(1)
- d RecipLen s 5i 0
-
- /Free
-
- // Populate list of ad-hoc recipients
- If RecipType = 'ADHOC';
-
- // Populate number of recipients and position to first one
- Char5i = %SubSt(pRecipList :1 :2);
- RecipientsList.NumberOfRecipients = Nbr5i;
- ParmListRecip@ = %Addr(pRecipList) +
- ((RecipientsList.NumberOfRecipients * 2) + 4);
-
- // Move each recipient to procedure parameter field
- For Index = 1 to RecipientsList.NumberOfRecipients;
- RecipientsList.Recipient(Index).Name =
- %TrimR(ParmListRecip.Name);
- RecipientsList.Recipient(Index).Address =
- %TrimR(ParmListRecip.Address);
- RecipientsList.Recipient(Index).Type =
- %TrimR(ParmListRecip.Type);
- ParmListRecip@ += ParmListRecipLen + 2;
- EndFor;
-
- EndIf;
-
- // Populate list of attachments
- If Attachments = 'Y';
-
- // Get number of attachments
- Char5i = %SubSt(AttachList :1 :2);
- AttachmentList.NumberOfAttachments = Nbr5i;
-
- // Format attachments for the e-mail procedures
- ParmListAttach@ = %Addr(AttachList) +
- ((AttachmentList.NumberOfAttachments * 2) + 4);
-
- // Move each recipient to procedure parameter field
- For Index = 1 to AttachmentList.NumberOfAttachments;
- AttachmentList.Attachment(Index).Name =
- ParmListAttach.Name;
- AttachmentList.Attachment(Index).Path =
- ParmListAttach.Path;
- ParmListAttach@ += ParmListAttachLen + 2;
- EndFor;
-
- EndIf;
-
- // Determine which procedure to call
- Select;
-
- When MessageType = 'ADHOC' and RecipType = 'ADHOC';
- SendAdHocMail(ErrorCode :SenderAddrKey :*OMIT :RecipientsList
- :Subject :MailMessage :AttachmentList);
-
- When MessageType = 'ADHOC' and RecipType = 'DEFINED';
- SendAdHocMail(ErrorCode :SenderAddrKey :RecipKey :*OMIT
- :Subject :MailMessage :AttachmentList);
-
- When MessageType = 'DEFINED' and RecipType = 'ADHOC';
- SendPreDefinedMail(ErrorCode :SenderAddrKey :*OMIT :RecipientsList
- :Subject :MessageKey :AttachmentList);
-
- When MessageType = 'DEFINED' and RecipType = 'DEFINED';
- SendPreDefinedMail(ErrorCode :SenderAddrKey :RecipKey :*OMIT
- :Subject :MessageKey :AttachmentList);
- EndSl;
-
- /End-Free
-
- p SendCLMail e
-
- //--------------------------------------------------------------------------------------------
- // Write e-mail header to temp file
- //--------------------------------------------------------------------------------------------
- p WriteMailHeader...
- p b
- d WriteMailHeader...
- d pi 5i 0
- d SenderKey 32a Const
- d RecipientsKey 32a Const Options(*Omit)
- d RecipientsList...
- d LikeDS(AdHocRecipients_t)
- d Options(*Omit)
- d Subject 128a Varying Const
-
- // Header string
- d Header s 32767a Varying
-
- // Recipient string
- d HdrRecipients s 8192a Varying
-
- // Miscellaneous definitions
- d NbrRecipients s 5i 0
-
- // Key value for default sender address
- d DefaultSender s 32a Inz('DEFAULT')
-
- // Constants to change field case
- d Upper c 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
- d Lower c 'abcdefghijklmnopqrstuvwxyz'
- /Free
-
- // Get sender name and e-mail address
- Chain SenderKey SNDEMADR;
-
- If Not %Found(SNDEMADR);
- Chain DefaultSender SNDEMADR;
- EndIf;
-
- // Build list of recipients
- If %Addr(RecipientsKey) <> *NULL;
- NbrRecipients = AddPreDefinedRecipients(HdrRecipients :RecipientsKey);
- ElseIf %Addr(RecipientsList) <> *NULL;
- AddAdHocRecipients(HdrRecipients :RecipientsList);
- NbrRecipients = RecipientsList.NumberOfRecipients;
- EndIf;
-
- // Build header string
- Header =
- 'From: ' + SenderName + ' <' + %XLate(Upper :Lower :SenderAddr)
- + '>' + CRLF
- + HdrRecipients + CRLF
- + 'Date: ' + MailDate() + CRLF
- + 'Subject: ' + Subject + CRLF
- + 'MIME-Version: 1.0' + CRLF
- + 'Content-Type: multipart/mixed;'
- + ' boundary="' + Boundary + '"' + CRLF
- + CRLF
- + 'Your mail reader doesn''t support MIME!' + CRLF
- + CRLF;
-
- // Write e-mail header to temporary file
- CallP Write(TempFileDesc: %addr(Header)+2: %len(Header));
-
- Return NbrRecipients;
-
- /End-Free
-
- p WriteMailHeader...
- p e
-
- //--------------------------------------------------------------------------------------------
- // Write e-mail body to temp file
- //--------------------------------------------------------------------------------------------
- p WriteMailBody...
- p b
- d WriteMailbody...
- d pi
- d Message 32000a Varying Const
-
- d Body s 32767a Varying
-
- /Free
-
- // Build body boundary
- Body = '--' + Boundary + CRLF
- +'Content-type: text/plain' + CRLF
- + CRLF;
-
- // Write body boundary to temporary file
- CallP Write(TempFileDesc: %Addr(Body)+2: %Len(Body));
-
- // Write message body to temporary file
- Body = Message + CRLF;
- CallP Write(TempFileDesc: %Addr(Body)+2: %Len(Body));
-
- /End-Free
-
- p WriteMailBody...
- p e
-
- //--------------------------------------------------------------------------------------------
- // Add any attachments to the MIME file
- //--------------------------------------------------------------------------------------------
- p AddAttachments b
- d AddAttachments pi
- d Attachments LikeDS(AttachmentList_t)
-
- // Miscellaneous variables
- d Body s 32767a Varying
- d Index s 5i 0
- d MaxAttachments s 5i 0 Inz(25)
- d MimeType s 64a Varying
-
- // Variables to control attachment file
- d AttachmentDesc s 10i 0
- d AttachmentData s 54a
- d DataLength s 10i 0
-
- // Endoded data variables
- d EncodedData s 74a
- d EncodedLength s 10i 0
-
- //Include base64 functions
- /copy qcpysrc,apr_b64_h
-
- /Free
-
- If Attachments.NumberOfAttachments > MaxAttachments;
- Attachments.NumberOfAttachments = MaxAttachments;
- EndIf;
-
- For Index = 1 to Attachments.NumberOfAttachments;
-
- // Insert the headers for the attachment file
- mimeType = 'document/pdf';
-
- Body =
- '--' + boundary + CRLF
- +'Content-Type: ' + mimeType + '; '
- + 'name="' + Attachments.Attachment(Index).Name + '"' + CRLF
- +'Content-Transfer-Encoding: base64' + CRLF
- +'Content-Disposition: attachment; '
- + 'filename="' + Attachments.Attachment(Index).Name + '"' + CRLF
- + CRLF;
-
- CallP Write(TempFileDesc: %Addr(Body)+2: %len(Body));
-
- // Read the attachment file, and base64
- // encode it. Write the results to the
- // e-mail message.
- AttachmentDesc = open( Attachments.Attachment(Index).Path: O_RDONLY );
-
- If (AttachmentDesc = -1);
- ReportError();
- EndIf;
-
- // Read through input file
- DataLength = read(AttachmentDesc: %Addr(AttachmentData)
- :%Size(AttachmentData));
-
- DoW DataLength > 0;
-
- // Encode data from the read
- EncodedLength = apr_base64_encode_binary( EncodedData
- : AttachmentData
- : DataLength ) - 1;
- %SubSt(EncodedData :EncodedLength + 1) = CRLF;
-
- // Add to e-mail message file
- CallP write(TempFileDesc: %Addr(EncodedData): EncodedLength + 2);
-
- // Get next segment of attachment
- DataLength = read(AttachmentDesc: %Addr(AttachmentData)
- :%Size(AttachmentData));
- EndDo;
-
- CallP close(AttachmentDesc);
-
- EndFor;
-
- /End-Free
-
- p AddAttachments e
-
- //--------------------------------------------------------------------------------------------
- // Write e-mail close to temp file
- //--------------------------------------------------------------------------------------------
- p WriteMailClose...
- p b
- d WriteMailClose...
- d pi
-
- d CloseText s 128a Varying
-
- /Free
-
- // Build close value
- CloseText = CRLF + '--' + boundary + '--' + CRLF;
-
- // Write message close to temporary file
- CallP Write(TempFileDesc: %Addr(CloseText)+2: %Len(CloseText));
-
- /End-Free
-
- p WriteMailClose...
- p e
-
- //--------------------------------------------------------------------------------------------
- // Build list of recipients using the recipients file
- //--------------------------------------------------------------------------------------------
- p AddPreDefinedRecipients...
- p b
- d AddPreDefinedRecipients...
- d pi 5i 0
- d HdrRecipients 8192a Varying
- d RecipientsKey Like(RcpLstKey) Const
-
- // Miscellaneous variables
- d Index s 5i 0
- d Index2 s 3i 0
-
- // Recipient status
- d ACTIVE c 'A'
-
- // Constants to change field case
- d Upper c 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
- d Lower c 'abcdefghijklmnopqrstuvwxyz'
-
- // Parts of the header recipients
- d TORecipients s 8195a Varying
- d CCRecipients s 8195a Varying
- d BCCRecipients s 8195a Varying
- d TOCount s 5i 0 Inz(0)
- d CCCount s 5i 0 Inz(0)
- d BCCCount s 5i 0 Inz(0)
-
- /Free
-
- // Build list of recipients
- Index = 0;
- SetLL RecipientsKey RCPEMADR;
- Read RCPEMADR;
-
- // DoW Not %EOF and RecipientsKey = RcpLstKey and Status = ACTIVE;
- DoW Not %EOF and RecipientsKey = RcpLstKey;
-
- // Group recipients by type
- Select;
-
- When %XLate(Lower :Upper :RcpType) = 'TO';
- TOCount += 1;
-
- // First time through add keyword
- If TOCount = 1;
- CCRecipients = CRLF + 'Cc: ';
-
- // For all except the first add separator
- Else;
- TORecipients += ', ';
- EndIf;
-
- TORecipients += RcpName + ' <' + %XLate(Upper :Lower :RcpAddr) +
- '>';
-
- When %XLate(Lower :Upper :RcpType) = 'CC';
- CCCount += 1;
-
- // First time through add keyword
- If CCCount = 1;
- TORecipients = 'To: ';
-
- // For all except the first add separator
- Else;
- CCRecipients += ', ';
- EndIf;
-
- CCRecipients += RcpName + ' <' + %XLate(Upper :Lower :RcpAddr) +
- '>';
-
- When %XLate(Lower :Upper :RcpType) = 'BCC';
- BCCCount += 1;
-
- // First time through add keyword
- If BCCCount = 1;
- BCCRecipients = CRLF + 'Bcc: ';
-
- // For all except the first add separator
- Else;
- BCCRecipients += ', ';
- EndIf;
-
- BCCRecipients += RcpName + ' <' + %XLate(Upper :Lower :RcpAddr) +
- '>';
- EndSl;
-
- // Build list of recipients for API call. RecipientList is a global DS.
- Index += 1;
- RecipientList(Index).NextOffset = %Size(ADDTO0100);
- RecipientList(Index).AddrLen = %Len(RcpAddr);
- RecipientList(Index).AddrFormat = 'ADDR0100';
- Index2 = %Lookup(RcpType :RecipientTypes);
-
- If Index2 > 0;
- RecipientList(Index).DistType = APIType(Index2);
- Else;
- RecipientList(Index).DistType = ADDR_NORMAL;
- EndIf;
-
- RecipientList(Index).Reserved = 0;
- RecipientList(Index).SmtpAddr = RcpAddr;
-
- Read RCPEMADR;
- EndDo;
-
- // Create MIME recipient text
- HdrRecipients = TORecipients + CCRecipients + BCCRecipients;
-
- // Return number of recipients
- Return Index;
-
- /End-Free
-
- p AddPreDefinedRecipients...
- p e
-
- //--------------------------------------------------------------------------------------------
- // Build list of recipients passed in as parameter
- //--------------------------------------------------------------------------------------------
- p AddAdHocRecipients...
- p b
- d AddAdHocRecipients...
- d pi
- d HdrRecipients 8192a Varying
- d AdHocRecipients...
- d LikeDS(AdHocRecipients_t)
-
- // Miscellaneous variables
- d Index s 5i 0
- d Index2 s 3i 0
-
- // Recipient status
- d ACTIVE c 'A'
-
- // Constants to change field case
- d Upper c 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
- d Lower c 'abcdefghijklmnopqrstuvwxyz'
-
- // Parts of the header recipients
- d TORecipients s 8195a Varying
- d CCRecipients s 8195a Varying
- d BCCRecipients s 8195a Varying
- d TOCount s 5i 0 Inz(0)
- d CCCount s 5i 0 Inz(0)
- d BCCCount s 5i 0 Inz(0)
-
- /Free
-
- // Walk through list of recipients
- For Index = 1 to AdHocRecipients.NumberOfRecipients;
-
- // Group recipients by type
- Select;
-
- When %XLate(Lower :Upper :AdHocRecipients.Recipient(Index).Type) =
- 'TO';
- TOCount += 1;
-
- // First time through add keyword
- If TOCount = 1;
- TORecipients = 'To: ';
-
- // For all except the first add separator
- Else;
- TORecipients += ', ';
- EndIf;
-
- TORecipients += AdHocRecipients.Recipient(Index).Name + ' <' +
- %XLate(Upper :Lower :AdHocRecipients.Recipient(Index).Address) +
- '>';
-
- When %XLate(Lower :Upper :AdHocRecipients.Recipient(Index).Type) =
- 'CC';
- CCCount += 1;
-
- // For all except the first add separator
- If CCCount = 1;
- CCRecipients = CRLF + 'Cc: ';
-
- // For all except the first add separator
- Else;
- CCRecipients += ', ';
- EndIf;
-
- CCRecipients += AdHocRecipients.Recipient(Index).Name + ' <' +
- %XLate(Upper :Lower :AdHocRecipients.Recipient(Index).Address) +
- '>';
-
- When %XLate(Lower :Upper :AdHocRecipients.Recipient(Index).Type) =
- 'BCC';
- BCCCount += 1;
-
- // First time through add keyword
- If BCCCount = 1;
- BCCRecipients = CRLF + 'Bcc: ';
-
- // For all except the first add separator
- Else;
- BCCRecipients += ', ';
- EndIf;
-
- BCCRecipients += AdHocRecipients.Recipient(Index).Name + ' <' +
- %XLate(Upper :Lower :AdHocRecipients.Recipient(Index).Address) +
- '>';
- EndSl;
-
- // Build list of recipients for API call. RecipientList is a global DS.
- RecipientList(Index).NextOffset = %Size(ADDTO0100);
- RecipientList(Index).AddrLen =
- %Len(AdHocRecipients.Recipient(Index).Address);
- RecipientList(Index).AddrFormat = 'ADDR0100';
- Index2 =
- %Lookup(AdHocRecipients.Recipient(Index).Type :RecipientTypes);
-
- If Index2 > 0;
- RecipientList(Index).DistType = APIType(Index2);
- Else;
- RecipientList(Index).DistType = ADDR_NORMAL;
- EndIf;
-
- RecipientList(Index).Reserved = 0;
- RecipientList(Index).SmtpAddr =
- AdHocRecipients.Recipient(Index).Address;
- EndFor;
-
- // Create MIME recipient text
- HdrRecipients = TORecipients + CCRecipients + BCCRecipients;
-
- /End-Free
-
- p AddAdHocRecipients...
- p e
-
- //--------------------------------------------------------------------------------------------
- // maildate(): Get current date/time in format required for SMTP
- //
- // For example: 'Mon, 15 Aug 2006 14:30:06 -0500'
- //--------------------------------------------------------------------------------------------
- p MailDate B
- d MailDate PI 31A
-
- d CEEUTCO PR opdesc
- d Hours 10I 0
- d Minutes 10I 0
- d Seconds 8F
- d fc 12A options(*omit)
-
- d SUNDAY C d'1899-12-31'
-
- d junk1 s 8F
- d hours s 10I 0
- d mins s 10I 0
- d tz_hours s 2P 0
- d tz_mins s 2P 0
- d tz s 5A varying
-
- d CurTS s Z
- d CurTime s 8a varying
- d CurDay s 2p 0
- d CurYear s 4p 0
- d CurMM s 2p 0
- d CurMonth s 3a varying
- d TempDOW s 10i 0
- d CurDOW s 3a varying
-
- d DateString s 31a
-
- /free
-
- //
- // Calculate the Timezone in format '+0000', for example
- // CST should show up as '-0600'
- //
-
- CEEUTCO(hours: mins: junk1: *omit);
- tz_hours = %abs(hours);
- tz_mins = mins;
-
- if (hours < 0);
- tz = '-';
- else;
- tz = '+';
- endif;
-
- tz += %editc(tz_hours:'X') + %editc(tz_mins:'X');
-
- //
- // Get the current time and convert it to the format
- // specified for e-mail in RFC 2822
- //
-
- CurTS = %timestamp();
-
- CurTime = %char(%time(CurTS): *HMS:);
-
- CurDay = %subdt(CurTS: *DAYS);
- CurYear = %subdt(CurTS: *YEARS);
- CurMM = %subdt(CurTS: *MONTHS);
-
- select;
- when CurMM = 1;
- CurMonth = 'Jan';
- when CurMM = 2;
- CurMonth = 'Feb';
- when CurMM = 3;
- CurMonth = 'Mar';
- when CurMM = 4;
- CurMonth = 'Apr';
- when CurMM = 5;
- CurMonth = 'May';
- when CurMM = 6;
- CurMonth = 'Jun';
- when CurMM = 7;
- CurMonth = 'Jul';
- when CurMM = 8;
- CurMonth = 'Aug';
- when CurMM = 9;
- CurMonth = 'Sep';
- when CurMM = 10;
- CurMonth = 'Oct';
- when CurMM = 11;
- CurMonth = 'Nov';
- when CurMM = 12;
- CurMonth = 'Dec';
- endsl;
-
- TempDOW = %diff( %date(CurTS) : SUNDAY : *DAYS );
- TempDOW = %rem( TempDOW : 7 );
-
- Select;
- when TempDOW = 0;
- CurDOW = 'Sun';
- when TempDOW = 1;
- CurDOW = 'Mon';
- when TempDOW = 2;
- CurDOW = 'Tue';
- when TempDOW = 3;
- CurDOW = 'Wed';
- when TempDOW = 4;
- CurDOW = 'Thu';
- when TempDOW = 5;
- CurDOW = 'Fri';
- when TempDOW = 6;
- CurDOW = 'Sat';
- endsl;
-
- DateString = CurDOW + ', '
- + %editc( CurDay: 'X' ) + ' '
- + CurMonth + ' '
- + %editc( CurYear: 'X' ) + ' '
- + CurTime + ' '
- + tz;
-
- return DateString;
-
- /end-free
-
- p MailDate e
-
- *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- * ReportError(): Send an escape message explaining any errors
- * that occurred.
- *
- * This function requires binding directory QC2LE in order
- * to access the __errno() function.
- *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- P ReportError B
- D ReportError PI
-
- D get_errno PR * ExtProc('__errno')
- D ptrToErrno s *
- D errno s 10I 0 based(ptrToErrno)
-
- D QMHSNDPM PR ExtPgm('QMHSNDPM')
- D MessageID 7A Const
- D QualMsgF 20A Const
- D MsgData 1A Const
- D MsgDtaLen 10I 0 Const
- D MsgType 10A Const
- D CallStkEnt 10A Const
- D CallStkCnt 10I 0 Const
- D MessageKey 4A
- D ErrorCode 8192A options(*varsize)
-
- D ErrorCode DS qualified
- D BytesProv 1 4I 0 inz(0)
- D BytesAvail 5 8I 0 inz(0)
-
- D MsgKey S 4A
- D MsgID s 7A
-
- /free
-
- ptrToErrno = get_errno();
- MsgID = 'CPE' + %char(errno);
-
- QMHSNDPM( MsgID
- : 'QCPFMSG *LIBL'
- : ' '
- : 0
- : '*ESCAPE'
- : '*PGMBDY'
- : 1
- : MsgKey
- : ErrorCode );
-
- /end-free
-
- P ReportError E
-
- //--------------------------------------------------------------------------------------------
- // Initialization routine to perform any necessary setup
- //--------------------------------------------------------------------------------------------
- p UT1010R_Constructor...
- p b
- d UT1010R_Constructor...
- d pi
-
- /Free
-
- If Not %Open(SNDEMADR);
- Open SNDEMADR;
- EndIf;
-
- If Not %Open(RCPEMADR);
- Open RCPEMADR;
- EndIf;
-
- If Not %Open(EMAILMSG);
- Open EMAILMSG;
- EndIf;
-
- ConstructorNotRun = *Off;
-
- /End-Free
-
- p UT1010R_Constructor...
- p e
-
- //--------------------------------------------------------------------------------------------
- // Shutdown routine to perform any necessary closing processing
- //--------------------------------------------------------------------------------------------
- p UT1010R_Destructor...
- p b Export
- d UT1010R_Destructor...
- d pi
-
- /Free
-
- If %Open(SNDEMADR);
- Close SNDEMADR;
- EndIf;
-
- If %Open(RCPEMADR);
- Close RCPEMADR;
- EndIf;
-
- If %Open(EMAILMSG);
- Close EMAILMSG;
- EndIf;
-
- If %Open(RCPTYPES);
- Close RCPTYPES;
- EndIf;
-
- /End-Free
-
- p UT1010R_Destructor...
- p e
-
- SMTP copybook
- /if defined(SENDMAIL_H)
- /eof
- /endif
- /define SENDMAIL_H
-
- D QtmmSendMail PR ExtProc('QtmmSendMail')
- D FileName 255A const options(*varsize)
- D FileNameLen 10I 0 const
- D MsgFrom 256A const options(*varsize)
- D MsgFromLen 10I 0 const
- D RecipBuf likeds(ADDTO0100)
- D dim(32767)
- D options(*varsize)
- D NumRecips 10I 0 const
- D ErrorCode 8000A options(*varsize)
-
- D ADDTO0100 ds qualified
- D based(Template)
- D NextOffset 10I 0
- D AddrLen 10I 0
- D AddrFormat 8A
- D DistType 10I 0
- D Reserved 10I 0
- D SmtpAddr 256A
-
- D ADDR_NORMAL C CONST(0)
- D ADDR_CC C CONST(1)
- D ADDR_BCC C CONST(2)
-
- IFS I/O copybook from Scott Klement
- /*- +
- * Copyright (c) 2002-2006 Scott C. Klement +
- * All rights reserved. +
- * +
- * Redistribution and use in source and binary forms, with or without +
- * modification, are permitted provided that the following conditions +
- * are met: +
- * 1. Redistributions of source code must retain the above copyright +
- * notice, this list of conditions and the following disclaimer. +
- * 2. Redistributions in binary form must reproduce the above copyright +
- * notice, this list of conditions and the following disclaimer in the +
- * documentation and/or other materials provided with the distribution. +
- * +
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +
- * SUCH DAMAGE. +
- * +
- */ +
- D/if defined(IFSIO_H)
- D/eof
- D/endif
-
- D/define IFSIO_H
-
- **********************************************************************
- * Some CCSID definitions that I've found useful
- **********************************************************************
- D CP_MSDOS C 437
- D CP_ISO8859_1 C 819
- D CP_WINDOWS C 1252
- D CP_UTF8 C 1208
- D CP_UCS2 C 1200
- D CP_CURJOB C 0
-
- **********************************************************************
- * Flags for use in open()
- *
- * More than one can be used -- add them together.
- **********************************************************************
- * 00000000000000000000000000000001 Reading Only
- D O_RDONLY C 1
- * 00000000000000000000000000000010 Writing Only
- D O_WRONLY C 2
- * 00000000000000000000000000000100 Reading & Writing
- D O_RDWR C 4
- * 00000000000000000000000000001000 Create File if needed
- D O_CREAT C 8
- * 00000000000000000000000000010000 Exclusively create --
- * open will fail if it
- * already exists.
- D O_EXCL C 16
- * 00000000000000000000000000100000 Assign a CCSID to new
- * file.
- D O_CCSID C 32
- * 00000000000000000000000001000000 Truncate file to 0 bytes
- D O_TRUNC C 64
- * 00000000000000000000000100000000 Append to file
- * (write data at end only)
- D O_APPEND C 256
- * 00000000000000000000010000000000 Synchronous write
- D O_SYNC C 1024
- * 00000000000000000000100000000000 Sync write, data only
- D O_DSYNC C 2048
- * 00000000000000000001000000000000 Sync read
- D O_RSYNC C 4096
- * 00000000000000001000000000000000 No controlling terminal
- D O_NOCTTY C 32768
- * 00000000000000010000000000000000 Share with readers only
- D O_SHARE_RDONLY C 65536
- * 00000000000000100000000000000000 Share with writers only
- D O_SHARE_WRONLY C 131072
- * 00000000000001000000000000000000 Share with read & write
- D O_SHARE_RDWR C 262144
- * 00000000000010000000000000000000 Share with nobody.
- D O_SHARE_NONE C 524288
- * 00000000100000000000000000000000 Assign a code page
- D O_CODEPAGE C 8388608
- * 00000001000000000000000000000000 Open in text-mode
- D O_TEXTDATA C 16777216
- /if defined(*V5R2M0)
- * 00000010000000000000000000000000 Allow text translation
- * on newly created file.
- * Note: O_TEXT_CREAT requires all of the following flags to work:
- * O_CREAT+O_TEXTDATA+(O_CODEPAGE or O_CCSID)
- D O_TEXT_CREAT C 33554432
- /endif
- * 00001000000000000000000000000000 Inherit mode from dir
- D O_INHERITMODE C 134217728
- * 00100000000000000000000000000000 Large file access
- * (for >2GB files)
- D O_LARGEFILE C 536870912
-
- **********************************************************************
- * Access mode flags for access() and accessx()
- *
- * F_OK = File Exists
- * R_OK = Read Access
- * W_OK = Write Access
- * X_OK = Execute or Search
- **********************************************************************
- D F_OK C 0
- D R_OK C 4
- D W_OK C 2
- D X_OK C 1
-
- **********************************************************************
- * class of users flags for accessx()
- *
- * ACC_SELF = Check access based on effective uid/gid
- * ACC_INVOKER = Check access based on real uid/gid
- * ( this is equvalent to calling access() )
- * ACC_OTHERS = Check access of someone not the owner
- * ACC_ALL = Check access of all users
- **********************************************************************
- D ACC_SELF C 0
- D ACC_INVOKER C 1
- D ACC_OTHERS C 8
- D ACC_ALL C 32
-
- **********************************************************************
- * Mode Flags.
- * basically, the mode parm of open(), creat(), chmod(),etc
- * uses 9 least significant bits to determine the
- * file's mode. (peoples access rights to the file)
- *
- * user: owner group other
- * access: R W X R W X R W X
- * bit: 8 7 6 5 4 3 2 1 0
- *
- * (This is accomplished by adding the flags below to get the mode)
- **********************************************************************
- * owner authority
- D S_IRUSR C 256
- D S_IWUSR C 128
- D S_IXUSR C 64
- D S_IRWXU C 448
- * group authority
- D S_IRGRP C 32
- D S_IWGRP C 16
- D S_IXGRP C 8
- D S_IRWXG C 56
- * other people
- D S_IROTH C 4
- D S_IWOTH C 2
- D S_IXOTH C 1
- D S_IRWXO C 7
- * special modes:
- * restrict rename/unlink
- D S_ISVTX C 512
- * Set effective GID
- D S_ISGID C 1024
- * Set effective UID
- D S_ISUID C 2048
-
- **********************************************************************
- * My own special MODE shortcuts for open() (instead of those above)
- **********************************************************************
- D M_RDONLY C const(292)
- D M_RDWR C const(438)
- D M_RWX C const(511)
-
- **********************************************************************
- * "whence" constants for use with seek(), lseek() and others
- **********************************************************************
- /if not defined(SEEK_WHENCE_VALUES)
- D SEEK_SET C CONST(0)
- D SEEK_CUR C CONST(1)
- D SEEK_END C CONST(2)
- /define SEEK_WHENCE_VALUES
- /endif
-
- **********************************************************************
- * flags specified in the f_flags element of the ds_statvfs
- * data structure used by the statvfs() API
- **********************************************************************
- D ST_RDONLY...
- D C CONST(1)
- D ST_NOSUID...
- D C CONST(2)
- D ST_CASE_SENSITITIVE...
- D C CONST(4)
- D ST_CHOWN_RESTRICTED...
- D C CONST(8)
- D ST_THREAD_SAFE...
- D C CONST(16)
- D ST_DYNAMIC_MOUNT...
- D C CONST(32)
- D ST_NO_MOUNT_OVER...
- D C CONST(64)
- D ST_NO_EXPORTS...
- D C CONST(128)
- D ST_SYNCHRONOUS...
- D C CONST(256)
-
- **********************************************************************
- * Constants used by pathconf() API
- **********************************************************************
- D PC_CHOWN_RESTRICTED...
- D C 0
- D PC_LINK_MAX...
- D C 1
- D PC_MAX_CANON...
- D C 2
- D PC_MAX_INPUT...
- D C 3
- D PC_NAME_MAX...
- D C 4
- D PC_NO_TRUNC...
- D C 5
- D PC_PATH_MAX...
- D C 6
- D PC_PIPE_BUF...
- D C 7
- D PC_VDISABLE...
- D C 8
- D PC_THREAD_SAFE...
- D C 9
-
- **********************************************************************
- * Constants used by sysconf() API
- **********************************************************************
- D SC_CLK_TCK...
- D C 2
- D SC_NGROUPS_MAX...
- D C 3
- D SC_OPEN_MAX...
- D C 4
- D SC_STREAM_MAX...
- D C 5
- D SC_CCSID...
- D C 10
- D SC_PAGE_SIZE...
- D C 11
- D SC_PAGESIZE...
- D C 12
-
- **********************************************************************
- * File Information Structure (stat)
- * struct stat {
- * mode_t st_mode; /* File mode */
- * ino_t st_ino; /* File serial number */
- * nlink_t st_nlink; /* Number of links */
- * unsigned short st_reserved2; /* Reserved @B4A*/
- * uid_t st_uid; /* User ID of the owner of file */
- * gid_t st_gid; /* Group ID of the group of file */
- * off_t st_size; /* For regular files, the file
- * size in bytes */
- * time_t st_atime; /* Time of last access */
- * time_t st_mtime; /* Time of last data modification */
- * time_t st_ctime; /* Time of last file status change */
- * dev_t st_dev; /* ID of device containing file */
- * size_t st_blksize; /* Size of a block of the file */
- * unsigned long st_allocsize; /* Allocation size of the file */
- * qp0l_objtype_t st_objtype; /* AS/400 object type */
- * char st_reserved3; /* Reserved @B4A*/
- * unsigned short st_codepage; /* Object data codepage */
- * unsigned short st_ccsid; /* Object data ccsid @AAA*/
- * dev_t st_rdev; /* Device ID (if character special */
- * /* or block special file) @B4A*/
- * nlink32_t st_nlink32; /* Number of links-32 bit @B5C*/
- * dev64_t st_rdev64; /* Device ID - 64 bit form @B4A*/
- * dev64_t st_dev64; /* ID of device containing file - */
- * /* 64 bit form. @B4A*/
- * char st_reserved1[36]; /* Reserved @B4A*/
- * unsigned int st_ino_gen_id; /* File serial number generation id
- * };
- * @A2A*/
- **********************************************************************
- D statds DS qualified
- D BASED(Template)
- D st_mode 10U 0
- D st_ino 10U 0
- D st_nlink 5U 0
- D st_reserved2 5U 0
- D st_uid 10U 0
- D st_gid 10U 0
- D st_size 10I 0
- D st_atime 10I 0
- D st_mtime 10I 0
- D st_ctime 10I 0
- D st_dev 10U 0
- D st_blksize 10U 0
- D st_allocsize 10U 0
- D st_objtype 11A
- D st_reserved3 1A
- D st_codepage 5U 0
- D st_ccsid 5U 0
- D st_rdev 10U 0
- D st_nlink32 10U 0
- D st_rdev64 20U 0
- D st_dev64 20U 0
- D st_reserved1 36A
- D st_ino_gen_id 10U 0
-
-
- **********************************************************************
- * File Information Structure, Large File Enabled (stat64)
- * struct stat64 { */
- * mode_t st_mode; /* File mode */
- * ino_t st_ino; /* File serial number */
- * uid_t st_uid; /* User ID of the owner of file */
- * gid_t st_gid; /* Group ID of the group of fileA2A*/
- * off64_t st_size; /* For regular files, the file */
- * size in bytes */
- * time_t st_atime; /* Time of last access */
- * time_t st_mtime; /* Time of last data modification2A*/
- * time_t st_ctime; /* Time of last file status changeA*/
- * dev_t st_dev; /* ID of device containing file */
- * size_t st_blksize; /* Size of a block of the file */
- * nlink_t st_nlink; /* Number of links */
- * unsigned short st_codepage; /* Object data codepage */
- * unsigned long long st_allocsize; /* Allocation size of the file2A*/
- * unsigned int st_ino_gen_id; /* File serial number generationAid*/
- * */
- * qp0l_objtype_t st_objtype; /* AS/400 object type */
- * char st_reserved2[5]; /* Reserved @B4A*/
- * dev_t st_rdev; /* Device ID (if character specialA*/
- * /* or block special file) @B4A*/
- * dev64_t st_rdev64; /* Device ID - 64 bit form @B4A*/
- * dev64_t st_dev64; /* ID of device containing file@-2A*/
- * /* 64 bit form. @B4A*/
- * nlink32_t st_nlink32; /* Number of links-32 bit @B5A*/
- * char st_reserved1[26]; /* Reserved @B4A @B5C*/
- * unsigned short st_ccsid; /* Object data ccsid @AAA*/
- * }; */
- *
- **********************************************************************
- D statds64 DS qualified
- D BASED(Template)
- D st_mode 10U 0
- D st_ino 10U 0
- D st_uid 10U 0
- D st_gid 10U 0
- D st_size 20I 0
- D st_atime 10I 0
- D st_mtime 10I 0
- D st_ctime 10I 0
- D st_dev 10U 0
- D st_blksize 10U 0
- D st_nlink 5U 0
- D st_codepage 5U 0
- D st_allocsize 20U 0
- D st_ino_gen_id 10U 0
- D st_objtype 11A
- D st_reserved2 5A
- D st_rdev 10U 0
- D st_rdev64 20U 0
- D st_dev64 20U 0
- D st_nlink32 10U 0
- D st_reserved1 26A
- D st_ccsid 5U 0
-
- **********************************************************************
- * ds_statvfs - data structure to receive file system info
- *
- * f_bsize = file system block size (in bytes)
- * f_frsize = fundamental block size in bytes.
- * if this is zero, f_blocks, f_bfree and f_bavail
- * are undefined.
- * f_blocks = total number of blocks (in f_frsize)
- * f_bfree = total free blocks in filesystem (in f_frsize)
- * f_bavail = total blocks available to users (in f_frsize)
- * f_files = total number of file serial numbers
- * f_ffree = total number of unused file serial numbers
- * f_favail = number of available file serial numbers to users
- * f_fsid = filesystem ID. This will be 4294967295 if it's
- * too large for a 10U 0 field. (see f_fsid64)
- * f_flag = file system flags (see below)
- * f_namemax = max filename length. May be 4294967295 to
- * indicate that there is no maximum.
- * f_pathmax = max pathname legnth. May be 4294967295 to
- * indicate that there is no maximum.
- * f_objlinkmax = maximum number of hard-links for objects
- * other than directories
- * f_dirlinkmax = maximum number of hard-links for directories
- * f_fsid64 = filesystem id (in a 64-bit integer)
- * f_basetype = null-terminated string containing the file
- * system type name. For example, this might
- * be "root" or "Network File System (NFS)"
- *
- * Since f_basetype is null-terminated, you should read it
- * in ILE RPG with:
- * myString = %str(%addr(ds_statvfs.f_basetype))
- **********************************************************************
- D ds_statvfs DS qualified
- D BASED(Template)
- D f_bsize 10U 0
- D f_frsize 10U 0
- D f_blocks 20U 0
- D f_bfree 20U 0
- D f_bavail 20U 0
- D f_files 10U 0
- D f_ffree 10U 0
- D f_favail 10U 0
- D f_fsid 10U 0
- D f_flag 10U 0
- D f_namemax 10U 0
- D f_pathmax 10U 0
- D f_objlinkmax 10I 0
- D f_dirlinkmax 10I 0
- D f_reserved1 4A
- D f_fsid64 20U 0
- D f_basetype 80A
-
-
- **********************************************************************
- * Group Information Structure (group)
- *
- * struct group {
- * char *gr_name; /* Group name. */
- * gid_t gr_gid; /* Group id. */
- * char **gr_mem; /* A null-terminated list of pointers
- * to the individual member names. */
- * };
- *
- **********************************************************************
- D group DS qualified
- D BASED(Template)
- D gr_name *
- D gr_gid 10U 0
- D gr_mem * DIM(256)
-
-
- **********************************************************************
- * User Information Structure (passwd)
- *
- * (Don't let the name fool you, this structure does not contain
- * any password information. Its named after the UNIX file that
- * contains all of the user info. That file is "passwd")
- *
- * struct passwd {
- * char *pw_name; /* User name. */
- * uid_t pw_uid; /* User ID number. */
- * gid_t pw_gid; /* Group ID number. */
- * char *pw_dir; /* Initial working directory. */
- * char *pw_shell; /* Initial user program. */
- * };
- *
- **********************************************************************
- D passwd DS qualified
- D BASED(Template)
- D pw_name *
- D pw_uid 10U 0
- D pw_gid 10U 0
- D pw_dir *
- D pw_shell *
-
-
- **********************************************************************
- * File Time Structure (utimbuf)
- *
- * struct utimbuf {
- * time_t actime; /* access time */
- * time_t modtime; /* modification time */
- * };
- *
- **********************************************************************
- D utimbuf DS qualified
- D
|
|