IPLINFO
IPLINFO
IPLINFO
/* */
/* AUTHOR: Mark Zelden */
/* */
/* Trace ?r */
/* ============================================================ */
/* */
/* NOTE TO SELF: */
/* */
/* Don't forget to check / update the JES2 node offset table */
/* for each new OS release and the JES3 FMID table. */
/* */
/* ============================================================ */
/* */
/*********************************************************************/
/* */
/* D I S C L A I M E R */
/* ------------------- */
/* */
/* This program is FREEWARE. Use at your own risk. Neither Mark */
/* Zelden, nor other contributing organizations or individuals */
/* accept any liability of any kind howsoever arising out of the use */
/* of this program. You are free to use and modify this program as */
/* you desire, however, the author does ask that you leave his name */
/* in the source and give credit to him as the original programmer. */
/* */
/*********************************************************************/
/* IPLINFO: DISPLAY SYSTEM INFORMATION ON TERMINAL */
/*********************************************************************/
/* */
/* IPLINFO can be called as an interactive exec / ISPF edit macro */
/* or in batch to display various system information. The result */
/* will be displayed in an ISPF browse data set if ISPF is active. */
/* */
/* IPLINFO can also be called as a REXX function to return from 1 */
/* to 20 variables used in the exec at their final value. If more */
/* than one variable is requested the variables are returned with */
/* a blank or user defined delimiter between each variable so they */
/* may be parsed if desired. */
/* */
/* See below for the sytax of each method. */
/* */
/*********************************************************************/
/* */
/* EXECUTION SYNTAX: */
/* */
/* TSO %IPLINFO <option> */
/* */
/* VALID OPTIONS ARE 'ALL', 'IPL', 'VERsion', 'STOrage', 'CPU', */
/* 'IPA', 'SYMbols', 'VMAp', 'PAGe', 'SMF', 'SUB', */
/* 'ASId', 'LPA', 'LNKlst', 'APF' and 'SVC' */
/* */
/* ** 'ALL' is the default option */
/* ** Options may be abbreviated by using 3 or more characters */
/* */
/* ** A 2nd parameter option of 'NOBrowse' may also be specified to */
/* eliminate browsing the output even when ISPF is active. This */
/* will allow any IPLINFO output to be trapped and parsed from */
/* another exec or edit macro if desired. The 'NOBrowse' option */
/* can also be specified as the only option and it will produce */
/* all IPLINFO output without browsing it. */
/* */
/* ** A 2nd parameter option of 'EDIt' may also be specified to */
/* EDIT the output instead of browsing it. The 'EDIt' option */
/* can also be specified as the only option and it will produce */
/* all IPLINFO output without editing it. */
/* */
/* ** The following options are not documented above as standard */
/* options nor in the help panel: */
/* "ASVt" - an alias for the "ASId" option */
/* "ASM" - an alias for the "PAGE" option */
/* "SSI" - an alias for the "SUB" option */
/* "SSN" - an alias for the "SUB" option */
/* "STOre" - an alias for the "STORage" option */
/* "MEMory" - an alias for the "STORage" option */
/* "SUBsystems" - an alias for the "SUB" option */
/* "NOBrowse" - the NOBrowse option */
/* "EDIt" - the EDIt option */
/* */
/* Examples: */
/* TSO %IPLINFO (Display all information) */
/* TSO %IPLINFO VMAP (Display a Virtual Storage Map) */
/* TSO %IPLINFO SYM (Display Static System Symbols) */
/* TSO %IPLINFO SUB (Display Subsystem Information) */
/* TSO %IPLINFO APF (Display APF Library List) */
/* TSO %IPLINFO ALL NOB (Display all infomation, don't browse O/P) */
/* TSO %IPLINFO SUB NOB (Display subsys info, don't browse O/P) */
/* TSO %IPLINFO NOBROWSE (Display all infomation, don't browse O/P) */
/* TSO %IPLINFO ALL EDI (Display all infomation, edit O/P) */
/* TSO %IPLINFO SUB EDI (Display subsys info, edit O/P) */
/* TSO %IPLINFO EDIT (Display all infomation, edit O/P) */
/* */
/* Edit macro invocation: */
/* IPLINFO (Display all information) */
/* IPLINFO VMAP (Display a Virtual Storage Map) */
/* IPLINFO SYM (Display Static System Symbols) */
/* IPLINFO SUB (Display Subsystem Information) */
/* IPLINFO APF (Display APF Library List) */
/* IPLINFO ALL NOB (Display all infomation, don't browse O/P) */
/* IPLINFO SUB NOB (Display subsys info, don't browse O/P) */
/* IPLINFO NOBROWSE (Display all infomation, don't browse O/P) */
/* IPLINFO ALL EDIT (Display all infomation, edit O/P) */
/* IPLINFO SUB EDIT (Display subsys info, edit O/P) */
/* IPLINFO EDIT (Display all infomation, edit O/P) */
/* */
/* Sample Unix System Services WEB Server execution via links: */
/* <a href="/cgi-bin/iplinfo">MVS Information</a> */
/* <a href="/cgi-bin/iplinfo?vmap">Virtual Storage Map</a> */
/* <a href="/cgi-bin/iplinfo?symbols">Static System Symbols</a> */
/* <a href="/cgi-bin/iplinfo?sub">Subsystem Information</a> */
/* <a href="/cgi-bin/iplinfo?apf">APF Library List</a> */
/* */
/*********************************************************************/
/* */
/* FUNCTION SYNTAX: */
/* */
/* IPLINFO(VAR,var1_name) */
/* IPLINFO(VAR,var1_name,var2_name,var3_name, ... var20_name) */
/* */
/* Examples: */
/* sysname = IPLINFO(VAR,GRSNAME) */
/* pvtsize = IPLINFO(VAR,GDAPVTSZ) */
/* */
/* */
/* /* REXX one line IPL information using IPLINFO rexx function */ */
/* IPL_SUM = IPLINFO(VAR,ipldate,ipltime,iplvol,ipladdr,iplparm) */
/* Parse var IPL_SUM ipldate ipltime iplvol ipladdr iplparm */
/* Say 'Date:'ipldate ' Time:'ipltime ' Vol:'iplvol , */
/* ' Load addr:'ipladdr ' LOADPARM:'iplparm */
/* */
/* */
/* NOTE: The default delimeter between returned variables is a */
/* blank. However, this can be problematic when the returned */
/* value contains a blank or is null. You can optionally */
/* change the delimiter from a blank to one of your choice */
/* by using "VAR2" instead of "VAR" in the function call and */
/* specifying the delimiter character(s) as the next operand */
/* prior to the list of variables you want returned. */
/* */
/* */
/* FUNCTION SYNTAX - "VAR2" / USER DEFINED DELIMITER: */
/* */
/* IPLINFO(VAR2,'dlm',var1_name) */
/* IPLINFO(VAR2,'dlm',var1_name,var2_name,var3_name, ... var20_name) */
/* */
/* Example: */
/* /* REXX one line IPL information using IPLINFO rexx function */ */
/* IPL_SUM = IPLINFO(VAR2,'@@',ipldate,ipltime,iplvol, , */
/* ipladdr,iplparm) */
/* Parse var IPL_SUM ipldate '@@' ipltime '@@' iplvol '@@' , */
/* ipladdr '@@' iplparm */
/* Say 'Date:'ipldate ' Time:'ipltime ' Vol:'iplvol , */
/* ' Load addr:'ipladdr ' LOADPARM:'iplparm */
/* */
/*********************************************************************/
/* */
/* NOTE: The dynamic APF and dynamic LNKLST code in this exec */
/* use undocumented IBM control blocks and may break at */
/* any time! */
/* ... tested on MVS ESA V4.3 up through z/OS 2.1. */
/* */
/* NOTE: The LNKLST SET displayed is the LNKLST SET of the address */
/* space running this exec, not necessarily the most */
/* current one. For the current LNKLST SET either: */
/* 1) Run this exec in batch. */
/* 2) Log off and on TSO before executing this exec. */
/* 3) Issue SETPROG LNKLST,UPDATE,JOB=userid (B4 execution) */
/* */
/* NOTE: The APF flag in the LNKLST display is the status if the */
/* data set is accessed VIA LNKLST. Therefore, if IEASYSxx */
/* specifies LNKAUTH=LNKLST, all entires are marked as APF=Y. */
/* */
/*********************************************************************/
LASTUPD = '06/17/2019' /* date of last update */
/*********************************************************************/
/* */
/* B E G I N C U S T O M I Z A T I O N S E C T I O N */
/* */
/* You may changes the variables below to your preference. */
/* You may only choose the options that are commented out. */
/* */
/* DATEFMT - Controls date format: ISO ; USA ; EUR */
/* VMAP - Controls VMAP order: HIGHFIRST ; LOWFIRST */
/* */
/*********************************************************************/
DATEFMT = 'ISO' /* ISO 8601 format YYYY-MM-DD (new default) */
/* DATEFMT = 'USA' */ /* USA format MM/DD/YYYY (original format) */
/* DATEFMT = 'EUR' */ /* EUR format DD/MM/YYYY */
/*********************************************************************/
VMAP = 'HIGHFIRST' /* new default - show VMAP from top down */
/* VMAP = 'LOWFIRST' */ /* the old way - show from bottom up */
/* Please let me know if you "need" the old way (LOWFIRST) as I */
/* will probably remove the duplicate code in the future. */
/*********************************************************************/
/* */
/* E N D C U S T O M I Z A T I O N S E C T I O N */
/* */
/*********************************************************************/
Signal On Syntax name SIG_ALL /* trap syntax errors */
Signal On Novalue name SIG_ALL /* trap uninitialized variables */
Arg OPTION,VAR.1,VAR.2,VAR.3,VAR.4,VAR.5,VAR.6,VAR.7,VAR.8,VAR.9, ,
VAR.10,VAR.11,VAR.12,VAR.13,VAR.14,VAR.15,VAR.16,VAR.17,VAR.18, ,
VAR.19,VAR.20,VAR.21
Parse source . EXEC_TYPE . . . . . ENV . .
MML = Substr(LASTUPD,1,2) /* MM from MM/DD/YYYY */
DDL = Substr(LASTUPD,4,2) /* DD from MM/DD/YYYY */
YYYYL = Substr(LASTUPD,7,4) /* YYYY from MM/DD/YYYY */
If DATEFMT = 'USA' then , /* USA format date? */
LASTUPD = LASTUPD /* date as MM/DD/YYYY */
If DATEFMT = 'EUR' then , /* EUR format date? */
LASTUPD = DDL'/'MML'/'YYYYL /* date as DD/MM/YYYY */
If DATEFMT = 'ISO' then , /* ISO format date? */
LASTUPD = YYYYL'-'MML'-'DDL /* date as YYYY-MM-DD */
SYSISPF = 'NOT ACTIVE' /* set SYSISPF=NOT ACTIVE */
FUNCDLM = ' ' /* Delimiter default for function call */
If ENV <> 'OMVS' then /* are we under unix ? */
If Sysvar('SYSISPF')='ACTIVE' then do /* no, is ISPF active? */
If Pos('NOB',OPTION) = 0 then , /* NOBrowse not used? */
Address ISREDIT "MACRO (OPTION)" /* YES,allow use as macro */
OPTION = Translate(OPTION) /* ensure upper case for edit macro */
Address ISPEXEC "VGET ZENVIR" /* ispf version */
SYSISPF = 'ACTIVE' /* set SYSISPF = ACTIVE */
End
/*********************************************************************/
/* Process options */
/*********************************************************************/
BROWSEOP = 'YES' /* default is to browse OP under ISPF */
EDITOP = 'NO' /* output is not in edit mode */
/*********************************************************************/
If SYSISPF = 'NOT ACTIVE' & Pos('EDI',OPTION) <> 0 then /* EDIT is */
call INVALID_OPTION /* not valid if ISPF isn't active */
If OPTION = '' then OPTION = 'ALL' /* Default option. Change to IPL */
/* or something else - may want to change help panel if changed */
If Abbrev('NOBROWSE',OPTION,3) = 1 then , /* NOBROWSE only opt? */
OPTION = 'ALL NOBROWSE' /* yes, use all option */
If Abbrev('EDIT',OPTION,3) = 1 then , /* EDITonly opt? */
OPTION = 'ALL EDIT' /* yes, use all option */
If Abbrev('NOBROWSE',Word(OPTION,2),3) = 1 then do /* NOBROWSE USED? */
OPTION = Word(OPTION,1) /* separate out option */
BROWSEOP = 'NO' /* set BROWSEOP flag to NO */
End
If Abbrev('EDIT',Word(OPTION,2),3) = 1 then do /* EDIT USED? */
OPTION = Word(OPTION,1) /* separate out option */
EDITOP = 'YES' /* set EDITOP flag to YES */
End
/*********************************************************************/
If OPTION <> 'IPL' & , /* check for IPL option */
Abbrev('VERSION',OPTION,3) <> 1 & , /* check for VERsion option */
Abbrev('STORAGE',OPTION,3) <> 1 & , /* check for STOrage option */
Abbrev('STORE',OPTION,3) <> 1 & , /* check for STOre option */
Abbrev('MEMORY',OPTION,3) <> 1 & , /* check for MEMory option */
OPTION <> 'CPU' & , /* check for CPU option */
OPTION <> 'IPA' & , /* check for IPA option */
Abbrev('SYMBOLS',OPTION,3) <> 1 & , /* check for SYMbols option */
Abbrev('VMAP',OPTION,3) <> 1 & , /* check for VMAp option */
Abbrev('PAGE',OPTION,3) <> 1 & , /* check for PAGe option */
Abbrev('ASM',OPTION,3) <> 1 & , /* check for ASM option */
Abbrev('AUX',OPTION,3) <> 1 & , /* check for ASM option */
OPTION <> 'SMF' & , /* check for SMF option */
OPTION <> 'SSI' & , /* check for SSI option */
OPTION <> 'SSN' & , /* check for SSN option */
OPTION <> 'SUB' & , /* check for SUB option */
Abbrev('SUBSYSTEMS',OPTION,3) <> 1 & , /* check for SUB option */
Abbrev('ASID',OPTION,3) <> 1 & , /* check for ASId option */
Abbrev('ASVT',OPTION,3) <> 1 & , /* check for ASVt option */
OPTION <> 'LPA' & , /* check for LPA option */
Abbrev('LNKLST',OPTION,3) <> 1 & , /* check for LNKlst option */
Abbrev('LINKLIST',OPTION,3) <> 1 & , /* check for LINklist option*/
OPTION <> 'APF' & , /* check for APF option */
OPTION <> 'SVC' & , /* check for SVC option */
OPTION <> 'ALL' & , /* check for ALL option */
Substr(OPTION,1,3) <> 'VAR' , /* check for VAR option */
then call INVALID_OPTION /* no valid option... */
Numeric digits 20 /* dflt of 9 not enough */
/* 20 can handle 64-bit */
Call COMMON /* control blocks needed by multiple routines */
Call HEADING /* Heading sub-routine */
Select
When OPTION = 'ALL' | Substr(OPTION,1,3) = 'VAR' then do
Call IPL /* IPL information */
Call VERSION /* Version information */
Call STOR /* Storage information */
Call CPU /* CPU information */
Call IPA /* Initialization info. */
Call SYMBOLS /* Symbols information */
Call VMAP /* Virt. Storage Map */
Call PAGE /* Page DSN information */
Call SMF /* SMF DSN information */
Call SUB /* Subsystem information */
Call ASID /* ASID usage information*/
Call LPA /* LPA List information */
Call LNKLST /* LNKLST information */
Call APF /* APF List information */
Call SVC /* SVC information */
End /* when OPTION = 'ALL' */
When Abbrev('VERSION',OPTION,3) = 1 then call VERSION
When Abbrev('STORAGE',OPTION,3) = 1 then call STOR
When Abbrev('STORE',OPTION,3) = 1 then call STOR
When Abbrev('MEMORY',OPTION,3) = 1 then call STOR
When Abbrev('SYMBOLS',OPTION,3) = 1 then call SYMBOLS
When Abbrev('VMAP',OPTION,3) = 1 then call VMAP
When Abbrev('ASM',OPTION,3) = 1 then call PAGE
When Abbrev('AUX',OPTION,3) = 1 then call PAGE
When Abbrev('SSI',OPTION,3) = 1 then call SUB
When Abbrev('SSN',OPTION,3) = 1 then call SUB
When Abbrev('SUBSYSTEMS',OPTION,3) = 1 then call SUB
When Abbrev('PAGE',OPTION,3) = 1 then call PAGE
When Abbrev('ASID',OPTION,3) = 1 then call ASID
When Abbrev('ASVT',OPTION,3) = 1 then call ASID
When Abbrev('LNKLST',OPTION,3) = 1 then call LNKLST
When Abbrev('LINKLIST',OPTION,3) = 1 then call LNKLST
Otherwise interpret "Call" OPTION
End /* select */
/*********************************************************************/
/* Done looking at all control blocks */
/*********************************************************************/
/*********************************************************************/
/* IPLINFO called as a function with an alternate delimiter. */
/* Return variable names and exit */
/*********************************************************************/
If Substr(OPTION,1,4) = 'VAR2' & EXEC_TYPE='FUNCTION' then do
"DROPBUF" /* remove data stack */
FUNCDLM = VAR.1 /* function delimiter */
ALL_VARS = Value(VAR.2) /* at least one var */
Do V = 3 to 21 /* check for others */
If VAR.V = '' then leave /* done, leave loop */
Else ALL_VARS = ALL_VARS || , /* concat additional */
FUNCDLM || Value(VAR.V) /* var + dlm at end */
End /* end Do V */
Return ALL_VARS /* return vars */
End
/*********************************************************************/
/* IPLINFO called as a function. Return variable names and exit */
/*********************************************************************/
If Substr(OPTION,1,3) = 'VAR' & EXEC_TYPE='FUNCTION' then do
"DROPBUF" /* remove data stack */
ALL_VARS = Value(VAR.1) /* at least one var */
Do V = 2 to 20 /* check for others */
If VAR.V = '' then leave /* done, leave loop */
Else ALL_VARS = ALL_VARS || , /* concat additional */
FUNCDLM || Value(VAR.V) /* var + dlm at end */
End /* end Do V */
Return ALL_VARS /* return vars */
End
/*********************************************************************/
/* If ISPF is active and the BROWSEOP option is set (default) then */
/* browse the output - otherwise write to the terminal */
/*********************************************************************/
If SYSISPF = 'ACTIVE' & BROWSEOP = 'YES' , /* ISPF active and */
then call BROWSE_ISPF /* BROWSEOP option set? */
Else do queued() /* ISPF is not active */
Parse pull line /* pull queued lines */
Say line /* say lines */
End /* else do */
Exit 0 /* End IPLINFO - RC 0 */
/*********************************************************************/
/* End of main IPLINFO code */
/*********************************************************************/
/*********************************************************************/
/* Start of sub-routines */
/*********************************************************************/
INVALID_OPTION: /* Invalid option sub-routine */
If SYSISPF = 'ACTIVE' then do
Queue ' '
Queue ' ******************************************************'
If OPTION <> '?' then,
Queue ' * Invalid IPLINFO option. *'
Queue ' * Please hit PF1/HELP two times for valid options. *'
Queue ' ******************************************************'
Queue ' '
OPTION = 'Invalid'
Call BROWSE_ISPF
Exit 16
End
Else do
Call CKWEB /* call CKWEB sub-routine */
Say Copies('*',79)
Say " "
If OPTION <> '?' then,
Say "Invalid IPLINFO option."
Say " "
Say "EXECUTION SYNTAX: %IPLINFO <option>"
Say " "
Say "VALID OPTIONS ARE 'ALL', 'IPL', 'VERsion'," ,
"'STOrage', 'CPU', 'IPA', 'SYMbols',"
Say " 'VMAp', 'PAGe', 'SMF', 'SUB'," ,
"'ASId', 'LPA', 'LNKlst' or 'LINklist' and 'APF'"
Say " "
Say "** 'ALL' is the default option"
Say "** OPTIONS may be abbreviated by using 3 or more characters"
Say " "
Say Copies('*',79)
If OPTION = '?' then Exit 0
Else exit 16
End
return
End /* Do SVCESRL = 1 to 4 */
Queue ' '
Queue ' SVC Usage Summary:'
Queue ' Total number of active standard SVCs (including ESR' ,
'slots) =' SVCACT_TOT
Queue ' Total number of unused standard SVCs =' SVCUNUSED_TOT
Queue ' Total number of active standard SVCs' ,
'requiring APF auth =' SVCAPF_TOT
Queue ' Total number of active Type 1 ESR SVCs =' SVCESR_T1_TOT
Queue ' Total number of active Type 2 ESR SVCs =' SVCESR_T2_TOT
Queue ' Total number of active Type 3/4 ESR SVCs =' SVCESR_T3_TOT
Queue ' Total number of active Type 6 ESR SVCs =' SVCESR_T6_TOT
Return
GET_CPCSI:
SI_OFF=0
IRALCCT = C2d(Storage(D2x(RMCT+620),4)) /* point to IRALCCT */
/* (undocumented) */
If Bitand(CVTOSLV5,'08'x) = '08'x then , /* z/OS 1.10 and above */
SI_OFF = 128 /* additional offset to CPC SI info in IRALCCT */
/****************************************************************/
/* If you have z/OS 1.12 or z/OS 1.13 with z13 support */
/* maintenance applied you will have to uncomment either the */
/* first 2 lines or the 2nd 2 lines to fix the CPCSI display. */
/* The 2nd set should work for z/OS 1.12 or z/OS 1.13 systems */
/* that do have the maintenance and also for those systems that */
/* do not have the maintenance. */
/****************************************************************/
/*If Bitand(CVTOSLV5,'02'x) = '02'x then , */ /* z/OS 1.12 and > */
/* SI_OFF = 384 */ /* additional offset to CPC SI info in IRALCCT */
/*If C2x(Storage(D2x(IRALCCT+10),1)) <> '40' then , *//* z13 support */
/* SI_OFF = 384 */ /* additional offset to CPC SI info in IRALCCT */
If Bitand(CVTOSLV6,'80'x) = '80'x then , /* z/OS 2.1 and above */
SI_OFF = 384 /* additional offset to CPC SI info in IRALCCT */
/****************************************************************/
/* The check below was added for a reported problem on */
/* z/OS 2.3 at RSU1812 or RSU1903. I'm not sure what APAR(s) */
/* broke this or if the same APAR could apply to earlier z/OS */
/* versions. */
/* */
/* If the CPU node display doesn't look right, delete the code */
/* that changes the offset to 392 or comment it out. */
/****************************************************************/
If Bitand(CVTOSLV6,'10'x) = '10'x then /* z/OS 2.3 and above */
/* (MODEL='3906' | MODEL='3907') | */ /* z/OS 2.3 + z14 */
/* (MODEL='2964' | MODEL='2965') then */ /* z/OS 2.3 + z13 */
SI_OFF = 392 /* additional offset to CPC SI info in IRALCCT */
CPCSI_TYPE = Storage(D2x(IRALCCT+332+SI_OFF),4) /* Type */
CPCSI_MODEL = Storage(D2x(IRALCCT+336+SI_OFF),4) /* Model */
CPCSI_MODEL = Strip(CPCSI_MODEL) /* Remove blanks */
CPCSI_MAN = Storage(D2x(IRALCCT+384+SI_OFF),16) /* Manufacturer */
CPCSI_MAN = Strip(CPCSI_MAN) /* Remove blanks */
CPCSI_PLANT = Storage(D2x(IRALCCT+400+SI_OFF),4) /* Plant */
CPCSI_PLANT = Strip(CPCSI_PLANT) /* Remove blanks */
CPCSI_CPUID = Storage(D2x(IRALCCT+352+SI_OFF),16) /* CPUID */
CPCSI_MODELID = Storage(D2x(IRALCCT+592+SI_OFF),4) /* Model ID */
CPCSI_MODELID = Strip(CPCSI_MODELID) /* Remove blanks */
/* CPCSI_MODELID may not be valid on emulated */
/* z/OS systems like FLEX, HERC and z/PDT */
Return
FORMAT_MEMSIZE:
/****************************************************************/
/* The following code is used to display the storage size in */
/* the largest possible unit. For example, 1023G and 1025G are */
/* displayed as 1023G and 1025G, but 1024G is displayed as 1T. */
/* The size passed to the routine must be in MB. */
/****************************************************************/
Arg SIZE_IN_MB
Select
When SIZE_IN_MB < 1024 then do
MUNITS = 'M'
End
When SIZE_IN_MB >= 1024 & SIZE_IN_MB < 1048576 then do
If SIZE_IN_MB/1024 == TRUNC(SIZE_IN_MB/1024) then do
SIZE_IN_MB = SIZE_IN_MB/1024
MUNITS = 'G'
End
Else MUNITS = 'M'
End
When SIZE_IN_MB >= 1048576 & SIZE_IN_MB < 1073741824 then do
If SIZE_IN_MB/1048576 == TRUNC(SIZE_IN_MB/1048576) then do
SIZE_IN_MB = SIZE_IN_MB/1048576
MUNITS = 'T'
End
Else do
If SIZE_IN_MB/1024 == TRUNC(SIZE_IN_MB/1024) then do
SIZE_IN_MB = SIZE_IN_MB/1024
MUNITS = 'G'
End
Else MUNITS = 'M'
End
End
When SIZE_IN_MB >= 1073741824 & ,
SIZE_IN_MB <= 17591112302592 then do
If SIZE_IN_MB/1073741824 == TRUNC(SIZE_IN_MB/1073741824) ,
then do
SIZE_IN_MB = SIZE_IN_MB/1073741824
MUNITS = 'P'
End
Else do
SIZE_IN_MB = SIZE_IN_MB/1048576
MUNITS = 'T'
End
End
When SIZE_IN_MB = 17592186040320 then do
SIZE_IN_MB = 'NOLIMIT' /* 16384P */
MUNITS = ''
End
When SIZE_IN_MB > 17592186040320 then do
SIZE_IN_MB = '*NOLIMT' /* >16384P (16EB) ?? */
MUNITS = ''
End
Otherwise do
Queue ' '
Queue 'Error in FORMAT_MEMSIZE code. Contact Mark Zelden.'
Queue 'SIZE_IN_MB=' SIZE_IN_MB
Queue ' '
SIZE_IN_MB = '*ERROR*'
MUNITS = ''
End
End /* select */
STOR_SIZE = SIZE_IN_MB || MUNITS
Return STOR_SIZE
REXXTOD:
/* REXX */
/* */
/* AUTHOR: Mark Zelden */
/* */
/***********************************************************/
/* Convert TOD string which is units since January 1, 1990 */
/* Result is in format of YYYY.DDD HH:MM:SS.ttt */
/* */
/* Examples: */
/* REXXTOD B92E37543F000000 --> 2003.086 05:06:06.435 */
/* REXXTOD C653258535522000 --> 2010.205 13:23:45.154 */
/* REXXTOD C8B8D8A516A77000 --> 2011.328 16:09:07.768 */
/***********************************************************/
Arg TODIN
/* Numeric Digits 16 */ /* commented out, IPLINFO already higher */
TODIN = Left(TODIN,13,0) /* rtn can only handle 1000s of a second */
TODIN = X2d(TODIN) /* convert to decimal for arithmetic */
TODIN = TODIN % 1000
TTT = TODIN // 1000 /* 1000s of a second - ".ttt" */
TODIN = TODIN % 1000
SS = TODIN // 60; /* Seconds - "SS" */
TODIN = TODIN % 60
MM = TODIN // 60; /* Minutes - "MM" */
TODIN = TODIN % 60
HH = TODIN // 24; /* Hours - "HH" */
TODIN = TODIN % 24
WHOLENUM = Strip(WHOLENUM)
COMMAVAR3 = ''
Parse var WHOLENUM COMMAVAR1
COMMAVAR1 = Reverse(COMMAVAR1)
Do while COMMAVAR1 <> ''
Parse var COMMAVAR1 COMMAVAR2 4 COMMAVAR1
If COMMAVAR3 = '' then COMMAVAR3 = COMMAVAR2
Else COMMAVAR3 = COMMAVAR3','COMMAVAR2
End
FORMATTED_WHOLENUM = Reverse(COMMAVAR3)
Return FORMATTED_WHOLENUM
/* rexx */
RDATE:
/* */
/* AUTHOR: Mark Zelden */
/* */
/************************************************/
/* Convert MM DD YYYY , YYYY DDD, or NNNNN to */
/* standard date output that includes the day */
/* of the week and the number of days (NNNNN) */
/* from January 1, 1900. This is not the same */
/* as the Century date! Valid input dates range */
/* from 01/01/1900 through 12/31/2172. */
/* */
/* A parm of "TODAY" can also be passed to */
/* the date conversion routine. */
/* MM DD YYYY can also be specifed as */
/* MM/DD/YYYY or MM-DD-YYYY. */
/* */
/* The output format is always as follows: */
/* MM/DD/YYYY.JJJ NNNNN WEEKDAY */
/* */
/* The above value will be put in the special */
/* REXX variable "RESULT" */
/* example: CALL RDATE TODAY */
/* example: CALL RDATE 1996 300 */
/* example: CALL RDATE 10 26 1996 */
/* example: CALL RDATE 10/26/1996 */
/* example: CALL RDATE 10-26-1996 */
/* example: CALL RDATE 35363 */
/* result: 10/26/1996.300 35363 Saturday */
/************************************************/
arg P1 P2 P3
JULTBL = '000031059090120151181212243273304334'
DAY.0 = 'Sunday'
DAY.1 = 'Monday'
DAY.2 = 'Tuesday'
DAY.3 = 'Wednesday'
DAY.4 = 'Thursday'
DAY.5 = 'Friday'
DAY.6 = 'Saturday'
Select
When P1 = 'TODAY' then do
P1 = Substr(date('s'),5,2)
P2 = Substr(date('s'),7,2)
P3 = Substr(date('s'),1,4)
call CONVERT_MDY
call THE_END
end
When P2 = '' & P3 = '' then do
call CONVERT_NNNNN
call THE_END
end
When P3 = '' then do
call CONVERT_JDATE
call DOUBLE_CHECK
call THE_END
end
otherwise do
call CONVERT_MDY
call DOUBLE_CHECK
call THE_END
end
end /* end select */
/* say RDATE_VAL; exit 0 */
return RDATE_VAL
/**********************************************/
/* E N D O F M A I N L I N E C O D E */
/**********************************************/
CONVERT_MDY:
if P1<1 | P1>12 then do
say 'Invalid month passed to date routine'
exit 12
end
if P2<1 | P2>31 then do
say 'Invalid day passed to date routine'
exit 12
end
if (P1=4 | P1=6 | P1=9 | P1=11) & P2>30 then do
say 'Invalid day passed to date routine'
exit 12
end
if P3<1900 | P3>2172 then do
say 'Invalid year passed to date routine. Must be be 1900-2172'
exit 12
end
BASE = Substr(JULTBL,((P1-1)*3)+1,3)
if (P3//4=0 & P3<>1900 & P3<>2100) then LEAP= 1
else LEAP = 0
if P1 > 2 then BASE = BASE+LEAP
JJJ = BASE + P2
MM = P1
DD = P2
YYYY = P3
return
CONVERT_NNNNN:
if P1<1 | P1>99712 then do
say 'Invalid date passed to date routine. NNNNN must be 1-99712'
exit 12
end
/* Determine YYYY and JJJ */
if P1>365 then P1=P1+1
YEARS_X4=(P1-1)%1461
JJJ=P1-YEARS_X4*1461
if P1 > 73415 then JJJ = JJJ +1
EXTRA_YEARS=(JJJ*3-3)%1096
JJJ=JJJ-(EXTRA_YEARS*1096+2)%3
YYYY=YEARS_X4*4+EXTRA_YEARS+1900
P1 = YYYY ; P2 = JJJ ; call CONVERT_JDATE
CONVERT_JDATE:
MATCH = 'N'
if P1<1900 | P1>2172 then do
say 'Invalid year passed to date routine. Must be be 1900-2172'
exit 12
end
if P2<1 | P2>366 then do
say 'Invalid Julian date passed to date routine'
exit 12
end
if (P1//4=0 & P1<>1900 & P1<>2100) then LEAP= 1
else LEAP = 0
ADJ1 = 0
ADJ2 = 0
Do MM = 1 to 11
VAL1 = Substr(JULTBL,((MM-1)*3)+1,3)
VAL2 = Substr(JULTBL,((MM-1)*3)+4,3)
if MM >=2 then ADJ2 = LEAP
if MM >=3 then ADJ1 = LEAP
if P2 > VAL1+ADJ1 & P2 <= VAL2+ADJ2 then do
DD = P2-VAL1-ADJ1
MATCH = 'Y'
leave
end
end
if MATCH <> 'Y' then do
MM = 12
DD = P2-334-LEAP
end
YYYY = P1
JJJ = P2
return
DOUBLE_CHECK:
if MM = 2 then do
if DD > 28 & LEAP = 0 then do
say 'Invalid day passed to date routine'
exit 12
end
if DD > 29 & LEAP = 1 then do
say 'Invalid day passed to date routine'
exit 12
end
end
if LEAP = 0 & JJJ > 365 then do
say 'Invalid Julian date passed to date routine'
exit 12
end
return
THE_END:
YR_1900 = YYYY-1900
NNNNN = (YR_1900*365) +(YR_1900+3)%4 + JJJ
if YYYY > 1900 then NNNNN = NNNNN-1
if YYYY > 2100 then NNNNN = NNNNN-1
INDEX = NNNNN//7 /* index to DAY stem */
WEEKDAY = DAY.INDEX
DD = Right(DD,2,'0')
MM = Right(MM,2,'0')
YYYY = Strip(YYYY)
NNNNN = Right(NNNNN,5,'0')
JJJ = Right(JJJ,3,'0')
SIG_ALL:
SIGTYPE = Condition('C') /* condition name */
If SIGTYPE = 'SYNTAX' then , /* SYNTAX error ? */
SIGINFO = Errortext(RC) /* rexx error message */
Else SIGINFO = Condition('D') /* condition description */
SIGLINE = Strip(Sourceline(SIGL)) /* error source code */
Say 'SIGNAL -' SIGTYPE 'ERROR:' SIGINFO , /* display the error info */
'on source line number' SIGL':' /* and line number */
Say '"'SIGLINE'"' /* error source code */
"Delstack" /* delete data stack */
Exit 16 /* exit RC=16 */