Get SMTP Name Programmatically

Article ID: 52432

Q: I'd like to write a program that e-mails reports to users on my system. I've discovered how to e-mail a report, but I can't figure out how to get the user's e-mail address. I can view it on the screen with the Work with Names for SMTP (WRKNAMSMTP) command, but how do I get the same information in a CL program?

A: Unfortunately, IBM didn't make it easy. You need to use the Search System Directory (QOKSCHD) API to get the e-mail address. In this article, I demonstrate how to do that from a CL program.

If you've used the WRKNAMSMTP command, you know that SMTP e-mail addresses are stored by a user ID and address field. For example, on my system, the WRKNAMSMTP screen looks like this:

                            Work with Names for SMTP                            
                                                             System:   S10XXXBA 
 Alias table type . . . . . . . . :   System                                    
 Type options, press Enter.                                                     
   1=Add   2=Change   4=Remove   5=Display   6=Print                            
 Opt     User ID      Address      SMTP Name                                    
         KLEMSCOT     S10XXXBA     klemscot@EXAMPLE.COM                         
                                                                         Bottom 
 F3=Exit   F5=Refresh   F12=Cancel   F15=Print list   F17=Position to

To use the QOKSCHD API to get this information, you have to construct a request data structure in SREQ0100 format that tells the API to search the directory by the user ID and address fields. While you're doing that, you have to tell the API that the type of information that you want back is SMTP information, which you do by specifying *SMTP in an SREQ0103 field.

The response is a list of variable-length entries, each one corresponding to one of the SMTP fields. There is an SMTP user field and an SMTP domain field. After you retrieve them, you can concatenate them with an at symbol (i.e., @) in between to get the e-mail address.

Because this is a relatively complicated process, I've done the dirty work for you. I've written a program called GETSMTP, and you can install it on your system. It accepts two input parameters containing the user ID and address, and one output parameter containing the SMTP e-mail address.

Here's the source code for my GETSMTP program:

PGM PARM(&USERID &USERADDR &SMTP)

   DCL VAR(&USERID)   TYPE(*CHAR) LEN(10)
   DCL VAR(&USERADDR) TYPE(*CHAR) LEN(10)
   DCL VAR(&SMTP)     TYPE(*CHAR) LEN(256)

   DCL VAR(&RCVVAR)   TYPE(*CHAR) LEN(1000)
   DCL VAR(&RCVLEN)   TYPE(*CHAR) LEN(4)
   DCL VAR(&REQUEST)  TYPE(*CHAR) LEN(186)
   DCL VAR(&REQLEN)   TYPE(*CHAR) LEN(4)
   DCL VAR(&ERRCOD)   TYPE(*CHAR) LEN(8)

   DCL VAR(&X)        TYPE(*DEC)  LEN(5 0)
   DCL VAR(&OFFSET)   TYPE(*DEC)  LEN(5 0)
   DCL VAR(&POS)      TYPE(*DEC)  LEN(5 0)
   DCL VAR(&NBRFLD)   TYPE(*DEC)  LEN(5 0)
   DCL VAR(&CCSID)    TYPE(*DEC)  LEN(5 0)
   DCL VAR(&CODPAG)   TYPE(*DEC)  LEN(5 0)
   DCL VAR(&FLDVAL)   TYPE(*CHAR) LEN(256)
   DCL VAR(&FLDLEN)   TYPE(*DEC)  LEN(5 0)
   DCL VAR(&SMTPUSER) TYPE(*CHAR) LEN(256)
   DCL VAR(&SMTPHOST) TYPE(*CHAR) LEN(256)

   MONMSG MSGID(CPF0000 MCH0000) EXEC(GOTO ERROR)

   /************************************************/
   /*         SET VARIABLE LENGTHS                 */
   /************************************************/

   CHGVAR VAR(%BIN(&REQLEN 1 4)) VALUE(186)  /* SIZE OF &REQUEST */
   CHGVAR VAR(%BIN(&RCVLEN 1 4)) VALUE(1000) /* SIZE OF &RCVVAR  */
   CHGVAR VAR(%BIN(&ERRCOD 1 4)) VALUE(0)    /* SIZE OF &ERRCOD  */

   /************************************************/
   /*         SEARCH FORMAT SREQ0100               */
   /************************************************/

   CHGVAR VAR(%BIN(&REQUEST   1 4 )) VALUE(0)    /* CCSID     */
   CHGVAR VAR(%BIN(&REQUEST   5 4 )) VALUE(0)    /* CHAR SET  */
   CHGVAR VAR(%BIN(&REQUEST   9 4 )) VALUE(0)    /* CODE PAGE */
   CHGVAR VAR(%SST(&REQUEST  13 4 )) VALUE(' ')  /* WILDCARD CHAR */
   CHGVAR VAR(%SST(&REQUEST  17 1 )) VALUE('0')  /* CONV RECV DTA */
   CHGVAR VAR(%SST(&REQUEST  18 1 )) VALUE('0')  /* SEARCH DATA   */
   CHGVAR VAR(%SST(&REQUEST  19 1 )) VALUE('1')  /* RUN VERIFY    */
   CHGVAR VAR(%SST(&REQUEST  20 1 )) VALUE('0')  /* CONT HANDLE   */
   CHGVAR VAR(%SST(&REQUEST  21 16)) VALUE(' ')  /* RESOURCE HNDL */

   /* SEARCH / REQUEST ARRAY INFO */
   CHGVAR VAR(%SST(&REQUEST  37 8 )) VALUE('SREQ0101') /* FORMAT */
   CHGVAR VAR(%BIN(&REQUEST  45 4 )) VALUE(100)        /* OFFSET */
   CHGVAR VAR(%BIN(&REQUEST  49 4 )) VALUE(2)          /* NUM ELEMS */

   /* FIELDS REQUESTED ARRAY */
   CHGVAR VAR(%SST(&REQUEST  53 8 )) VALUE('SREQ0103') /* FORMAT */
   CHGVAR VAR(%BIN(&REQUEST  61 4 )) VALUE(176)        /* OFFSET */
   CHGVAR VAR(%BIN(&REQUEST  65 4 )) VALUE(1)          /* NUM ELEMS */

   /* USERS REQUESTED ARRAY */
   CHGVAR VAR(%SST(&REQUEST  69 8 )) VALUE('SRCV0101') /* FORMAT */
   CHGVAR VAR(%BIN(&REQUEST  77 4 )) VALUE(1)          /* COUNT  */

   /* FIELDS FOR EACH USER */
   CHGVAR VAR(%SST(&REQUEST  81 8 )) VALUE('SRCV0112') /* FORMAT */

   /* ORDER OF FIELD NAMES */
   CHGVAR VAR(%SST(&REQUEST  89 8 )) VALUE('        ') /* FORMAT */
   CHGVAR VAR(%SST(&REQUEST  97 1 )) VALUE('0')        /* OPTION */

   /* SREQ101 DATA */
   /* ENTRY FOR USRID = &USERID */
   CHGVAR VAR(%BIN(&REQUEST 101 4 )) VALUE(38)       /* LEN */
   CHGVAR VAR(%SST(&REQUEST 105 1 )) VALUE('1')      /* COMP VALUE */
   CHGVAR VAR(%SST(&REQUEST 106 10)) VALUE('USRID')  /* FLD NAME */
   CHGVAR VAR(%SST(&REQUEST 116 7 )) VALUE('*IBM')   /* PROD ID  */
   CHGVAR VAR(%SST(&REQUEST 123 1 )) VALUE('0')      /* CASE     */
   CHGVAR VAR(%BIN(&REQUEST 125 4 )) VALUE(10)       /* VAL LEN  */
   CHGVAR VAR(%SST(&REQUEST 129 10)) VALUE(&USERID)  /* VALUE    */
   /* ENTRY FOR USRADDR = &USERADDR */
   CHGVAR VAR(%BIN(&REQUEST 139 4 )) VALUE(38)       /* LEN */
   CHGVAR VAR(%SST(&REQUEST 143 1 )) VALUE('1')      /* COMP VALUE */
   CHGVAR VAR(%SST(&REQUEST 144 10)) VALUE('USRADDR')/* FLD NAME */
   CHGVAR VAR(%SST(&REQUEST 154 7 )) VALUE('*IBM')   /* PROD ID  */
   CHGVAR VAR(%SST(&REQUEST 161 1 )) VALUE('0')      /* CASE     */
   CHGVAR VAR(%BIN(&REQUEST 163 4 )) VALUE(10)       /* VAL LEN  */
   CHGVAR VAR(%SST(&REQUEST 167 10)) VALUE(&USERADDR)/* VALUE    */

   /* SREQ103 DATA */
   CHGVAR VAR(%SST(&REQUEST 177 10)) VALUE('*SMTP')
   /************************************************/
   /*    SEARCH DIRECTORY (QOKSCHD) API            */
   /************************************************/

   CALL PGM(QOKSCHD) PARM(&RCVVAR    +
                          &RCVLEN    +
                          'SRCV0100' +
                          '*SEARCH'  +
                          '0'        +
                          &REQUEST   +
                          &REQLEN    +
                          'SREQ0100' +
                          &ERRCOD    )
   /************************************************/
   /*    PARSE OUT SMTP ADDRESS FROM RESPONSE      */
   /************************************************/

   CHGVAR VAR(&OFFSET)   VALUE(%BIN(&RCVVAR 9 4))

   CHGVAR VAR(&POS)    VALUE(&OFFSET + 5)
   CHGVAR VAR(&NBRFLD) VALUE(%BIN(&RCVVAR &POS 4))
   CHGVAR VAR(&POS)    VALUE(&POS + 4)
   CHGVAR VAR(&X)      VALUE(0)

LOOP:
   CHGVAR VAR(&X) VALUE(&X + 1)
   IF (&X *LE &NBRFLD) THEN(DO)
       /* FIELD CCSID */
       CHGVAR VAR(&CCSID)  VALUE(%BIN(&RCVVAR &POS 4))

       /* FIELD CODE PAGE */
       CHGVAR VAR(&POS)    VALUE(&POS + 4)
       CHGVAR VAR(&CODPAG) VALUE(%BIN(&RCVVAR &POS 4))

       /* FIELD LENGTH */
       CHGVAR VAR(&POS)    VALUE(&POS + 4)
       CHGVAR VAR(&FLDLEN) VALUE(%BIN(&RCVVAR &POS 4))
       IF (&FLDLEN *GT 256) THEN(+
          CHGVAR VAR(&FLDLEN) VALUE(256) +
       )

       /* FIELD VALUE */
       CHGVAR VAR(&POS)    VALUE(&POS + 4)
       IF (&FLDLEN *GT 0) THEN(DO)
          CHGVAR VAR(&FLDVAL) VALUE(%SST(&RCVVAR &POS &FLDLEN))
          CHGVAR VAR(&POS)    VALUE(&POS + &FLDLEN)
       ENDDO

       /* MAP FIELD VALUE TO VARIABLE */
       IF (&X *EQ 1) THEN(+
          CHGVAR VAR(&SMTPUSER) VALUE(&FLDVAL)+
       )
       ELSE IF (&X *EQ 2) THEN(+
          CHGVAR VAR(&SMTPHOST) VALUE(&FLDVAL)+
       )

       GOTO LOOP
   ENDDO

   /************************************************/
   /*   COMBINE USER & HOST TO MAKE TYPICAL        */
   /*   E-MAIL ADDRESS                             */
   /************************************************/

   CHGVAR VAR(&SMTP) VALUE(&SMTPUSER *TCAT '@' *CAT &SMTPHOST)
   RETURN

ERROR:
   /************************************************/
   /*    GENERIC ERROR HANDLER                     */
   /************************************************/
     CALL PGM(QMHMOVPM) PARM( '    '              +
                              '*DIAG'             +
                              x'00000001'         +
                              '*PGMBDY   '        +
                              x'00000001'         +
                              x'0000000800000000' )

     CALL PGM(QMHRSNEM) PARM( '    '              +
                              x'0000000800000000' )
ENDPGM

You can call this program from another one when you need to get the SMTP address. For example, the following program gets my e-mail address and prints it on the bottom of the screen:

PGM

    DCL VAR(&P1) TYPE(*CHAR) LEN(10) VALUE('KLEMSCOT')
    DCL VAR(&P2) TYPE(*CHAR) LEN(10) VALUE('S10XXXBA')
    DCL VAR(&SMTP) TYPE(*CHAR) LEN(256)

    CALL PGM(GETSMTP) PARM(&P1 &P2 &SMTP)

    SNDPGMMSG MSGID(CPF9897) MSGF(QCPFMSG) MSGTYPE(*COMP) +
              MSGDTA(&SMTP)

ENDPGM

The QOKSCHD API is documented in the Information Center at the following link:
http://publib.boulder.ibm.com/infocenter/iseries/v5r3/topic/apis/QOKSCHD.htm

ProVIP Sponsors

ProVIP Sponsors