×
INTELLIGENT WORK FORUMS
FOR COMPUTER PROFESSIONALS

Contact US

Log In

Come Join Us!

Are you a
Computer / IT professional?
Join Tek-Tips Forums!
  • Talk With Other Members
  • Be Notified Of Responses
    To Your Posts
  • Keyword Search
  • One-Click Access To Your
    Favorite Forums
  • Automated Signatures
    On Your Posts
  • Best Of All, It's Free!

*Tek-Tips's functionality depends on members receiving e-mail. By joining you are opting in to receive e-mail.

Posting Guidelines

Promoting, selling, recruiting, coursework and thesis posting is forbidden.

Students Click Here

Capturing JES2 Variables in Batch REXX

Capturing JES2 Variables in Batch REXX

Capturing JES2 Variables in Batch REXX

(OP)
Hi everyone ...

I know almost 0% about REXX, but am using an exec written about 16 years ago by a predecessor at my shop.  

The function of the exec is used in a batch job to send data in a file created by a previous step in the same job to an SMTP gateway on one of the MVS communication server running an SMTP gateway.

This exec has worked fine all these years, but our users have requested that we include a few variables with the passing of the data that I do not believe are system variables (e.g. mvsvar('symdef','jobname')).   The variables that are being requested are the JES2 job number and the job's condition code.

I was hoping that someone may have a suggestion on something relatively easy I could implement to grab the data from JES2 about the job that is creating this data using the existing exec I have.  Here is the exec we're using today.  

Thanks in advance for any suggestions!

CODE

/* THIS COMMENT IS REQUIRED TO DENOTE THAT THIS IS A REXX EXEC */

PARSE UPPER ARG RECIPDSN BODYDSN
RECIPDSN = STRIP(RECIPDSN)
BODYDSN = STRIP(BODYDSN)

CALL INIT

CALL GET_RECIPIENTS

CALL GET_BODY_OF_NOTE

CALL BUILD_HEADER

CALL BUILD_BODY

CALL BUILD_TRAILER

CALL DISPLAY_IT

CALL MAIL_IT

EXIT
/*--------------------------------------------------------------------*/

INIT:

SYSID   = mvsvar('sysname')
Sysplex = mvsvar('sysplex')
Jobname = mvsvar('symdef','jobname')
Userid  = userid()

Jobname = translate(Jobname,'________________________________',  ,
                            '~!@#$%¬&*()_+{}|:"<>?`-=¢¦\;'',./')

MAILTIME = Date('Normal') /* dd mon yyyy */ ,
           Time('Normal') /* hh:mm:ss 24 hour */

SMTPTASK = 'TCPSMTP'
SMTPSYSID = SYSID

Select
  When Sysplex = 'MVS1PLEX' Then SMTPSYSID =    'MVS1'
  When Sysplex = 'MVS3PLEX' Then SMTPSYSID = /* 'MVS3' */ 'MVS5'
  When Sysplex = 'MVS4PLEX' Then SMTPSYSID = /* 'MVS9' */ 'MVS5'
  When Sysplex = 'MVS5PLEX' Then SMTPSYSID =    'MVS5'
  When Sysplex = 'MVS7PLEX' Then SMTPSYSID = /* 'MVS7' */ 'MVS5'
  When Sysid   = 'MVS8'     Then SMTPSYSID = /* 'MVS8' */ 'MVS5'
  When Sysplex = 'Y2KPLEX'  Then SMTPSYSID = /* 'MT2K' */ 'MVS5'
  Otherwise
      SMTPSYSID = 'MVS5'
end; /* select */

RETURN
/*--------------------------------------------------------------------*/

GET_RECIPIENTS:

/* Read the recipient file into array "RECIP." */
ADDRESS TSO "ALLOCATE DD(RECIPDD) DATASET('"RECIPDSN"') SHR"
"EXECIO * DISKR RECIPDD (STEM RECIP. FINIS)"
ADDRESS TSO "FREE DD(RECIPDD)"
SAY RECIP.0 'RECIPIENTS READ'

/* Clean up recipients ID's */
DO I = 1 TO RECIP.0
   RECIP.I = STRIP(RECIP.I)

   PARSE UPPER VAR RECIP.I NODE.I '.' NAME.I

   If index(RECIP.I,'RSCS1.') Then Do
      RECIP.I = Substr(RECIP.I,7,80)
   End

   If index(RECIP.I,'OCWVM.') Then Do
      RECIP.I = Substr(RECIP.I,7,80)
   End

   If index(RECIP.I,'OCBVM.') Then Do
      RECIP.I = Substr(RECIP.I,7,80)
   End

   If index(RECIP.I,'N14.') Then Do
      RECIP.I = Substr(RECIP.I,5,80)
   End

   If index(RECIP.I,'N15.') Then Do
      RECIP.I = Substr(RECIP.I,5,80)
   End

   If index(RECIP.I,'VM4.') Then Do
      RECIP.I = Substr(RECIP.I,5,80)
   End

   If index(RECIP.I,'VM5.') Then Do
      RECIP.I = Substr(RECIP.I,5,80)
   End

   RECIP.I = strip(RECIP.I)

   /* If ID doesn't have an '@' then default recipients to DOMAIN.com */
   If index(RECIP.I,'@') = 0 Then Do
      RECIP.I = RECIP.I||'@DOMAIN.Com'
   End
END

RETURN
/*--------------------------------------------------------------------*/

GET_BODY_OF_NOTE:

ADDRESS TSO "ALLOCATE DD(BODYDD) DATASET('"BODYDSN"') SHR"
"EXECIO * DISKR BODYDD (STEM BODY. FINIS)"
ADDRESS TSO "FREE DD(BODYDD)"
SAY BODY.0 'LINES OF TEXT BODY READ'

If BODY.1 = 'BODY.1' Then BODY.1 = ' '

If BODY.2 = 'BODY.2' Then BODY.2 = ' '

RETURN
/*--------------------------------------------------------------------*/

BUILD_HEADER:

WORK.1 = 'HELO' SMTPSYSID||'.DOMAIN.COM'  /* no space */
WORKSUB = 2 /* subscript for work arry */

WORK.WORKSUB = 'MAIL FROM: <'||sysid||'.'||jobname||'@DOMAIN.com>'
WORKSUB = WORKSUB + 1

DO I = 1 TO RECIP.0
   WORK.WORKSUB = 'RCPT TO: <'||RECIP.I||'>'
   WORKSUB = WORKSUB + 1
END

WORK.WORKSUB = 'DATA'  /* end of SMTP commands */
WORKSUB = WORKSUB + 1

WORK.WORKSUB = 'Date:' MAILTIME 'GMT'
WORKSUB = WORKSUB + 1

WORK.WORKSUB = 'From:' sysid||'.'||jobname strip(BODY.1)
WORKSUB = WORKSUB + 1

DO I = 1 TO RECIP.0
   WORK.WORKSUB = 'TO:' RECIP.I
   WORKSUB = WORKSUB + 1
END

WORK.WORKSUB = 'SUBJECT:' strip(BODY.2)
WORKSUB = WORKSUB + 1

RETURN
/*--------------------------------------------------------------------*/

BUILD_BODY:


If index(BODY.3,':') > 0 then do
   WORK.WORKSUB = ' '
   WORKSUB = WORKSUB + 1
end

DO I = 3 TO BODY.0

   If BODY.I = '.' Then Do
      BODY.I = ' ' || BODY.I
   End
   WORK.WORKSUB = BODY.I
   WORKSUB = WORKSUB + 1
END

RETURN
/*--------------------------------------------------------------------*/

BUILD_TRAILER:

WORK.WORKSUB = '_____' /* '' caused note to terminate ' ' is ok */
WORKSUB = WORKSUB + 1

WORK.WORKSUB = '.'
/*  WORKSUB = WORKSUB + 1  not for last line */

RETURN
/*--------------------------------------------------------------------*/

DISPLAY_IT:

SAY('The following note is about to be sent:')
SAY('')
DO I = 1 TO WORKSUB
   SAY(WORK.I)
END
SAY('')

RETURN
/*--------------------------------------------------------------------*/

MAIL_IT:

SAY('About to mail to:' SMTPSYSID||'.'||SMTPTASK)
ADDRESS TSO "ALLOCATE DD(PROFSDD) SYSOUT(B) ,
             DEST("SMTPSYSID") WRITER("SMTPTASK")"
"EXECIO * DISKW PROFSDD (STEM WORK. FINIS"
ADDRESS TSO "FREE DD(PROFSDD)"

RETURN

RE: Capturing JES2 Variables in Batch REXX

There is a way to get jobname and jobnumber from a running job:

CODE

@ascb    = Right(c2x(Storage(224,4)),7) /* ASCBaddr is at X'224'     */
@cvt     = Right(c2x(Storage(10,4)),7) /* CVTaddr is at X'10'        */
sysname  = Storage(d2x(x2d(@cvt) + x2d('154')),8)
                             /* SYSNAME is X'154' bytes into the CVT */

@smca    = Right(c2x(Storage(d2x(x2d(@cvt) + x2d('c4')),4)),7)
                             /* SMCAaddr is X'C4' bytes into the CVT */
cpuid    = Storage(d2x(x2d(@smca) + x2d('10')),4)
                       /* DW92, e.g.; located 16 bytes into the SMCA */

@tcb     = Right(c2x(Storage(21c,4)),7)  /* TCBaddr is at X'21C'     */
@tct     = Right(c2x(Storage(d2x(x2d(@tcb) + x2d('a4')),4)),7)
                              /* TCTaddr is X'A4' bytes into the TCB */
@jscb    = Right(c2x(Storage(d2x(x2d(@tcb) + x2d('b4')),4)),7)
                             /* JSCBaddr is X'B4' bytes into the TCB */
@ssib    = Right(c2x(Storage(d2x(x2d(@jscb) + x2d('13c')),4)),7)
                           /* SSIBaddr is X'13C' bytes into the JSCB */
jobnum   = Storage(d2x(x2d(@ssib) + x2d('0c')),8)
                           /* JOBnumber is X'0C' bytes into the SSIB */

@tiot    = Right(c2x(Storage(d2x(x2d(@tcb) + x2d('c')),4)),7)
                                /* TIOTaddr is 12 bytes into the TCB */
jobname  = Storage(@tiot,8)
                         /* JOBname is the first 8 bytes of the TIOT */

text = "JN="jobname " J#="jobnum "  CPU="cpuid "  Sysn="sysname
This isn't my original work.   I got it from somebody else, probably Doug Nadel.

There is also a method (I've seen it) to get all the step-return codes from prior steps in the job, but I don't have a copy of that.  Keep looking.
 

Frank Clarke
--America's source for adverse opinions since 1943.

RE: Capturing JES2 Variables in Batch REXX

(OP)
Thanks Frank, I will try this out and see how it works!  

Do you have any suggestions on a good documentation/reference point for a total REXX newbie that I could add to my favorites that I could read up on other helpful things such as this?

Thanks again!

RE: Capturing JES2 Variables in Batch REXX


Well, you could look at my REXX site at http://home.roadrunner.com/~mvsrexx/REXX/ to see some examples of utility software.  Some of it is pretty elaborate so it might be over your head, but lots of people have told me they learned a great deal from the routines there.
 

Frank Clarke
--America's source for adverse opinions since 1943.

RE: Capturing JES2 Variables in Batch REXX

(OP)
Hi Frank ...

My job ended with a return code 0012 for the step that executed the exec.

Here is the update I made to my code:

CODE

INIT:                                                           
                                                                
SYSID   = mvsvar('sysname')                                     
Sysplex = mvsvar('sysplex')                                     
Jobname = mvsvar('symdef','jobname')                            
Jobnum  = Storage(d2x(x2d(@ssib) + x2d('0c')),8)
Userid  = userid()

Here is the error message I received:

CODE

READY                                                       
 %DRPROFSX PCX.CPSR.LIST.LOAD.TEST PCX.RPT.STA147A.OUT      
    87 +++  Jobnum  = Storage(d2x(x2d(@ssib) + x2d('0c')),8)
    62 +++ CALL INIT                                        
Error running DRPROFSX, line 87: Incorrect call to routine

Any suggestions?

Thank you again in advance ...

RE: Capturing JES2 Variables in Batch REXX


You need ALL of the code I gave you, not just one line.   

Frank Clarke
--America's source for adverse opinions since 1943.

RE: Capturing JES2 Variables in Batch REXX

(OP)
Thanks Frank, this worked perfectly and gave me exactly what I needed.  I spent a few hours yesterday reading through the REXX manuals on the IBM web site so this has been a good learning experience for me as well.

One final question, any suggestion on where I might be able to find the job's final condition code?

Thanks again!

 

RE: Capturing JES2 Variables in Batch REXX

Each step has a condition code.

I'm not aware of any "final condition code" for a job.

RE: Capturing JES2 Variables in Batch REXX

(OP)
Perhaps I should have worded that better ... the highest return code?

RE: Capturing JES2 Variables in Batch REXX


As I said: there is a REXX routine which pokes through various system control blocks to discover ALL of the step return codes.  I've been looking for it -- I know we use it in one of our applications -- but haven't been able to find it.  There might be a reference on mvshelp.net and I'll look there later.
 

Frank Clarke
--America's source for adverse opinions since 1943.

Red Flag This Post

Please let us know here why this post is inappropriate. Reasons such as off-topic, duplicates, flames, illegal, vulgar, or students posting their homework.

Red Flag Submitted

Thank you for helping keep Tek-Tips Forums free from inappropriate posts.
The Tek-Tips staff will check this out and take appropriate action.

Reply To This Thread

Posting in the Tek-Tips forums is a member-only feature.

Click Here to join Tek-Tips and talk with other members! Already a Member? Login


Close Box

Join Tek-Tips® Today!

Join your peers on the Internet's largest technical computer professional community.
It's easy to join and it's free.

Here's Why Members Love Tek-Tips Forums:

Register now while it's still free!

Already a member? Close this window and log in.

Join Us             Close