On Fri, 2 May 2008 16:37:19 -0700, Howard Rifkind <[EMAIL PROTECTED]> 
wrote:

>Brian, would you be good enough to share the code for the process you 

>mention below?

>>On Thu, 1 May 2008 15:20:04 -0500, Brian Nielsen 
<[EMAIL PROTECTED]> >wrote:
>>
>>I recently setup an automated process to FTP to z/OS data extracted fro
m
>>DISKACNT's ACCOUNT files every day.  No RSCS or human intervention
>>required.

Here is a sanitized version of the code and environment in which sanitize
d 
parts have been replaced with:  {comment about what should be here}
The environment is described first, followed by the code.

---------------
User directory for service machine:

   USER {userid} LBYONLY 16M 128M G
    INCLUDE IBMDFLT
    MACH ESA
    IPL CMS
    MDISK 191 3390 {start cyl} 001 {volid}  MR
    MDISK 192 3390 {start cyl} 020 {volid}  MR
    LINK DISKACNT 191 291 RR


Service machine requirements and notes:
  - all files below must reside on the {userid} 191 MDISK
  - the 192 disk will hold all files created by this process
  - 20 cyls for the 192 disk will hold about 20 months worth of data (for
 
this site, ymmv)


z/OS requirements:
  - TCP/IP connection with sending side
  - pre-allocated PDSE to receive FTP transfers (2 cyls holds about 150 

days worth of data for this site, ymmv)
  - userid for sending side to use for FTP, with authority to write into 

the PDSE


General Process requirements and notes:
  - VM accounting records are closed every day just before midnight (by a
 
scheduling service machine)
  - {userid} is XAUTOLOG'd just after midnight (by a scheduling service 

machine)
  - PDSE members DAYdd contain the accounting data from that day of the 

month
  - Alternate code in BILL-DAT EXEC can name PDSE members $Ammddyy instea
d 
of DAYdd
  - The PDSE is self-cleaning if members are named DAYdd, but not if name
d 
$Ammddyy
  - PDSE member TODAY contains yesterday's accounting data (to be 
processed today by a z/OS process at this site)
  - The z/OS process must erase the TODAY member when it is done with it
  - PDSE member $TODAY will only exist if the z/OS process didn't erase 

member TODAY
  - If PDSE member REQUESTS exists, it will be retrieved and later rename
d 
$Rmmddyy
  - The contents of the REQUESTS member is one or more lines of: mmddyy
  - The sending side will send accounting data from all dates listed in 

REQUESTS
  - Any ACCOUNT files on DISKACNT 191 but not on {userid} 192 are 
processed & sent to z/OS

  - An automated process for deleting old DISKACNT 191 files and {userid}
 
192 files needs to be implemented.
  - The EXPIRE EXEC will find files older than a threshold, but currently
 
does nothing else.


--------------
PROFILE EXEC:

/* */
'set pf1 filel * * '
'set pf3 q disk'
'set pf12 retrieve'
'set pf24 retrieve forward'
'access 291 z'                         /* DISKACNT 191 */
'CP LINK TCPMAINT 592 592 RR'          /* has FTP command */
'ACCESS 592 U'

/* If connected, prompt user for action */
connected=substr( diag(24, -1), 13, 1 ) <> 2
IF connected
THEN DO
        say 'Press ENTER to run normally, or any input to cancel.'
        pull response
        IF response<>'' THEN EXIT 1
     END

/* run the billing process */
'EXEC BILLING'

'CP LOGOFF'


------------------------
BILLING EXEC:

/* This exec ties together the execs that do the sub-functions.      */

'COPY FTP REQUESTS A = INPUT D (REP'   /* prep the ftp commands file */

'EXEC FTP-PRD1'                   /* get requests file from zOS */

'EXEC BILL-CHK'                   /* add unprocessed files to TODO LIST *
/

'EXEC BILL-DO'                    /* process TODO LIST file */

'EXEC FTP-PRD1'                   /* send data file to zOS  */


------------------------
FTP REQUESTS (this has been sanitized):

cd '{fully qualified name of z/OS PDSE}'
get requests todo.list.d (replace
quit


------------------------
FTP-PRD1 EXEC (this has been sanitized to remove an IP address):

/* This exec FTPs data to/from z/OS on PROD1.                        */
/* FTP commands are in an input file.                                */
/* FTP ouput will be saved to a file, then appended to a log.        */

fm='D'
 in_file='FTP INPUT' fm
out_file='FTP OUTPUT' fm

today=DATE('U',,,'')              /* get todays date as mmddyy  */
ftp_log ='FTP-LOG' today fm

'FILEDEF  INPUT DISK' in_file
'FILEDEF OUTPUT DISK' out_file

z_os_ip_addr='{IP address of z/OS system}'

'FTP' z_os_ip_addr

ftp_rc=rc
IF ftp_rc<>0
THEN say 'FTP rc='ftp_rc

'FILEDEF  INPUT CLEAR'
'FILEDEF OUTPUT CLEAR'

'PIPE (ENDCHAR ?)',          /* append the ftp output to the log file */
   '<' out_file,
   '| >>' ftp_log


----------------------
BILL-CHK EXEC:

/* This exec determines which VM accounting files have not been       */
/* processed yet.                                                     */

fm_new='Z'                        /* unprocessed files - DISKACNT 191 *
/
fm_old='D'                        /*   processed files */
todo_fid='TODO LIST' fm_old
yesterday_fid='YESTERDY LIST' fm_old

'PIPE (ENDCHAR ?)',               /* make RECFM of todo file be V instead
 
of F */
   'CMS COPY' todo_fid todo_fid '(oldd rep recfm V',
   '| HOLE'

'PIPE (ENDCHAR ?)',               /* erase old file if it exists */
   'CMS ERASE' yesterday_fid,
   '| HOLE'

base=DATE('B')
today    =DATE('U',base  ,'B','')     /* today's     date in mmddyy 
format  */
yesterday=DATE('U',base-1,'B','')     /* yesterday's date in mmddyy 
format  */

'PIPE (ENDCHAR ?)',
  'CMS LISTF ACCOUNT $A*' fm_new '(DATE NOH', /* list ACCOUNT files on 

DISKACNT 191 */
  '| NFIND DMS',                              /* discard CMS error 
msgs          */
  '| NLOCATE W2 \$A'today'\',                 /* discard today's 
accounting file */
  '| SPECS /STATE/ 1 W1-2 NW /'fm_old'/ NW',  /* build command to see if 

file is on processed disk */
  '| CMS',                                    /* issue 
command                   */
  '| SPECS W4 1',                             /* keep ft from NOT FOUND 

msg      */
  '| SPECS 3-* 1',                            /* strip $A from 
ft                */
  '| y: NLOCATE W1 \'yesterday'\',            /* find yesterday's 
accounting file */
  '| f: FANINANY',                            /* append to list of files 

to send */
  '| >>' todo_fid,                            /* append to list of files 

to send */
  '?',
  'y:',
  '| >' yesterday_fid,
  '| f:'                                      /* append to list of files 

to send */


---------------------------
BILL-DO EXEC:

/* This exec reads the TODO LIST file and for each entry calls the    */
/* BILL-DAT exec to process that dates data.                          */

fm_old='D'                        /*   processed files */
in_file='TODO LIST' fm_old
ftp_fid='FTP INPUT' fm_old        /* file to hold FTP commands   */
yesterday_fid='YESTERDY LIST' fm_old

today=DATE('U',,,'')              /* get todays date as mmddyy  */

'COPY FTP HEADER A' ftp_fid '(REP'          /* initialize FTP command fil
e 
*/

'STATE' in_file              /* verify that input file exists */
IF rc<>0 THEN EXIT rc

'PIPE (ENDCHAR ?)',
   '<' in_file,                                  /* read in the 
file                */
   '| NLOCATE W1 /'today'/',                     /* discard files with 

today's date */
   '| SPECS /EXEC BILL-DAT ACCOUNT $A/' 1 W1 N,  /* build call to BILL-DA
T 
EXEC     */
   '| CMS'                                       /* call BILL-DAT 
EXEC              */

'PIPE (ENDCHAR ?)',                         /* add to FTP command file */

   'LITERAL rename requests $r'today,
   '| >>' ftp_fid

'RENAME' in_file 'TODO' today fm_old      /* preserve TODO list */

'STATE' yesterday_fid        /* verify that input file exists */
IF rc<>0 THEN EXIT rc

'PIPE (ENDCHAR ?)',                         /* add to FTP command file */

   '<' yesterday_fid,                       /* read in the file        */

   '| SPECS /put billdata.$A/ 1 W1 N /.'fm_old '$TODAY/ N',
   '| APPEND LITERAL rename $TODAY TODAY',
   '| >>' ftp_fid


-----------------------------
FTP HEADER (this has been sanitized):

cd '{same fully qualified z/OS PDSE name as in FTP REQUESTS file}'


-----------------------------
NETRC DATA (this has been sanitized):

machine {same IP address as in FTP-PRD1 EXEC} login {z/OS userid for this
 
FTP process} password {password for same}


-----------------------------
BILL-DAT EXEC (this has been sanitized to remove reformatting of the 
accounting records):

/* This exec reads a file containing VM accounting records and        */
/* filters and transforms the data into the format required by the    */
/* billing system on z/OS.                                            */

arg fname ftype .
in_file=fname ftype

 in_fm='Z'                   /* unprocessed files - DISKACNT 191 */
out_fm='D'                   /*   processed files */

'PIPE (ENDCHAR ?)',          /* copy input file to processed disk */
   'CMS COPY' in_file in_fm '= =' out_fm '(OLDD REP',
   '| HOLE'

in_file=fname ftype out_fm   /* use the copied file */

'STATE' in_file              /* verify that input file exists */
IF rc<>0 THEN EXIT rc

out_file='BILLDATA' ftype out_fm

ftp_fid='FTP INPUT' out_fm
zos_name='DAY'substr(ftype,5,2)
/* zos_name='$A'delstr(ftype,1,2) */      /* use this for non-overwrite
 
mode */

'PIPE (ENDCHAR ?)',
   'LITERAL put billdata.'ftype'.'out_fm zos_name,
   '| >>' ftp_fid

{sanitized variables being initialized for use in pipe below}

'pipe (endchar ?)',
   'f:',                           /* reformatted records come here */
   'FANINANY',
   '| >' out_file,
   '?',
   '<' in_file,                         /* read input file    */

   {sanitized pipe stages which manipulate the accounting records}

   '| f:'

EXIT


---------------------------
EXPIRE EXEC:

/* This EXEC finds files older than a specified number of days.      */

arg fn ft fm threshold .

IF ^DATATYPE(threshold,'W')
THEN DO
        say '"'threshold'" is not a whole number.'
        EXIT 4
     END

base_date=DATE('B')                    /* today's date */
cutoff_date=base_date-threshold        /* date of old files */

'PIPE (ENDCHAR ?)',
   'CMS LISTF' fn ft fm '(DATE NOH',
   '| SPECS W1-3 1.21  PAD 0 W8 22.8 RIGHT',     /* fn ft fm 
mm/dd/yy            */
   '| DATECONV W4 REXXU REXXB',                  /* put date in base date
 
format */
   '| PICK W4 <<= /'cutoff_date'/',              /* keep only old 
files          */
   '| SPECS W1-3 1',                             /* fn ft 
fm                     */
   '| CONS'


---------------------------

Brian Nielsen

Reply via email to