如何於 CL 中產生 UUID ?(Command GENUUID with MI GENUUID)
How to Generate UUID in CL ? (Command GENUUID with MI GENUUID)
File : QCLSRC
Member: GENUUIDC
Type : CLLE
/* */
/* \\\\\\\ */
/* ( o o ) */
/*------------------------oOO----(_)----OOo-----------------------*/
/* */
/* Program : GENUUIDC */
/* System : IBM i V7R2 */
/* Author : Vengoal Chang */
/* Date : 2023/11/10 */
/* Description : Generate Universal Unique Identifier (GENUUID)*/
/* GENUUID command CPP */
/* */
/* ooooO Ooooo */
/* ( ) ( ) */
/*----------------------( )-------------( )-------------------*/
/* (_) (_) */
/* */
/* */
/* To compile : */
/* The source type must be "CLLE" (and not CLP). */
/* Compile with STRPDM option 14 or use the */
/* CRTBNDCL command. */
/* */
/*----------------------------------------------------------------*/
Pgm Parm(&UUIDP &UUIDHEX)
Dcl &UUIDP *Char 16
Dcl &UUIDHEX *Char 32
Dcl &TMPL *Char 32
Dcl &LEN *Uint 4 VALUE(32)
Dcl &BytPrv *Uint Stg(*DEFINED) +
Len(4) DefVar(&TMPL)
Dcl &BytAvl *Uint Stg(*DEFINED) +
Len(4) DefVar(&TMPL)
Dcl &Reserved *Char Stg(*DEFINED) +
Len(8) DefVar(&TMPL 10)
Dcl &UUID *Char Stg(*DEFINED) +
Len(16) DefVar(&TMPL 17)
Dcl &RcvHexLen *Int 4 32
CallPrc Prc('_PROPB') Parm((&TMPL *ByRef) +
(X'00' *ByVal) +
(&LEN *ByVal))
ChgVar &BytPrv 32
CallPrc Prc('_GENUUID') Parm((&TMPL *ByRef))
ChgVar &UUIDP &UUID
CallPrc PRC('cvthc') +
PARM((&UUIDHEX *ByRef) +
(&UUID *ByRef) +
(&RcvHexLen *ByVal))
/* DmpClPgm */
End: EndPgm
File : QCMDSRC
Member: GENUUID
Type : CMD
/*****************************************************************/
/* */
/* Command name: GenUUID */
/* */
/* Author : Vengoal Chang */
/* */
/* Date written: 2023/11/10 */
/* */
/* Description : Generate Universal Unique Identifier (GENUUID) */
/* */
/* To compile: */
/* CRTCMD CMD( GenUUID ) */
/* PGM( GenUUIDC ) */
/* SRCMBR( GenUUID ) */
/* ALLOW( *Ipgm *Bpgm ) */
/* */
/*****************************************************************/
Cmd Prompt('Generate Universal Unique ID')
Parm Kwd( UUID ) +
Type(*CHAR) +
Len(16) +
RtnVal(*YES) +
Prompt('CL var for UUID (16)')
Parm Kwd( UUIDHEX ) +
Type(*CHAR) +
Len(32) +
RtnVal(*YES) +
Prompt('CL var for UUID HEX STR (32)')
A blog about IBM i (AS/400), MQ and other things developers or Admins need to know.
星期五, 11月 10, 2023
2023-11-10 如何於 CL 中產生 UUID ?(Command GENUUID with MI GENUUID)
星期四, 11月 09, 2023
2018-12-03 Check Daily Batch Jobs started or not
Check Daily Batch Jobs started or not
CHKBCHJOB CLP read file CHKBCHJOBP and check current time >= start time and current time < end time and chkflg ='Y',
then call API get the job active information, If job does not active, then send the job not acticve message to sysopr.
If job active, but status is MSGW, also send message to sysopr.
File : QDDSSRC
Member: CHKBCHJOBP
Type : PF
Usage : CrtPF File(CHKBCHJOBP)
A*****************************************************************
A* FUNCTION : CHKBCHJOB monitor batch job file
A* FILE : CHKBCHJOBP
A* AUTHOR : Vengoal Chang
A* DATE : 2018/12/03
A*****************************************************************
A UNIQUE
A R BCHJOBR TEXT('Batch job record')
A JOBNAME 10A COLHDG(' JOB NAME')
A JOBUSER 10A COLHDG(' USER')
A STRTIME 6S 0 COLHDG('start time')
A ENDTIME 6S 0 COLHDG('end time')
A CHKFLAG 1A COLHDG('check Y/N')
A NOTE 32O COLHDG('note')
A UPDDATE 8S 0 COLHDG('update date')
A UPDTIME 6S 0 COLHDG('update time')
A*----------------------------------------------------------------
A K JOBNAME
File : QCLSRC
Member: CHKBCHJOBC
Type : CLP
OS400 : V5R4 above
Usage : CrtClPgm Pgm(ChkBCHJOBC)
/* =============================================================== */
/* = Program ChkBchJobC = */
/* = ChkBchJob CLP = */
/* = Paramater notes: = */
/* = Read CHKBCHJOBP file to check daily job active or not = */
/* =============================================================== */
/* = Date : 2018/12/03 = */
/* = Author: Vengoal Chang = */
/* =============================================================== */
PGM
DCL &CURTIMEC *CHAR 6
DCL &STRTIMEC *CHAR 6
DCL &ENDTIMEC *CHAR 6
DCL &CURTIME *DEC (6 0)
DCL &MSGTEXT *CHAR 256
DCL &USP_NAME *CHAR 10
DCL &USP_LIB *CHAR 10
DCL &USP_QUAL *CHAR 20
DCL &USP_TYPE *CHAR 10
DCL &USP_SIZE *CHAR 4
DCL &USP_FILL *CHAR 1
DCL &USP_AUT *CHAR 10
DCL &USP_TEXT *CHAR 50
DCL &API_USQUAL *CHAR 20
DCL &API_JBQUAL *CHAR 26
DCL &API_JBNAM *CHAR 10
DCL &API_USER *CHAR 10
DCL &API_JOBNR *CHAR 6
DCL &API_STATUS *CHAR 10
DCL &STARTPOS *CHAR 4
DCL &DATALEN *CHAR 4
DCL &HEADER *CHAR 150
DCL &LST_OFFSET *DEC (10 0)
DCL &LST_SIZE *DEC (10 0)
DCL &LST_DATA *CHAR 4096
DCL &LST_NBR *DEC (5 0)
DCL &LST_LEN *DEC (5 0)
DCL &LST_LENBIN *CHAR 4
DCL &LST_POSBIN *CHAR 4
DCL &LST_COUNT *DEC (5 0) VALUE(0)
DCL &EXC_COUNT *DEC (5 0) VALUE(0)
DCL &TYPE *CHAR 1 VALUE('*')
DCL &NBRTORTN *CHAR 4
DCL &KEYSTORTN *CHAR 16
DCL &KEY1 *CHAR 4
DCL &KEY2 *CHAR 4
DCL &KEY3 *CHAR 4
DCL &KEY4 *CHAR 4
DCL &SBSSYS *CHAR 20
DCL &WRKSTS *CHAR 4
DCL &MSGRPLY *CHAR 1
DCL &USER *CHAR 10
DCL &CURUSR *CHAR 10
DCL &JOBNBR *CHAR 6
DCL &STATUS *CHAR 10
DCL &JOBTYPE *CHAR 1
DCL &SUBTYPE *CHAR 1
DCLF CHKBCHJOBP
MONMSG (CPF0000 MCH0000) *NONE GOTO ERROR
READF:
RCVF
MONMSG CPF0864 *N GOTO ENDF
RTVSYSVAL SYSVAL(QTIME) RTNVAR(&CURTIMEC)
CHGVAR &CURTIME &CURTIMEC
IF (&CURTIME >= &STRTIME *AND +
&CURTIME < &ENDTIME *AND +
&CHKFLAG = 'Y') Do
CallSubR SubR(ListJob)
If (&LST_NBR *EQ 0) Do
CHGVAR &STRTIMEC &STRTIME
CHGVAR &ENDTIMEC &ENDTIME
CHGVAR &MSGTEXT +
('* Bctch Job=' *CAT +
&JOBNAME *CAT 'run time : ' *CAT +
&STRTIMEC *BCAT '~' *BCAT &ENDTIMEC *CAT +
', program not started !')
SNDPGMMSG MSGID(CPF9898) MSGF(QCPFMSG) +
MSGDTA(&MSGTEXT) TOMSGQ(*SYSOPR)
EndDo
EndDo
Goto READF
ENDF:
Return
Error:
Call QMHMOVPM ( ' ' +
'*DIAG' +
x'00000001' +
'*PGMBDY' +
x'00000001' +
x'0000000800000000' +
)
Call QMHRSNEM ( ' ' +
x'0000000800000000' +
)
/****************************************************************/
/* Sub routine ListJob */
/****************************************************************/
SUBR SUBR(ListJob)
CHGVAR VAR(%BIN(&NBRTORTN)) VALUE(4)
/* 0101 -- Ststus as WRKACTJOB */
CHGVAR VAR(%BIN(&KEY1 )) VALUE(0101)
/* 1906 -- Subsystem */
CHGVAR VAR(%BIN(&KEY2 )) VALUE(1906)
/* 1307 -- Message Reply */
CHGVAR VAR(%BIN(&KEY3 )) VALUE(1307)
/* 0305 -- Current user profile */
CHGVAR VAR(%BIN(&KEY4 )) VALUE(0305)
CHGVAR VAR(&KEYSTORTN) VALUE(&KEY1 *CAT &KEY2 *CAT +
&KEY3 *CAT &KEY4)
CHGVAR VAR(&USP_NAME) VALUE('CHKJOBNAME')
CHGVAR VAR(&USP_LIB) VALUE('QTEMP')
CHGVAR VAR(&USP_QUAL) VALUE(&USP_NAME *CAT +
&USP_LIB)
CHGVAR VAR(&USP_TYPE) VALUE('MYTYPE')
CHGVAR VAR(%BIN(&USP_SIZE)) VALUE(128000)
CHGVAR VAR(&USP_FILL) VALUE(' ')
CHGVAR VAR(&USP_AUT) VALUE('*USE')
CHGVAR VAR(&USP_TEXT) VALUE('my user space')
DLTUSRSPC USRSPC(&USP_LIB/&USP_NAME)
MONMSG CPF0000
CALL PGM(QUSCRTUS) PARM(&USP_QUAL &USP_TYPE +
&USP_SIZE &USP_FILL &USP_AUT &USP_TEXT)
CHGVAR VAR(&API_USQUAL) VALUE(&USP_QUAL)
CHGVAR VAR(&API_JBNAM) VALUE(&JOBNAME)
CHGVAR VAR(&API_USER) VALUE('*ALL')
/* CHGVAR VAR(&API_USER) VALUE(&JOBUSER) */
CHGVAR VAR(&API_JOBNR) VALUE('*ALL')
CHGVAR VAR(&API_STATUS) VALUE('*ACTIVE')
CHGVAR VAR(&API_JBQUAL) VALUE(&API_JBNAM *CAT +
&API_USER *CAT &API_JOBNR)
CALL PGM(QUSLJOB) PARM(&API_USQUAL 'JOBL0200' +
&API_JBQUAL &API_STATUS X'00000000' +
&TYPE &NBRTORTN &KEYSTORTN)
CHGVAR VAR(%BIN(&STARTPOS)) VALUE(1)
CHGVAR VAR(%BIN(&DATALEN)) VALUE(140)
CALL PGM(QUSRTVUS) PARM(&API_USQUAL &STARTPOS +
&DATALEN &HEADER)
CHGVAR VAR(&LST_OFFSET) VALUE(%BIN(&HEADER 125 4))
CHGVAR VAR(&LST_SIZE) VALUE(%BIN(&HEADER 129 4))
CHGVAR VAR(&LST_NBR) VALUE(%BIN(&HEADER 133 4))
CHGVAR VAR(&LST_LEN) VALUE(%BIN(&HEADER 137 4))
CHGVAR VAR(%BIN(&LST_POSBIN)) VALUE(&LST_OFFSET + 1)
CHGVAR VAR(&LST_LENBIN) VALUE(%SST(&HEADER 137 4))
CHGVAR VAR(&LST_COUNT) VALUE(0)
IF (&LST_NBR *EQ 0) DO
/* Job not found */
Goto Lst_End
ENDDO
LST_LOOP: IF COND(&LST_COUNT *EQ &LST_NBR) THEN(GOTO +
CMDLBL(LST_END))
CALL PGM(QUSRTVUS) PARM(&API_USQUAL &LST_POSBIN +
&LST_LENBIN &LST_DATA)
CHGVAR VAR(&JOBNAME) VALUE(%SST(&LST_DATA 1 10))
CHGVAR VAR(&USER) VALUE(%SST(&LST_DATA 11 10))
CHGVAR VAR(&JOBNBR) VALUE(%SST(&LST_DATA 21 6))
CHGVAR VAR(&STATUS) VALUE(%SST(&LST_DATA 43 10))
CHGVAR VAR(&JOBTYPE) VALUE(%SST(&LST_DATA 53 1))
CHGVAR VAR(&SUBTYPE) VALUE(%SST(&LST_DATA 54 1))
/* for status */
CHGVAR VAR(&WRKSTS ) VALUE(%SST(&LST_DATA 81 4))
/* for subsystem */
CHGVAR VAR(&SBSSYS ) VALUE(%SST(&LST_DATA 101 20))
/* for msgrply */
CHGVAR VAR(&MSGRPLY) VALUE(%SST(&LST_DATA 137 1))
/* for current user */
CHGVAR VAR(&CURUSR ) VALUE(%SST(&LST_DATA 157 10))
IF (&WRKSTS *EQ 'MSGW' *AND &MSGRPLY *EQ '1') DO
CHGVAR &MSGTEXT ('* Job' *BCAT +
&JOBNBR *TCAT '/' *CAT +
&USER *TCAT '/' *CAT +
&JOBNAME *BCAT 'status is' *BCAT +
&WRKSTS *TCAT '.')
SNDPGMMSG MSGID(CPF9898) MSGF(QCPFMSG) +
MSGDTA(&MSGTEXT) TOMSGQ(*SYSOPR)
EndDo
CHGVAR VAR(&LST_COUNT) VALUE(&LST_COUNT + 1)
CHGVAR VAR(%BIN(&LST_POSBIN)) +
VALUE(%BIN(&LST_POSBIN) + &LST_LEN)
GOTO CMDLBL(LST_LOOP)
LST_END:
DLTUSRSPC USRSPC(&USP_LIB/&USP_NAME)
ENDSUBR
EndPgm:
EndPgm
File : QCLSRC
Member: CHKBCHJOB
Type : CLP
Usage : CRTCLPGM CHKBCHJOB
Insert your batch job which need to be monitored to CHKBCHJOBP
SBMJOB CMD(CALL CHKBCHJOB) JOB(CHKBCHJOB)
PGM
/*-- Global error monitoring: --------------------------------------*/
MonMsg CPF0000 *N GoTo Error
Loop:
Call ChkBchJobC
DlyJob 300
Goto Loop
Return:
Return
/*-- Error handling: -----------------------------------------------*/
Error:
Call QMHMOVPM ( ' ' +
'*DIAG' +
x'00000001' +
'*PGMBDY' +
x'00000001' +
x'0000000800000000' +
)
Call QMHRSNEM ( ' ' +
x'0000000800000000' +
)
EndPgm:
EndPgm
2017-11-21 Check Message Queue Manager started or not
Check Message Queue Manager started or not
File : QCLSRC
Member: CHKMQM
Type : CLLE
Usage : CrtCLMod Module( ChkMqm )
CrtPgm Pgm( ChkMqm ) BndSrvPgm((QMQM/LIBMQM))
/*-------------------------------------------------------------------*/
/* */
/* Program . . : CHKMQM */
/* Description : Check MQM Status */
/* Author . . : Vengoal Chang */
/* Published . : AS400ePaper */
/* Date . . . : November 21, 2017 */
/* */
/* Program function: CHKMQM command processing program */
/* */
/* */
/* Programmer's notes: */
/* */
/* Compile options: */
/* CrtCLMod Module( ChkMqm ) */
/* CrtPgm Pgm( ChkMqm ) */
/* BndSrvPgm((QMQM/LIBMQM)) */
/*-------------------------------------------------------------------*/
/* */
/* Exceptions monitored : */
/* MQCONN MQRC_Q_MGR_STOPPING */
/* MQRC_Q_MGR_QUIESCING */
/* MQRC_Q_MGR_NOT_AVAILABLE */
/* MQRC_STORAGE_NOT_AVAILABLE */
/* */
/*-------------------------------------------------------------------*/
Pgm ( &MQMName &RCChar)
Dcl &MQMName *CHAR 48
Dcl &RCChar *Char 10
/* Define local variables */
Dcl &HCONN *CHAR 4 X'00000000'
Dcl &CCODE *CHAR 4 X'00000000'
Dcl &REASON *CHAR 4 X'00000000'
Dcl &NOTAVAIL *CHAR 4 X'0000080B'
Dcl &STOPPING *CHAR 4 X'00000872'
Dcl &QUIESCING *CHAR 4 X'00000871'
Dcl &NOSTORAGE *CHAR 4 X'00000817'
Dcl &UNKNOWN *CHAR 4 X'0000080A'
Dcl &MsgDta *Char 256
Dcl &Rc *Dec (10 0)
/*-- Global error monitoring: --------------------------------------*/
MonMsg (CPF0000 MCH3601) *N GoTo Error
AddLibLe QMQM
MonMsg CPF0000
/******************************************************/
/* Connect to queue manager */
/******************************************************/
CallPrc 'MQCONN' (&MQMName &Hconn &Ccode &Reason)
If (%bin(&Ccode) *ne 0) Do
/*************************************************/
/* MQCONN failed */
/*************************************************/
ChgVar &Rc %Bin(&Reason)
ChgVar &RcChar &Rc
Select
When (&Reason = &STOPPING) Do
ChgVar &MsgDta ('Qmgr' *bcat &MQMName *Bcat +
'stopping, RC =' *bcat &RcChar)
EndDo
When (&Reason = &NOTAVAIL) Do
ChgVar &MsgDta ('Qmgr' *bcat &MQMName *Bcat +
'not available, RC =' *bcat &RcChar)
EndDo
When (&Reason = &QUIESCING) Do
ChgVar &MsgDta ('Qmgr' *bcat &MQMName *Bcat +
'quiescing, RC =' *bcat &RcChar)
EndDo
When (&Reason = &NOSTORAGE) Do
ChgVar &MsgDta ('Qmgr' *bcat &MQMName *Bcat +
'nostorage, RC =' *bcat &RcChar)
EndDo
When (&Reason = &UNKNOWN) Do
ChgVar &MsgDta ('Qmgr' *bcat &MQMName *Bcat +
'unknown, RC =' *bcat &RcChar)
EndDo
Otherwise Do
ChgVar &MsgDta ('Qmgr' *bcat &MQMName *Bcat +
'conn error, RC =' *bcat &RcChar)
EndDo
EndSelect
SndPgmMsg MsgId(CPF9898) MsgF(QCPFMSG) +
MsgDta(&MsgDta) ToPgmQ(*Ext) MsgType(*Info)
Goto Return
ENDDO
ChgVar &MsgDta ('Qmgr' *bcat &MQMName *Bcat +
'started')
SndPgmMsg MsgId(CPF9898) MsgF(QCPFMSG) +
MsgDta(&MsgDta) ToPgmQ(*EXT) MsgType(*INFO)
/******************************************************/
/* MQCONN worked so disonnect */
/******************************************************/
CallPrc 'MQDISC' (&Hconn &Ccode &Reason)
Return:
Return
/*-- Error handling: -----------------------------------------------*/
Error:
Call QMHMOVPM ( ' ' +
'*DIAG' +
x'00000001' +
'*PGMBDY' +
x'00000001' +
x'0000000800000000' +
)
Call QMHRSNEM ( ' ' +
x'0000000800000000' +
)
EndPgm:
EndPgm
File : QCMDSRC
Member: CHKMQM
Type : CMD
Usage : CrtCmd Cmd( CHKMQM )
Pgm( CHKMQM )
SrcFile( QCMDSRC )
Allow( *IPGM *BPGM )
/*-------------------------------------------------------------------*/
/* */
/* Compile options: */
/* */
/* CrtCmd Cmd( CHKMQM ) */
/* Pgm( CHKMQM ) */
/* SrcMbr( CHKMQM ) */
/* Allow( *IPGM *BPGM ) */
/* */
/*-------------------------------------------------------------------*/
Cmd Prompt( 'Check MQ Queue Manager')
Parm Kwd(MQMNAME) Type(*CHAR) Len(48) Min(1) +
Prompt('Message Queue Manager name')
Parm Kwd(RC) Type(*CHAR) Len(10) +
RtnVal(*Yes) +
Prompt('Return code')
File : QCLSRC
Member: CHKMQMTSTC
Type : CLP
Usage : CRTCLPGM CHKMQMTSTC
PGM
DCL &MQMNAME *CHAR 48
DCL &RC *CHAR 10
/*-- Global error monitoring: --------------------------------------*/
MonMsg CPF0000 *N GoTo Error
CHGVAR &MQMNAME 'TEST'
CHKMQM MQMNAME(&MQMNAME) RC(&RC)
If (&RC *NE ' ') Do
DmpClPgm
/* MQM got Exception */
/* do exception process */
EndDo
CHGVAR &MQMNAME 'TEST1'
CHKMQM MQMNAME(&MQMNAME) RC(&RC)
If (&RC *NE ' ') Do
DmpClPgm
/* MQM got Exception */
/* do exception process */
EndDo
Return:
RCLACTGRP ACTGRP(*ELIGIBLE)
Return
/*-- Error handling: -----------------------------------------------*/
Error:
RCLACTGRP ACTGRP(*ELIGIBLE)
Call QMHMOVPM ( ' ' +
'*DIAG' +
x'00000001' +
'*PGMBDY' +
x'00000001' +
x'0000000800000000' +
)
Call QMHRSNEM ( ' ' +
x'0000000800000000' +
)
EndPgm:
EndPgm
2016-12-26 Log message to IFS file with command LOGTOIFS
Log message to IFS file with command LOGTOIFS
File : QRPGLESRC
Member: LOGTOIFS
Type : RPGLE
Usage : CRTBNDRPG PGM(LOGTOIFS) SRCFILE(LIBxx/QRPGLESRC) SRCMBR(LOGTOIFS)
**===============================================================
** Command....... LogToIfs =
** CPP........... LogToIfs RPGLE =
** Description... Log Message to IFS File =
**===============================================================
** Date : 2016/12/26 =
** Author: Vengoal Chang =
**===============================================================
** =
** To compile: =
** CRTBNDRPG LOGTOIFS SRCFILE(lib/QRPGLESRC) DBGVIEW(*LIST) =
** =
**===============================================================
H DftActGrp(*NO)
H Debug Option(*SrcStmt:*NoDebugIo)
* PGM SDS
D SDS
D psdsPgmName *Proc
D psdsPgmLib 81 90 * Program library
D JobNam 244 253
D JobUsr 254 263
D JobNbr 264 269
D CurUsr 358 367
** API call to open a stream file
**
D open PR 10I 0 ExtProc('open')
D path * value options(*string)
D openflags 10I 0 value
D mode 10U 0 value options(*nopass)
D ccsid 10U 0 value options(*nopass)
D txtcreatid 10U 0 value options(*nopass)
D**********************************************************************
D* Flags for use in open()
D*
D* More than one can be used -- add them together.
D**********************************************************************
D* Writing Only
D O_WRONLY C 2
D* Create File if not exist
D O_CREAT C 8
D* Truncate File to 0 bytes
D O_TRUNC C 64
* Append to file
D O_APPEND C 256
D* Convert text by code-page
D O_CODEPAGE C 8388608
D* Convert text by ccsid
D O_CCSID C 32
D* Open in text-mode
D O_TEXTDATA C 16777216
* 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
D* owner authority
D**********************************************************************
D* Mode Flags.
D* basically, the mode parm of open(), creat(), chmod(),etc
D* uses 9 least significant bits to determine the
D* file's mode. (peoples access rights to the file)
D*
D* user: owner group other
D* access: R W X R W X R W X
D* bit: 8 7 6 5 4 3 2 1 0
D*
D* (This is accomplished by adding the flags below to get the mode)
D**********************************************************************
D S_IRUSR C 256
D S_IWUSR C 128
D S_IXUSR C 64
D S_IRWXU C 448
D* group authority
D S_IRGRP C 32
D S_IWGRP C 16
D S_IXGRP C 8
D S_IRWXG C 56
D* other people
D S_IROTH C 4
D S_IWOTH C 2
D S_IXOTH C 1
D S_IRWXO C 7
** API call to write data to a stream file
**
D write PR 10I 0 extproc('write')
D fildes 10I 0 value
D buf * value
D nbyte 10U 0 value
** API call to close a stream file
**
D close PR 10I 0 extproc('close')
D fildes 10I 0 value
D @__ERRNO PR * EXTPROC('__errno')
D STRERROR PR * EXTPROC('strerror')
D ERRNUM 10I 0 VALUE
D ERRNO PR 10I 0
D DIE PR
D PEMSG 256A CONST
D GetCaller PR
D CallingPgmNam 10
D CallingPgmLib 10
D fd S 10I 0
D data S 4096A
D IfsPath S 256A
D Curtime S Z
D PgmNam S 10
D PgmLib S 10
D Proc S 32
* Program parameters - title and page length in lines
D paIfsFile S 64
D paPath S 256
D paMessage S 2048
D paIncludeJob S 4
* Program parameters
C *Entry Plist
C Parm paIfsFile
C Parm paPath
C Parm paMessage
C Parm paIncludeJob
c eval *inlr = *on
C eval IfsPath = %trim(paPath) + '/' +
C %trim(paIfsFile)
C* Create an empty file
c eval fd = open(%trim(IfsPath)
c : O_CREAT + O_APPEND + O_WRONLY
c + O_CCSID + O_TEXT_CREAT
c + O_TEXTDATA
c : S_IWUSR+S_IRUSR+S_IRGRP+S_IROTH
c : 0
c : 0 )
c if fd < 0
c callp die('open(): ' + %Char(ERRNO) + ' ' +
c %trim(IfsPath) + ' ' +
c %STR(STRERROR(ERRNO)))
c return
c endif
C Time Curtime
C If paIncludeJob = '*YES'
C callp GetCaller ( PgmNam
C : PgmLib
C )
C eval data = %SubSt(%Char(Curtime):1:23)+ ' ' +
C JobNam + ' ' +
C JobUsr + ' ' +
C JobNbr + ' ' +
C PgmLib + ' ' +
C PgmNam + ' ' +
C %trimR(paMessage) + x'0D25'
C Else
C eval data = %SubSt(%Char(Curtime):1:23)+ ' ' +
C %trimR(paMessage) + x'0D25'
C EndIf
C
c callp write(fd: %addr(data): %len(%trim(data)))
C* Close the file:
c callp close(fd)
**********************************************************************
* Get Caller with Retrieve Call Stack API
**********************************************************************
P GetCaller B
D GetCaller PI
D CallingPgmNam 10
D CallingPgmLib 10
D RtvCallStack PR Extpgm('QWVRCSTK')
D 2000
D 10I 0
D 8 CONST
D 56
D 8 CONST
D 15
D Var DS 2000
D BytAvl 10I 0
D BytRtn 10I 0
D Entries 10I 0
D Offset 10I 0
D EntryCount 10I 0
D VarLen S 10I 0 Inz(%size(Var))
D ApiErr S 15
D JobIdInf DS
D JIDQName 26 Inz('*')
D JIDIntID 16
D JIDRes3 2 Inz(*loval)
D JIDThreadInd 10I 0 Inz(1)
D JIDThread 8 Inz(*loval)
D Entry DS 256
D EntryLen 10I 0
D PgmNam 10 Overlay(Entry:25)
D PgmLib 10 Overlay(Entry:35)
c eval CallingPgmNam = *blanks
c eval CallingPgmLib = *blanks
c callp RtvCallStack ( Var
c : VarLen
c : 'CSTK0100'
c : JobIdInf
c : 'JIDF0100'
c : ApiErr
c )
C Do EntryCount
C Eval Entry = %subst(Var:Offset + 1)
c if CallingPgmNam = *blanks and
c CallingPgmLib = *blanks
c if PgmNam = psdsPgmName and
c PgmLib = psdsPgmLib
C Else
c eval CallingPgmNam = Pgmnam
c eval CallingPgmLib = Pgmlib
C Endif
C Endif
C Eval Offset = Offset + EntryLen
C Enddo
C
C Return
P GetCaller E
**********************************************************************
* This ends this program abnormally, and sends back an escape.
* message explaining the failure.
**********************************************************************
P DIE B
D DIE PI
D PeMsg 256A CONST
D SndPgmMsg PR ExtPgm('QMHSNDPM')
D MessageId 7A Const
D QualMsgF 20A Const
D MsgData 256A Const
D MsgDtaLen 10I 0 Const
D MsgType 10A Const
D CallStkEnt 10A Const
D CallStkCct 10I 0 Const
D MessageKey 4A
D ErrorCode 32766A Options(*VarSize)
D Dsec DS
D DsecBytesP 1 4I 0 Inz(256)
D DsecBytesA 5 8I 0 Inz(0)
D DsecMsgId 9 15
D DsecReserv 16 16
D DsecMsgDta 17 256
D WWMsgLen S 10I 0
D WWTheKey S 4A
C EVAL WWMsgLen = %Len(%TrimR(PeMsg))
C IF WWMsgLen<1
C RETURN
C ENDIF
C Callp SndPgmMsg('CPF9897': 'QCPFMSG *LIBL':
C PeMsg: WWMsgLen: '*ESCAPE':
C '*PGMBDY': 1: WWTheKey: Dsec)
C RETURN
P DIE E
**********************************************************************
* This procedure return call socket C API errno
**********************************************************************
P ErrNo B
D ErrNo PI 10I 0
D P_EeeNo S *
D WWReturn S 10I 0 Based(P_Errno)
C EVAL P_Errno = @__Errno
C RETURN WWReturn
P Errno E
File : QCMDSRC
Member: LOGTOIFS
Type : CMD
Usage : CrtCmd Cmd( LogToIfs )
Pgm( LogToIfs )
SrcFile( QCMDSRC )
/* =============================================================== */
/* = Command....... LogToIfs = */
/* = CPP........... LogToIfs RPGLE = */
/* = Description... Log Message to IFS File = */
/* = = */
/* = CrtCmd Cmd( LogToIfs ) = */
/* = Pgm( LogToIfs ) = */
/* = SrcFile( QCMDSRC ) = */
/* =============================================================== */
/* = Date : 2016/12/26 = */
/* = Author: Vengoal Chang = */
/* =============================================================== */
Cmd Prompt('Log Message To IFS File')
Parm Kwd(ToStmf) +
Type(*Name) Len(64) Min(1) +
Prompt('To stream file name')
Parm Kwd(ToDir) +
Type(*Pname) LEN(256) MIN(1) +
Prompt('To directory')
Parm Kwd(LogMsg) +
Type(*Char) Len(2048) Min(1) +
Prompt('Log message')
Parm Kwd(InCldJob) +
Type(*Char) Len(4) +
Rstd(*Yes) +
Dft(*No ) +
Values(*YES *NO) +
Prompt('Log include job info')
Usage example:
Log Message To IFS File (LOGTOIFS)
Type choices, press Enter.
To stream file name . . . . . .
To directory . . . . . . . . . .
Log message . . . . . . . . . .
...
Log include job info . . . . . . *NO *YES, *NO
LOGTOIFS TOSTMF(AP1LOG.TXT) TODIR('/tmp') LOGMSG('test 2') INCLDJOB(*YES)
LOGTOIFS TOSTMF(AP1LOG.TXT) TODIR('/tmp') LOGMSG('test 3') INCLDJOB(*YES)
LOGTOIFS TOSTMF(AP1LOG.TXT) TODIR('/tmp') LOGMSG('test 3')
LOGTOIFS TOSTMF(AP1LOG.TXT) TODIR('/tmp') LOGMSG('test 4')
DSPF STMF('/tmp/AP1LOG.TXT')
Browse : /tmp/AP1LOG.TXT
Record : 1 of 4 by 14 Column : 1 59 by 79
Control :
....+....1....+....2....+....3....+....4....+....5....+....6....+....7....+....
************Beginning of data**************
2016-12-26-15.25.45.104 QPADEV0047 USRTEST 317148 QSYS QUOCMD test 2
2016-12-26-15.25.50.561 QPADEV0047 USRTEST 317148 QSYS QUOCMD test 3
2016-12-26-15.25.57.791 test 3
2016-12-26-15.26.02.863 test 4
************End of Data********************
2016-10-04 Check MQ Job by APPLTYPE USER or SYSTEM(CHKMQJOB) with StrMqmMqsc command output
Check MQ Job by APPLTYPE USER or SYSTEM(CHKMQJOB) with StrMqmMqsc command output
File : QCLSRC
Member: CHKMQJOBC
Type : CLP
Usage : CRTCLPGM PGM(CHKMQJOBC)
/*-------------------------------------------------------------------*/
/* */
/* Program . . : CHKMQJOB */
/* Description : Check MQ User Job */
/* Author . . : Vengoal Chang */
/* Published . : AS400ePaper */
/* Date . . . : July 25, 2016 */
/* */
/* Program function: CHKMQJOB command processing program */
/* */
/* */
/* Programmer's notes: */
/* CRTSRCPF FILE(QGPL/MQSRC) TEXT('MQ CMD SRC') */
/* Put following line to file QGPL/MQSRC menber CHKMQJOB */
/* DISPLAY CONN(*) TYPE(CONN) APPLTAG APPLTYPE */
/* */
/* Compile options: */
/* CrtClPgm Pgm( CHKMQJOB ) */
/* SrcFile( QCLSRC ) */
/* SrcMbr( *PGM ) */
/* */
/*-------------------------------------------------------------------*/
Pgm ( &Qmgr +
&ApplType +
&JobAction +
)
/*-- Parameters: ---------------------------------------------------*/
Dcl &Qmgr *Char 48
Dcl &ApplType *Char 10
Dcl &JobAction *Char 10
Dcl &MqSrcFile *Char 10 'MQSRC'
Dcl &MqSrcLib *Char 10 'QGPL'
Dcl &MqSrcMbr *Char 10 'CHKMQJOB'
/*-- Global error monitoring: --------------------------------------*/
MonMsg CPF0000 *N GoTo Error
DltF File(Qtemp/MqJobLst)
MonMsg CPF2105
CrtPf File(Qtemp/MqJobLst) RcdLen(133) IgcDta(*Yes)
StrMqmMqsc SrcMbr(&MqSrcMbr) SrcFile(&MqSrcLib/&MqSrcFile) +
MqmName(&Qmgr)
CpySplf File(QsysPrt) ToFile(Qtemp/MqJobLst) SplNbr(*Last)
Call ChkMqJobR (&Qmgr &ApplType &JobAction)
MonMsg CPF9898
DltSplF File(QsysPrt) SplNbr(*Last)
Return:
Return
/*-- Error handling: -----------------------------------------------*/
Error:
Call QMHMOVPM ( ' ' +
'*DIAG' +
x'00000001' +
'*PGMBDY' +
x'00000001' +
x'0000000800000000' +
)
Call QMHRSNEM ( ' ' +
x'0000000800000000' +
)
EndPgm:
EndPgm
File : QRPGLESRC
Member: CHKMQJOBR
Type : RPGLE
Usage : CRTBNDRPG PGM(CHKMQJOBR)
H DEBUG OPTION(*SRCSTMT:*NODEBUGIO) dftactgrp(*NO)
FMQJOBLST IF F 133 DISK
**-- API error information:
D ERRC0100 Ds Qualified
D BytPro 10i 0 Inz( %Size( ERRC0100 ))
D BytAvl 10i 0
D MsgId 7a
D 1a
D MsgDta 256a
**-- Global variables:
D MsgKey s 4a
**-- Send program message:
D SndPgmMsg Pr ExtPgm( 'QMHSNDPM' )
D SpMsgId 7a Const
D SpMsgFq 20a Const
D SpMsgDta 128a Const
D SpMsgDtaLen 10i 0 Const
D SpMsgTyp 10a Const
D SpCalStkE 10a Const Options( *VarSize )
D SpCalStkCtr 10i 0 Const
D SpMsgKey 4a
D SpError 32767a Options( *VarSize )
**-- Send completion message:
D SndCmpMsg Pr 10i 0
D PxMsgDta 512a Const Varying
**-- Send escape message:
D SndEscMsg Pr 10i 0
D PxMsgDta 512a Const Varying
D ParseInput PR
D GetAtrValue PR 512 Varying
D inputStr 512 Const Varying
D atrName 64 Const Varying
**-- Execute command:
D RunCmd Pr ExtPgm( 'QCMDEXC' )
D CmdStr 4096a Const Options( *VarSize )
D CmdLen 15p 5 Const
D CmdIGC 3a Const Options( *NoPass )
D InputData DS
D saInput 133A
D APPLTAGDS DS dim(100) qualified
D CONNID 16
D APPLTAG 28
D APPLTYPE 10
D idx S 10I 0
D jobCount S 10I 0
D jobCmd S 128
D mqJob S 52
D AtrValue S 512a Varying
C *Entry Plist
C Parm pMqmName 48
C Parm pApplType 10
C Parm pJobAction 10
C READ MQJOBLST InputData LR
C DOW *INLR = *OFF
C CALLP ParseInput
C READ MQJOBLST InputData LR
C ENDDO
C eval jobCount = idx
C
C For idx = 1 to jobCount
1B C If pApplType='USER'
2B C If %trim(APPLTAGDS(idx).APPLTYPE) = 'USER'
3b C If pJobAction = '*DSP'
C eval mqJob = APPLTAGDS(idx).APPLTYPE +
C APPLTAGDS(idx).APPLTAG
C callp SndCmpMsg('DISPLAY ' + mqJob)
3x C Else
4b C If pJobAction = '*ENDJOB'
C eval jobCmd = 'ENDJOB JOB(' +
C %trim(APPLTAGDS(idx).APPLTAG) +
C ') OPTION(*IMMED)'
C callp(e) RunCmd(%Trim(jobCmd):%Len(%Trim(jobcmd)))
4e C EndIf
4b C If pJobAction = '*ENDCNN'
C eval jobCmd = 'ENDMQMCONN CONN(' +
C %trim(APPLTAGDS(idx).CONNID) +
C ') MQMNAME(' +
C %trim(pMqmName) + ')'
C callp(e) RunCmd(%Trim(jobCmd):%Len(%Trim(jobcmd)))
4e C EndIf
4b C If %error
C Callp SndEscMsg ('Command Error:' +
C %trim(jobCmd) +
C ', please see joblog'
C )
C Else
C Callp SndCmpMsg ('Command :' +
C %trim(jobCmd) +
C ' completed.'
C )
4e C EndIf
3e C EndIf
2e C EndIf
1X C Else
2b C If %trim(APPLTAGDS(idx).APPLTYPE) <>'USER'
C eval mqJob = APPLTAGDS(idx).APPLTYPE +
C APPLTAGDS(idx).APPLTAG
C callp SndCmpMsg('DISPLAY ' + mqJob)
2e C EndIf
1e C EndIf
C
C EndFor
**********************************************************************
P ParseInput B
D ParseInput PI
C eval AtrValue=
C %trim(GetAtrValue(saInput: 'CONN'))
C If %len(%trim(AtrValue)) = 16
C eval idx = idx + 1
C eval APPLTAGDS(idx).CONNID = %trim(AtrValue)
C EndIf
C eval AtrValue=
C %trim(GetAtrValue(saInput: 'APPLTAG'))
C If %len(%trim(AtrValue)) > 0
C eval APPLTAGDS(idx).APPLTAG = %trim(AtrValue)
C eval AtrValue=
C %trim(GetAtrValue(saInput: 'APPLTYPE'))
C eval APPLTAGDS(idx).APPLTYPE=%trim(AtrValue)
C EndIf
P ParseInput E
P GetAtrValue B
D GetAtrValue PI 512 Varying
D pInputStr 512a Const Varying
D pAtrName 64a Const Varying
D AtrName S 512a
D AtrValue S 512a Varying
C eval AtrValue = ''
C z-add 0 Str 5 0
C z-add 0 End 5 0
C Eval AtrName = %trim(pAtrName)+ '('
C Eval Str=%Scan(%trim(AtrName): pInputStr: 1)
C If Str > 0
C Eval End=%Scan(%trim(')'):saInput: Str)
C Eval AtrValue =
C %SubSt(pInputStr:
C str+%len(%trim(AtrName)):
C End-(str+%len(%trim(AtrName))))
C EndIf
C Return AtrValue
P GetAtrValue E
**-- Send escape message: ----------------------------------------------**
P SndEscMsg B
D Pi 10i 0
D PxMsgDta 512a Const Varying
/Free
SndPgmMsg( 'CPF9898'
: 'QCPFMSG *LIBL'
: PxMsgDta
: %Len( PxMsgDta )
: '*ESCAPE'
: '*PGMBDY'
: 1
: MsgKey
: ERRC0100
);
If ERRC0100.BytAvl > *Zero;
Return -1;
Else;
Return 0;
EndIf;
/End-Free
P SndEscMsg E
**-- Send completion message: ------------------------------------------**
P SndCmpMsg B
D Pi 10i 0
D PxMsgDta 512a Const Varying
/Free
SndPgmMsg( 'CPF9897'
: 'QCPFMSG *LIBL'
: PxMsgDta
: %Len( PxMsgDta )
: '*COMP'
: '*PGMBDY'
: 1
: MsgKey
: ERRC0100
);
If ERRC0100.BytAvl > *Zero;
Return -1;
Else;
Return 0;
EndIf;
/End-Free
**
P SndCmpMsg E
File : QCMDSRC
Member: CHKMQJOB
Type : CMD
Usage : CrtCmd Cmd( CHKMQJOB )
Pgm( CHKMQJOBC )
SrcMbr( CHKMQJOB )
CRTSRCPF FILE(QGPL/MQSRC) TEXT('MQ CMD SRC')
Put following line to file QGPL/MQSRC menber CHKMQJOB
DISPLAY CONN(*) TYPE(CONN) APPLTAG APPLTYPE
/*-------------------------------------------------------------------*/
/* */
/* Compile options: */
/* */
/* CrtCmd Cmd( CHKMQJOB ) */
/* Pgm( CHKMQJOBC ) */
/* SrcMbr( CHKMQJOB ) */
/* */
/*-------------------------------------------------------------------*/
Cmd Prompt( 'Check MQ Job')
Parm QMNAME *Char 48 +
Min(1) +
Prompt('Queue manager name')
PARM ApplType *Char 10 +
Rstd(*YES) +
Dft(USER) +
Values(USER SYSTEM) +
Prompt('Application type')
PARM JobAction *Char 10 +
Rstd(*YES) +
Dft(*DSP) +
Values(*DSP *ENDCNN *ENDJOB) +
PmtCtl( P0001 ) +
Prompt('Job action')
P0001: PmtCtl Ctl( APPLTYPE ) +
Cond(( *EQ 'SYSTEM' ))
DEP Ctl(&APPLTYPE *EQ 'SYSTEM') +
Parm((&JOBACTION *EQ '*DSP')) +
NbrTrue( *EQ 1 )
Command sample:
Check MQ Job (CHKMQJOB)
Type choices, press Enter.
Queue manager name . . . . . . .
Application type . . . . . . . . USER USER, SYSTEM
Job action . . . . . . . . . . . *DSP *DSP, *ENDCNN, *ENDJOB
Note:
*DSP => display MQ job info
*ENDCNN => end MQ USER connection handle
*ENDJOB => end MQ USER connection job
參照: Start IBM MQ Commands (STRMQMMQSC)
參照: DISPLAY CONN
2016-04-06 擷取系統時間至微秒單位(Get system timesatmp with a precision in microseconds by API QWCCVTDT)
擷取系統時間至微秒單位(Get system timesatmp with a precision in microseconds by API QWCCVTDT)
範例含 CLP, RPGLE, COBOL。
File : QCLSRC
Member: GETSYSTIMC
Type : CLP
Usage : CRTCLPGM PGM(GETSYSTIMC)
PGM
/* For Convert Date & Time... */
dcl &CDT_I_FORM *char 10 value( '*CURRENT' )
dcl &CDT_I_VAR *char 8
dcl &CDT_O_FORM *char 10 value( '*YYMD' )
dcl &CDT_O_VAR *char 20
dcl &CDT_I_TZ *char 10 value( '*SYS' )
dcl &CDT_O_TZ *char 10 value( '*SYS' )
dcl &CDT_O_TZi *char 111 value( ' ' )
dcl &CDT_O_TZl *int value( 0 )
dcl &CDT_O_Pi *char 1 value( '1' )
/* And we'll need to specify an errcode receiver at one point... */
dcl &ERRCODE *char 116 value( x'00000074' )
dcl &ERRLEN *int value( 0 )
call QWCCVTDT ( +
&CDT_I_FORM +
&CDT_I_VAR +
&CDT_O_FORM +
&CDT_O_VAR +
&ERRCODE +
&CDT_I_TZ +
&CDT_O_TZ +
&CDT_O_TZi +
&CDT_O_TZl +
&CDT_O_Pi +
)
SndPgmMsg MsgId(CPF9898) MsgF(*LIBL/QCPFMSG) +
MsgDta(&CDT_O_VAR)
Return
ENDPGM
File : QRPGLESRC
Member: GETSYSTIMR
Type : RPGLE
Usage : CRTBNDRPG PGM(GETSYSTIMR)
**-- API error data structure:
D ERRC0100 Ds Qualified
D BytPrv 10i 0 Inz( %Size( ERRC0100 ))
D BytAvl 10i 0
D MsgId 7a
D 1a
D MsgDta 128a
DOutputVar DS
D CurCentury 2
D CurYear 2
D CurMonth 2
D CurDay 2
D CurHour 2
D CurMinute 2
D CurSecond 2
D CurMicroSec 6
D TimeZoneInfL 10i 0
C Move *On *InLr
C Call 'QWCCVTDT'
C Parm '*CURRENT' InputFmt 10
C Parm InputVar 1
C Parm '*YYMD' OutputFmt 10
C Parm OutputVar
C Parm ERRC0100
C Parm InpTimeZone 10
C Parm '*SYS' OutTimeZone 10
C Parm TimeZineInf 1
C Parm 0 TimeZoneInfL
C Parm '1' PrcInd 1
C OutputVar dsply
File : QCBLLESRC
Member: GETSYSTIME
Type : COBOL
Usage : CRTCBLPGM PGM(GETSYSTIME)
IDENTIFICATION DIVISION.
PROGRAM-ID. SAMPLE07.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
SOURCE-COMPUTER. IBM-AS400.
OBJECT-COMPUTER. IBM-AS400.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 DATES.
05 INPUT-DATE PIC X(10).
05 OUTPUT-DATE17 PIC X(17).
05 OUTPUT-DATE20 PIC X(20).
05 INPUT-DATE-FORMAT PIC X(10).
05 OUTPUT-DATE-FORMAT PIC X(10).
05 INPUT-TIME-ZONE PIC X(10) VALUE '*SYS'.
05 OUTPUT-TIME-ZONE PIC X(10) VALUE '*SYS'.
05 TIME-ZONE-INFO PIC X(10).
05 TIME-ZONE-INFO-LEN PIC S9(9) BINARY VALUE ZERO.
05 PRECISION-INDICATOR PIC X(01) VALUE '1'.
01 CURRENTTIME.
05 CUR-YEAR PIC X(04).
05 CUR-MONTH PIC X(02).
05 CUR-DAY PIC X(02).
05 CUR-HH PIC X(02).
05 CUR-MM PIC X(02).
05 CUR-SS PIC X(02).
05 CUR-MICROSECOND PIC X(06).
01 ERRPARM.
05 INPUT-L PIC S9(9) BINARY VALUE 116.
05 OUTPUT-L PIC S9(9) BINARY VALUE ZERO.
05 EXCEPTION-ID PIC X(7).
05 RESERVED PIC X(1).
05 EXCEPTION-DATA PIC X(100).
PROCEDURE DIVISION.
MAINLINE.
PERFORM GET-DATE-08
GOBACK.
GET-DATE-08.
MOVE SPACES TO EXCEPTION-ID.
MOVE "*CURRENT" TO INPUT-DATE-FORMAT.
MOVE "*YYMD " TO OUTPUT-DATE-FORMAT.
CALL "QWCCVTDT" USING INPUT-DATE-FORMAT ,
INPUT-DATE ,
OUTPUT-DATE-FORMAT,
CURRENTTIME ,
ERRPARM ,
INPUT-TIME-ZONE ,
OUTPUT-TIME-ZONE ,
TIME-ZONE-INFO ,
TIME-ZONE-INFO-LEN,
PRECISION-INDICATOR.
DISPLAY 'TIMESTAMP FROM COBOL: ' CURRENTTIME.
參照: Convert Date and Time Format (QWCCVTDT) API
2016-02-02 即時監控工作站錯誤訊息 CPF5140,並終止該工作站
即時監控工作站錯誤訊息 CPF5140,並終止該工作站
Monitor interactive job which got CPF5140 error message and end it
即時監控工作站錯誤訊息 CPF5140,並終止該工作站。
因為使用者有時會因等待輸入暫停過久,直接將5250工作站直接點擊右上角關閉方塊,
此時系統會拋出 CPF5140 錯誤,此時若該工作站正執行大量資料的存取,系統仍會繼續
執行,但最終仍無法傳回資訊,導致系統浪費資源,要防止此狀況發生,就須即時監控並
終止該工作站 JOB。
File : QCLSRC
Member: WCHCPF5140
Type : CLP
Usage : CRTCLPGM PGM(QGPL/WCHCPF5140)
Start
STRWCH SSNID(WCHCPF5140) WCHPGM(QGPL/WCHCPF5140)
WCHMSG((CPF5140))
WCHMSGQ((*JOBLOG))
WCHJOB((*ALL/*ALL/*ALL))
End
WRKWCH *ALL use option 2 to End Watch
/* ================================================================ */
/* */
/* Program : WCHCPF5140 */
/* */
/* Description: Monitor interactive job which got CPF5410 */
/* and end it to prevent system from high CPU usage */
/* */
/* Date : 2016/02/01 */
/* */
/* Author : Vengoal Chang */
/* ================================================================ */
/* */
/* */
/* CRTCLPGM PGM(WCHCPF5140) */
/* */
/* */
/* STRWCH SSNID(WCHCPF5140) WCHPGM(QGPL/WCHCPF5140) */
/* WCHMSG((CPF5140)) */
/* WCHMSGQ((*JOBLOG)) */
/* WCHJOB((*ALL/*ALL/*ALL)) */
/* */
/* ================================================================ */
Pgm Parm(&Type &Session &Error &Data)
Dcl Var(&Type) Type(*Char) Len(10)
Dcl Var(&Session) Type(*Char) Len(10)
Dcl Var(&Error) Type(*Char) Len(10)
Dcl Var(&Data) Type(*Char) Len(2000)
Dcl Var(&LenEvtDta) Type(*Int) Len(4) +
Stg(*Defined) DefVar(&Data 1)
Dcl Var(&Job) Type(*Char) Len(10) +
Stg(*Defined) DefVar(&Data 33)
Dcl Var(&User) Type(*Char) Len(10) +
Stg(*Defined) DefVar(&Data 43)
Dcl Var(&Nbr ) Type(*Char) Len( 6) +
Stg(*Defined) DefVar(&Data 53)
Dcl Var(&MSGID) Type(*Char) Len(7) +
Stg(*Defined) DefVar(&Data 5)
Dcl Var(&MsgF) Type(*Char) Len(10) +
Stg(*Defined) DefVar(&Data 391)
Dcl Var(&MsgFLib) Type(*Char) Len(10) +
Stg(*Defined) DefVar(&Data 401)
Dcl Var(&OffRplDta) Type(*Int) Len(4) +
Stg(*Defined) DefVar(&Data 441)
Dcl Var(&LenRplDta) Type(*Int) Len(4) +
Stg(*Defined) DefVar(&Data 445)
Dcl Var(&OrgLenRpl) Type(*Int) Len(4) +
Stg(*Defined) DefVar(&Data 59)
Dcl Var(&MsgDtaPtr) Type(*Ptr)
Dcl Var(&MsgDta) Type(*Char) Len(1010) +
Stg(*Based) BasPtr(&MsgDtaPtr)
/* CPF5140 char data */
Dcl Var(&MsgUser ) Type(*Char) Len(10) +
Stg(*Defined) DefVar(&MsgDta 1)
Dcl Var(&Host ) Type(*Char) Len(255) +
Stg(*Defined) DefVar(&MsgDta 11)
Dcl Var(&QualMsgf) Type(*Char) Len(20)
Dcl Var(&MsgTxt ) Type(*Char) Len(1024)
Dcl Var(&Rtvm0100 ) Type(*Char) Len(1024)
Dcl Var(&RplDta ) Type(*Char) Len(1024)
Dcl Var(&SysValTo) Type(*Char) Len(500)
Dcl VAR(&MsgTxtLenC) Type(*Char) Len(4)
Dcl VAR(&MsgTxtLen ) Type(*Dec ) Len(5 0)
Dcl VAR(&RplDtaLenC) Type(*Char) Len(4)
Dcl VAR(&ErrCode) Type(*Char) Len(15) /* Error Code */
/* Check to make sure this is a *MSGID watch */
If Cond(&Type = '*MSGID') Then(Do)
/* Check to make sure this is for CPF5140 */
If Cond(&MsgID = 'CPF5140') Then(Do)
ChgVar Var(&MsgDtaPtr) Value(%Addr(&Data))
Chgvar Var(%Offset(&MsgDtaPtr)) +
Value(%Offset(&MsgDtaPtr) + &OffRplDta)
ChgVar &RplDta %sst(&MsgDta 1 &LenRplDta)
ChgVar &QualMsgf (&MsgF *Cat &MsgFLib)
ChgVar %BIN(&MSGTXTLENC) 1024
ChgVar %BIN(&RplDtaLenC) &LenRplDta
ChgVar %BIN(&ErrCode 1 4) 15
Call QMHRTVM ( +
&Rtvm0100 +
&MsgTxtLenC +
'RTVM0100' +
&MSGID +
&QUALMSGF +
&RplDta +
&RplDtaLenC +
'*YES ' +
'*NO ' +
&Errcode)
ChgVar &MsgTxtLenC %SST(&Rtvm0100 9 4)
ChgVar &MsgTxtLen %BIN(&MsgTxtLenC)
ChgVar &MsgTxt (&MSGID *CAT ':' *BCAT +
%SST(&Rtvm0100 25 &MsgTxtLen) *BCAT +
'Job ' *BCAT +
&Nbr *CAT '/' *CAT &User *Tcat '/' *CAT &Job +
*BCAT 'was ended by watch program')
EndJob Job(&NBR/&USER/&JOB) Option(*IMMED)
MonMsg CPF0000
SndPgmMsg MsgId(CPF9898) Msgf(QCPFMSG) MsgDta(&MsgTxt) +
ToUsr(*SYSOPR)
EndDo
EndDo /* End If &Type = *MSGID */
ChgVar Var(&Error) Value(' ')
EndPgm
參照: STRWCH - Watch Exit Programs Explained with CL Example
2015-09-17 Retrieve AS400 Network Interfaces with java( List Network Interfaces (QtocLstNetIfc) API format NIFC0100)
Retrieve AS400 Network Interfaces with java( List Network Interfaces (QtocLstNetIfc) API format NIFC0100)
(RtvNetIfc.java)
File : RtvNetIfc.java
/* ==================================================================*/
/* */
/* Program . . : RtvNetIfc.java */
/* Description : List Network Interfaces */
/* Author . . : Vengoal Chang */
/* Published . : AS400ePaper */
/* Date . . . : September 17, 2015 */
/* */
/* ==================================================================*/
package com.free400.vengoal.as400api;
import com.ibm.as400.access.AS400;
import com.ibm.as400.access.AS400Bin4;
import com.ibm.as400.access.AS400Exception;
import com.ibm.as400.access.AS400Text;
import com.ibm.as400.access.ProgramParameter;
import com.ibm.as400.access.ServiceProgramCall;
import com.ibm.as400.access.SystemStatus;
import com.ibm.as400.access.UserSpace;
public class RtvNetIfc {
public static void main(String[] args) {
final AS400Bin4 intConverter_ = new AS400Bin4();
// Change following as400ip, as400user, as400password as your system and user profile setting
AS400 as400 = new AS400("as400ip", "as400user", "as400password");
try {
// The first parm is 20 characters, 10 chars of user space followed by 10 chars of library.
// Create a converter for 20 chars. AS400Text char20 = new AS400Text(20, system);
// The second parm is the format name (8 chars). Create a converter.
AS400Text char20 = new AS400Text(20, as400);
AS400Text char8 = new AS400Text(8, as400);
// Create program parameters
ProgramParameter[] parms = new ProgramParameter[3];
UserSpace usrSpc = new UserSpace(as400, "/QSYS.LIB/QTEMP.LIB/MYSPACE.USRSPC");
usrSpc.setMustUseProgramCall(true);
usrSpc.create(10240, // The initial size is 10KB
true, // Replace if the user space already exists
" ", // No extended attribute
(byte) 0x00, // The initial value is a null
"Created by a Java program", // The description of the user
// space
"*USE");
// First parm is qualified user space CHAR(20)
// CHAR(0-9) is the user space name
// CHAR(10-19) is the library name
String qSpace = "MYSPACE QTEMP ";
// First parm is the library qualified UserSpace
parms[0] = new ProgramParameter(char20.toBytes(qSpace));
parms[0].setParameterType(ProgramParameter.PASS_BY_REFERENCE);
// Second parm is the format
parms[1] = new ProgramParameter(char8.toBytes("NIFC0100"));
parms[1].setParameterType(ProgramParameter.PASS_BY_REFERENCE);
// Last parm is the error code. We pass an array of 0x00s so
// messages are returned.
byte[] bytes = new byte[32];
parms[2] = new ProgramParameter(bytes, 32);
parms[2].setParameterType(ProgramParameter.PASS_BY_REFERENCE);
System.out.println("Retrieving network interface information for system "
+ new SystemStatus(as400).getSystemName() + " ...");
ServiceProgramCall sPGMCall = new ServiceProgramCall(as400, "/QSYS.LIB/QTOCNETSTS.SRVPGM", "QtocLstNetIfc",
ServiceProgramCall.NO_RETURN_VALUE, parms);
if (sPGMCall.run() != true) {
throw new AS400Exception(sPGMCall.getMessageList());
} else {
byte[] header = new byte[140];
usrSpc.read(header, 0);
int list_Offset = intConverter_.toInt(header, 124);
int list_Size = intConverter_.toInt(header, 128);
int entry_count = intConverter_.toInt(header, 132);
int entry_size = intConverter_.toInt(header, 136);
int strPos = list_Offset;
System.out.println("IP Address " + " " + "NetWork Address" + " " + "Line Desc " + " " + "Status");
System.out.println("===============" + " " + "===============" + " " + "==========" + " " + "======");
for (int i = 0; i < entry_count; i++) {
String ipAdr = usrSpc.read(strPos, 15);
String netAdr = usrSpc.read(strPos + 20, 15);
String netWork = usrSpc.read(strPos + 40, 10);
String lineDesc = usrSpc.read(strPos + 50, 10);
String ifc = usrSpc.read(strPos + 60, 10);
byte[] ifcStatusBytes = new byte[4];
usrSpc.read(ifcStatusBytes, strPos + 72);
int ifcStatus = intConverter_.toInt(ifcStatusBytes);
System.out.println(ipAdr + " " + netAdr + " " + lineDesc + " " + ifcStatus);
strPos += entry_size;
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
參照: List Network Interfaces (QtocLstNetIfc) API
2015-07-02 Get AS400 Subsystem jobs with java( Open List of Jobs (QGYOLJOB) API format OLJB0300)
Get AS400 Subsystem jobs with java( Open List of Jobs (QGYOLJOB) API format OLJB0300)
(SubsystemJobOpenListTest.java, SubsystemJobListItem.java, SubsystemJobOpenList.java)
File : SubsystemJobListItem.java
///////////////////////////////////////////////////////////////////////////////
//
//
// Filename: SubsystemJobListItem.java
//
// Author : Vengoal Chang
//
// Date : 2015/07/01
//
//
///////////////////////////////////////////////////////////////////////////////
package com.vengoal.as400.list;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import com.ibm.as400.access.BinaryConverter;
public class SubsystemJobListItem {
public static final int ACTIVE_JOB_STATUS_FOR_JOBS_ENDING = 103; // Active job status for jobs ending
public static final int CURRENT_USER = 305; // Current user profile
public static final int CPU_TIME_USED_LARGE = 312; // Processing unit time used - total for the job
public static final int CPU_TIME_USED_FOR_DATABASE = 313; // Processing unit time used for database - total for the job (Deprecated)
public static final int ELAPSED_CPU_PERCENT_USED = 314; // Processing unit used - percent during the elapsed time (job)
public static final int ELAPSED_CPU_TIME_USED = 315; // Processing unit used - time during the elapsed time (job)
public static final int ELAPSED_CPU_PERCENT_USED_FOR_DATABASE = 316; // Processing unit used for database - percent during the elapsed time (job) (Deprecated)
public static final int ELAPSED_CPU_TIME_USED_FOR_DATABASE = 317; // Processing unit used for database - time during the elapsed time (job) (Deprecated)
public static final int DATE_ENTERED_SYSTEM = 402; // Date and time job entered system
public static final int ELAPSED_DISK_IO = 414; // Disk I/O count during the elapsed time (job)
public static final int DISK_IO = 415; // Disk I/O count - total for the job
public static final int ELAPSED_DISK_IO_ASYNCH = 416; // Disk I/O count during the elapsed time - asynchronous I/O (job)
public static final int ELAPSED_DISK_IO_SYNCH = 417; // Disk I/O count during the elapsed time - synchronous I/O (job)
public static final int CONTROLLED_END_REQUESTED = 502; // End status
public static final int FUNCTION_NAME = 601; // Function name
public static final int FUNCTION_TYPE = 602; // Function type
public static final int INTERNAL_JOB_IDENTIFIER = 902; // Internal job identifier
public static final int ELAPSED_INTERACTIVE_RESPONSE_TIME = 904; // Interactive response time - total during the elapsed time
public static final int ELAPSED_INTERACTIVE_TRANSACTIONS = 905; // Interactive transactions - count during the elapsed time
public static final int JOB_USER_IDENTITY = 1012; // Job user identity
public static final int JOB_END_REASON = 1014; // Job end reason
public static final int JOB_LOG_PENDING = 1015; // Job log pending
public static final int JOB_TYPE_ENHANCED = 1016; // Job type - enhanced
public static final int MEMORY_POOL = 1306; // Memory pool name
public static final int MESSAGE_REPLY = 1307; // Message reply
public static final int MESSAGE_KEY = 1308; // Message key, when active job waiting for a message
public static final int MESSAGE_QUEUE = 1309; // Message queue name - qualified, when active job waiting for a message
public static final int MESSAGE_QUEUE_ASP = 1310; // Message queue library ASP device name, when active job waiting for a message
public static final int ELAPSED_PAGE_FAULTS = 1609; // Page fault count during the elapsed time (job)
public static final int RUN_PRIORITY = 1802; // Run priority (job)
public static final int SUBSYSTEM = 1906; // Subsystem description name - qualified
public static final int SERVER_TYPE = 1911; // Server type
public static final int SPOOLED_FILE_ACTION = 1982; // Spooled file action
public static final int THREAD_COUNT = 2008; // Thread count
public static final int TEMP_STORAGE_USED_LARGE = 2009; // Temporary storage used, in megabytes(from V7R2)
private String jobName;
private String jobUser;
private String jobNumber;
private String status;
private String jobType;
private String jobSubtype;
private String currentUser; // key 305
private String functionName; // key 601
private String functionType; // key 602
private String messageReply; // key 1307
private byte[] messageKey; // key 1308
private String qualMessageQueue; // key 1309
private String qualSubsystem; // key 1906
private TreeMap keyValues = new TreeMap(); // key others
public SubsystemJobListItem(String jobName, String jobUser, String jobNumber,
String status, String jobType,String jobSubtype, String currentUser, String functionName,
String functionType,
String messageReply, byte[] messageKey, String qualMessageQueue, String qualSubsystem) {
this.jobName = jobName;
this.jobUser = jobUser;
this.jobNumber = jobNumber;
this.status = status;
this.jobType = jobType;
this.jobSubtype = jobSubtype;
this.currentUser = currentUser;
this.functionName = functionName;
this.functionType = functionType;
this.messageReply = messageReply;
this.messageKey = messageKey;
this.qualMessageQueue = qualMessageQueue;
this.qualSubsystem = qualSubsystem;
}
public Object getObject(int key){
return keyValues.get(key);
}
public void setKeyValues(TreeMap keyValues){
this.keyValues = keyValues;
}
public String getJobName() {
return jobName;
}
public String getJobUser() {
return jobUser;
}
public String getJobNumber() {
return jobNumber;
}
public String getStatus() {
return status;
}
public String getJobType() {
return jobType;
}
public String getJobSubtype() {
return jobSubtype;
}
public String getCurrentUser() {
return currentUser;
}
public String getFunctionName() {
return functionName;
}
public String getFunctionType() {
return functionType;
}
public String getMessageReply() {
return messageReply;
}
public byte[] getMessageKey() {
return messageKey;
}
public String getQualMessageQueue() {
return qualMessageQueue;
}
public String getQualSubsystem() {
return qualSubsystem;
}
public String toString(){
StringBuffer strBuf = new StringBuffer();
strBuf.append(jobName).append("/");
strBuf.append(jobUser).append("/");
strBuf.append(jobNumber).append(",");
strBuf.append(status).append(",");
strBuf.append(jobType).append(",");
strBuf.append(jobSubtype).append(",");
strBuf.append("305=" + currentUser).append(",");
strBuf.append("601=" + functionName).append(",");
strBuf.append("602=" + functionType).append(",");
strBuf.append("1307=" + messageReply).append(",");
strBuf.append("1308(MSGKEY 4 bytes hex string)=" + BinaryConverter.bytesToHexString(messageKey)).append(",");
strBuf.append("1309=" + qualMessageQueue).append(",");
strBuf.append("1906=" + qualSubsystem);
if(keyValues.size() > 0){
Set set = keyValues.entrySet();
Iterator i = set.iterator();
while(i.hasNext()) {
Map.Entry me = (Map.Entry)i.next();
strBuf.append("," + me.getKey() + "=" + me.getValue());
}
}
return strBuf.toString();
}
}
File : SubsystemJobOpenList.java
///////////////////////////////////////////////////////////////////////////////
//
//
// Filename: SubsystemJobOpenList.java
//
// Author : Vengoal Chang
//
// Date : 2015/07/01
//
//
///////////////////////////////////////////////////////////////////////////////
package com.vengoal.as400.list;
import java.io.IOException;
import java.util.TreeMap;
import com.ibm.as400.access.AS400;
import com.ibm.as400.access.AS400Exception;
import com.ibm.as400.access.AS400SecurityException;
import com.ibm.as400.access.AS400Text;
import com.ibm.as400.access.BinaryConverter;
import com.ibm.as400.access.CharConverter;
import com.ibm.as400.access.ErrorCodeParameter;
import com.ibm.as400.access.ErrorCompletingRequestException;
import com.ibm.as400.access.Job;
import com.ibm.as400.access.ObjectDoesNotExistException;
import com.ibm.as400.access.ProgramCall;
import com.ibm.as400.access.ProgramParameter;
import com.ibm.as400.access.Trace;
import com.ibm.as400.access.list.OpenList;
/**
* Represents a list of subsystem jobs on the system with Open List of Jobs (QGYOLJOB) API.
* By default, following keys retrieved:
* keys_[0] = 305;
* keys_[1] = 601;
* keys_[2] = 602;
* keys_[3] = 1307;
* keys_[4] = 1308;
* keys_[5] = 1309;
* keys_[6] = 1906;
*
* List of Keys Supported for Format OLJB0300 reference:
* http://www-01.ibm.com/support/knowledgecenter/ssw_ibm_i_72/apis/qgyoljob.htm?lang=en
*
*/
public class SubsystemJobOpenList extends OpenList {
private String subsystem_;
private Job[] subsystemJobs_;
// Sort keys.
private int currentSortKey_ = 1;
// Info saved between calls to load() and getJobs().
private int numKeysReturned_;
private int[] keyFieldsReturned_;
private char[] keyTypesReturned_;
private int[] keyLengthsReturned_;
private int[] keyOffsetsReturned_;
// Keys to pre-load.
private int currentKey_ = 7;
private int[] keys_ = new int[currentKey_];
public SubsystemJobOpenList(AS400 system, String subsystem) {
super(system);
this.subsystem_ = subsystem;
// Figure out Job information default return key fields
keys_[0] = 305;
keys_[1] = 601;
keys_[2] = 602;
keys_[3] = 1307;
keys_[4] = 1308;
keys_[5] = 1309;
keys_[6] = 1906;
}
public void addJobAttributeToRetrieve(int attribute){
if (currentKey_ >= keys_.length){
// Resize.
int[] temp = keys_;
keys_ = new int[temp.length * 2];
System.arraycopy(temp, 0, keys_, 0, temp.length);
}
keys_[currentKey_++] = attribute;
}
public Job[] getSubsystemJobs(){
return subsystemJobs_;
}
@Override
protected byte[] callOpenListAPI() throws AS400SecurityException,
ErrorCompletingRequestException, InterruptedException, IOException,
ObjectDoesNotExistException {
if (Trace.isTraceOn()) Trace.log(Trace.DIAGNOSTIC, "Opening spooled file list.");
int lengthOfReceiverVariableDefinitionInformation = 4 + 20 * currentKey_;
byte[] keyOfFieldsToBeReturned = new byte[4 * currentKey_];
for (int i = 0; i < currentKey_; ++i)
{
BinaryConverter.intToByteArray(keys_[i], keyOfFieldsToBeReturned, i * 4);
}
// Figure out our sort information
byte[] sortInformation = new byte[4 + currentSortKey_ * 12];
BinaryConverter.intToByteArray(currentSortKey_, sortInformation, 0);
int fieldStartingPosition = 1;
int fieldLength = 10;
short dataType = (short)4;
BinaryConverter.intToByteArray(fieldStartingPosition, sortInformation, 4 );
BinaryConverter.intToByteArray(fieldLength, sortInformation, 8);
BinaryConverter.shortToByteArray(dataType, sortInformation, 12);
// Sort order 0xF1 = ascending, 0xF2 = descending.
sortInformation[14] = (byte)0xF1;
// Figure out our selection criteria.
byte[] jobSelectionInformation = new byte[206];
// Generate text objects based on system CCSID.
CharConverter conv = new CharConverter(system_.getCcsid(), system_);
for (int i = 0; i < 26; ++i) jobSelectionInformation[i] = 0x40;
String selectionJobName_ = "*ALL";
String selectionUserName_= "*ALL";
String selectionJobNumber_= "*ALL";
String selectionJobType_= "*";
conv.stringToByteArray(selectionJobName_.toUpperCase(), jobSelectionInformation, 0);
conv.stringToByteArray(selectionUserName_.toUpperCase(), jobSelectionInformation, 10);
conv.stringToByteArray(selectionJobNumber_, jobSelectionInformation, 20);
conv.stringToByteArray(selectionJobType_, jobSelectionInformation, 26);
int offset = 195;
int numberOfSubsystem = 1;
BinaryConverter.intToByteArray(offset, jobSelectionInformation, 76);
BinaryConverter.intToByteArray(numberOfSubsystem, jobSelectionInformation, 80);
// Subsystem name
AS400Text subsystemText = new AS400Text(10, system_);
byte[] subSystemBytes = subsystemText.toBytes(subsystem_);
System.arraycopy(subSystemBytes, 0, jobSelectionInformation, offset, 10);
offset += 10;
// Setup program parameters.
ProgramParameter[] parameters = new ProgramParameter[]
{
// Receiver variable, output, char(*).
new ProgramParameter(0),
// Length of receiver variable, input, binary(4).
new ProgramParameter(new byte[] { 0x00, 0x00, 0x00, 0x00 } ),
// Format name, input, char(8), EBCDIC 'OLJB0300'.
new ProgramParameter(new byte[] { (byte)0xD6, (byte)0xD3, (byte)0xD1, (byte)0xC2, (byte)0xF0, (byte)0xF3, (byte)0xF0, (byte)0xF0 } ),
// Receiver variable definition information, output, char(*).
new ProgramParameter(lengthOfReceiverVariableDefinitionInformation),
// Length of receiver variable definition information, input, binary(4).
new ProgramParameter(BinaryConverter.intToByteArray(lengthOfReceiverVariableDefinitionInformation)),
// List information, output, char(80).
new ProgramParameter(80),
// Number of records to return, input, binary(4).
// Special value '-1' indicates that "all records are built synchronously in the list".
new ProgramParameter(new byte[] { (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF } ),
// Sort information, input, char(*).
new ProgramParameter(sortInformation),
// Job selection information, input, char(*).
new ProgramParameter(jobSelectionInformation),
// Size of job selection information, input, binary(4).
new ProgramParameter(BinaryConverter.intToByteArray(jobSelectionInformation.length)),
// Number of fields to return, input, binary(4).
new ProgramParameter(BinaryConverter.intToByteArray(currentKey_)),
// Key of fields to be returned, input, array(*) of binary(4).
new ProgramParameter(keyOfFieldsToBeReturned),
// Error code, I/0, char(*).
new ErrorCodeParameter(),
// Job selection format name, input, char(8), EBCDIC 'OLJS0200'.
new ProgramParameter(new byte[] { (byte)0xD6, (byte)0xD3, (byte)0xD1, (byte)0xE2, (byte)0xF0, (byte)0xF2, (byte)0xF0, (byte)0xF0 } )
};
// Call the program.
ProgramCall pc = new ProgramCall(system_, "/QSYS.LIB/QGY.LIB/QGYOLJOB.PGM", parameters);
if (!pc.run())
{
throw new AS400Exception(pc.getMessageList());
}
// Key information returned.
byte[] defInfo = parameters[3].getOutputData();
numKeysReturned_ = BinaryConverter.byteArrayToInt(defInfo, 0);
keyFieldsReturned_ = new int[numKeysReturned_];
keyTypesReturned_ = new char[numKeysReturned_];
keyLengthsReturned_ = new int[numKeysReturned_];
keyOffsetsReturned_ = new int[numKeysReturned_];
offset = 4;
for (int i = 0; i < numKeysReturned_; ++i)
{
keyFieldsReturned_[i] = BinaryConverter.byteArrayToInt(defInfo, offset + 4);
keyTypesReturned_[i] = conv.byteArrayToString(defInfo, offset + 8, 1).charAt(0); // 'C' or 'B'
keyLengthsReturned_[i] = BinaryConverter.byteArrayToInt(defInfo, offset + 12);
keyOffsetsReturned_[i] = BinaryConverter.byteArrayToInt(defInfo, offset + 16);
offset += 20;
}
// List information returned.
return parameters[5].getOutputData();
}
@Override
protected Object[] formatOutputData(byte[] data, int recordsReturned, int recordLength)
throws AS400SecurityException, ErrorCompletingRequestException,
InterruptedException, IOException, ObjectDoesNotExistException {
int number = recordsReturned; // request entire list
CharConverter conv = new CharConverter(system_.getCcsid(), system_);
SubsystemJobListItem[] listItems = new SubsystemJobListItem[number];
subsystemJobs_ = new Job[number];
String currentUser = null;
String functionName = null;
String functionType = null;
String messageReply = null;
byte[] messageKey = null;
String qualMessageQueue = null;
String qualSubsystem = null;
TreeMap keyValues = new TreeMap();
for (int i = 0, offset = 0; i < listItems.length; ++i, offset += recordLength)
{
String jobName = conv.byteArrayToString(data, offset, 10);
String jobUser = conv.byteArrayToString(data, offset + 10, 10);
String jobNumber = conv.byteArrayToString(data, offset + 20, 6);
String status = conv.byteArrayToString(data, offset + 26, 4);
String jobType = conv.byteArrayToString(data, offset + 30, 1);
String jobSubtype = conv.byteArrayToString(data, offset + 31, 1);
for (int j = 0; j < numKeysReturned_; ++j)
{
int keyOffset = keyOffsetsReturned_[j];
if (keyTypesReturned_[j] == 'C')
{
String value = conv.byteArrayToString(data, offset + keyOffset, keyLengthsReturned_[j]);
if(keyFieldsReturned_[j] == 305 ) currentUser = value;
if(keyFieldsReturned_[j] == 601 ) functionName = value;
if(keyFieldsReturned_[j] == 602 ) functionType = value;
if(keyFieldsReturned_[j] == 1307) messageReply = value;
if(keyFieldsReturned_[j] == 1309) qualMessageQueue = value;
if(keyFieldsReturned_[j] == 1906) qualSubsystem = value;
if(keyFieldsReturned_[j] == 1308)
{
byte[] msgKey = new byte[4];
System.arraycopy(data, offset + keyOffset, msgKey, 0, 4);
messageKey = msgKey;
}
if(j > 6){
if(keyFieldsReturned_[j] == 312 || keyFieldsReturned_[j] == 313 ||
keyFieldsReturned_[j] == 315 || keyFieldsReturned_[j] == 317 ||
keyFieldsReturned_[j] == 414 || keyFieldsReturned_[j] == 415 ||
keyFieldsReturned_[j] == 416 || keyFieldsReturned_[j] == 417 ||
keyFieldsReturned_[j] == 1609)
keyValues.put(keyFieldsReturned_[j], new Long(BinaryConverter.byteArrayToLong(data, offset + keyOffset))) ;
else
keyValues.put(keyFieldsReturned_[j], value) ;
}
}
else
{
if ((keyFieldsReturned_[j] == Job.TEMP_STORAGE_USED_LARGE))
keyValues.put(keyFieldsReturned_[j], new Long(BinaryConverter.byteArrayToUnsignedInt(data, offset + keyOffset))) ;
else
keyValues.put(keyFieldsReturned_[j], new Integer(BinaryConverter.byteArrayToInt(data, offset + keyOffset))) ;
}
}
listItems[i] = new SubsystemJobListItem(jobName, jobUser, jobNumber,
status, jobType,jobSubtype, currentUser, functionName, functionType,
messageReply, messageKey, qualMessageQueue, qualSubsystem);
subsystemJobs_[i] = new Job(this.getSystem(), jobName, jobUser, jobNumber);
listItems[i].setKeyValues(keyValues);
}
return listItems;
}
@Override
protected int getBestGuessReceiverSize(int number) {
return 300 * number;
}
}
File : SubsystemJobOpenListTest.java
//////////////////////////////////////////////////////////////////////////////
//
//
// Filename: SubsystemJobOpenListTest.java
//
// Author : Vengoal Chang
//
// Date : 2015/07/01
//
//
///////////////////////////////////////////////////////////////////////////////
package com.vengoal.as400.list;
import java.util.Enumeration;
import com.ibm.as400.access.AS400;
import com.ibm.as400.access.CallStackEntry;
import com.ibm.as400.access.Job;
import com.vengoal.as400.common.MessageUtil;
public class SubsystemJobOpenListTest {
public static void main(String[] args) {
AS400 as400 = new AS400("as400ip", "user", "pass");
String subsystem = "QBATCH";
SubsystemJobOpenList list = new SubsystemJobOpenList(as400, subsystem);
list.addJobAttributeToRetrieve(SubsystemJobListItem.MEMORY_POOL);
list.addJobAttributeToRetrieve(SubsystemJobListItem.RUN_PRIORITY);
list.addJobAttributeToRetrieve(SubsystemJobListItem.DATE_ENTERED_SYSTEM);
list.addJobAttributeToRetrieve(SubsystemJobListItem.JOB_LOG_PENDING);
list.addJobAttributeToRetrieve(SubsystemJobListItem.JOB_TYPE_ENHANCED);
list.addJobAttributeToRetrieve(SubsystemJobListItem.SPOOLED_FILE_ACTION);
list.addJobAttributeToRetrieve(SubsystemJobListItem.THREAD_COUNT);
list.addJobAttributeToRetrieve(SubsystemJobListItem.CPU_TIME_USED_LARGE);
list.addJobAttributeToRetrieve(SubsystemJobListItem.ELAPSED_CPU_PERCENT_USED);
list.addJobAttributeToRetrieve(SubsystemJobListItem.ELAPSED_CPU_TIME_USED);
list.addJobAttributeToRetrieve(SubsystemJobListItem.ELAPSED_PAGE_FAULTS);
list.addJobAttributeToRetrieve(SubsystemJobListItem.DISK_IO);
list.addJobAttributeToRetrieve(SubsystemJobListItem.ELAPSED_DISK_IO_ASYNCH);
list.addJobAttributeToRetrieve(SubsystemJobListItem.ELAPSED_DISK_IO_SYNCH);
try {
list.open();
Enumeration items = list.getItems();
while (items.hasMoreElements())
{
SubsystemJobListItem item = (SubsystemJobListItem)items.nextElement();
System.out.println(item);
if(item.getMessageReply().equalsIgnoreCase(Job.MESSAGE_REPLY_WAITING)){
System.out.println(MessageUtil.getErrMsgTxtWithAPI(as400, item.getMessageKey(), item.getQualMessageQueue()));
Job msgwJob = new Job(as400, item.getJobName(), item.getJobUser(), item.getJobNumber());
CallStackEntry[] callstackEntry = msgwJob.getCallStack(Job.INITIAL_THREAD);
System.out.println("job call stack as following:");
for(int i = 0; i< callstackEntry.length; ++i){
//System.out.println(callstackEntry[i].getProgramLibrary() + "/" + callstackEntry[i].getProgramName() + " " + callstackEntry[i].getProcedureName());
}
}
System.out.println("Spooled file action=" + item.getObject(SubsystemJobListItem.SPOOLED_FILE_ACTION));
System.out.println("====================================");
}
Job[] subsystemJobs = list.getSubsystemJobs();
if(subsystemJobs != null){
for(int i =0; i < subsystemJobs.length; ++i){
// do your work related job
System.out.println(subsystemJobs[i].getNumber() + "/" + subsystemJobs[i].getUser() + "/" + subsystemJobs[i].getName());
}
} else {
System.out.println("Subsystem " + subsystem + " is inactive or not exist");
}
list.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
參照: Open List of Jobs (QGYOLJOB) API
2015-06-08 如何讓 WRKACTJOB 畫面中欄位 Function 更容易明瞭?(Command CHGFUNCNAM -- Change Function Name with QWCCCJOB Change Current Job API)
如何讓 WRKACTJOB 畫面中欄位 Function 更容易明瞭?(Command CHGFUNCNAM -- Change Function Name with QWCCCJOB Change Current Job API)
File : QCLSRC
Member: CHGFUNCNAM
Type : CLP
Usage : CRTCLPGM PGM(CHGFUNCNAM)
/*-------------------------------------------------------------------*/
/* */
/* Program . . : CHGFUNCNAM */
/* Description : Change function name */
/* with Change Current Job (QWCCCJOB) API */
/* which support change function name from V6R1 */
/* Author . . : Vengoal Chang */
/* Published . : AS400ePaper */
/* Date . . . : June 8, 2015 */
/* */
/* */
/* Program function: Change function name command allows you to */
/* change the description of the Function field */
/* on WRKACTJOB to provide a better description */
/* of what a job is doing. */
/* */
/* The value on WRKACTJOB would appear as */
/* USR-xxxx where xxxx is the 10 bytes specified */
/* on CHGFUNCNAM. */
/* */
/* This program expects a single parameter */
/* specifying the function name. */
/* */
/* */
/* Compile options: */
/* CrtClPgm Pgm( CHGFUNCNAM ) */
/* SrcFile( QCLSRC ) */
/* SrcMbr( *PGM ) */
/* */
/*-------------------------------------------------------------------*/
Pgm &FuncName
Dcl &FuncName *Char 10
Dcl &ChgInf *Char 22
MonMsg CPF0000 *N GoTo Error
ChgVar %Bin( &ChgInf 1 4 ) 1
ChgVar %Bin( &ChgInf 5 4 ) 3 /* Function name */
ChgVar %Bin( &ChgInf 9 4 ) 10 /* 10 byte */
Chgvar %Sst( &ChgInf 13 10 ) &FuncName
Call QWCCCJOB ( &ChgInf x'0000000000000000' )
Return
/*-- Error handling: -----------------------------------------------*/
Error:
Call QMHMOVPM ( ' ' +
'*DIAG' +
x'00000001' +
'*PGMBDY' +
x'00000001' +
x'0000000800000000' +
)
Call QMHRSNEM ( ' ' +
x'0000000800000000' +
)
EndPgm:
EndPgm
File : QCMDSRC
Member: CHGFUNCNAM
Type : CMD
Usage : CrtCmd Cmd( CHGFUNCNAM )
Pgm( CHGFUNCNAM )
SrcFile( YourSourceFile )
Allow( *IPgm *BPgm )
/* =============================================================== */
/* = Command....... ChgFuncNam = */
/* = CPP........... ChgfuncNam CLP = */
/* = Description... Change Function Name = */
/* = = */
/* = = */
/* = CrtCmd Cmd( ChgFuncNam ) = */
/* = Pgm( ChgFuncNam ) = */
/* = SrcFile( YourSourceFile ) = */
/* = Allow( *IPgm *BPgm ) = */
/* =============================================================== */
/* = Date : 2015/06/08 = */
/* = Author: Vengoal Chang = */
/* =============================================================== */
Cmd Prompt('Change Function Name')
Parm FuncName *Char 10 +
Prompt('Function name')
File : QCLSRC
Member: CHGFUNCTST
Type : CLLE
Usage : CrtCmd Cmd( CHGFUNCTST )
Pgm( CHGFUNCTST )
SrcFile( YourSourceFile )
SbmJob Cmd( Call CHGFUNCTST)
Job( CHGFUNCTST )
WRKACTJOB press F10 see the job CHGFUNCTST Function name
will change STEP1, STEP2, STEP1, STEP2 ...
/*-------------------------------------------------------------------*/
/* */
/* Program . . : CHGFUNCTST */
/* Description : Change function name Test */
/* Author . . : Vengoal Chang */
/* Published . : AS400ePaper */
/* Date . . . : June 8, 2015 */
/* */
/* */
/* Program function: Change function name command test */
/* */
/* */
/* Compile options: */
/* CrtBndCl Pgm( CHGFUNCTST ) */
/* SrcFile( QCLSRC ) */
/* SrcMbr( *PGM ) */
/* */
/*-------------------------------------------------------------------*/
Pgm
Dcl &SleepSec *Int
ChgVar &SleepSec 1
Loop:
ChgFuncNam FuncName(STEP1)
CallPrc PRC('sleep') Parm((&SleepSec *ByVal))
ChgFuncNam FuncName(STEP2)
CallPrc PRC('sleep') Parm((&SleepSec *ByVal))
Goto Loop
EndPgm
參照: Change Current Job (QWCCCJOB) API
訂閱:
文章 (Atom)