ジョブ情報を検索するのであれば API を使わなくてもコマンド RTVJOBA を
使えば十分ではないかと諸兄は考えるかも知れないが、実は RTVJOBA を
うかつに信用してしまうと、とんでもないことになる場合がある。
実は、
のである。
例えばバッチ・ジョブや他のジョブの情報を RTVJOBA コマンドを使って
のように検索したいとする。
指定したジョブの情報が得られるかと思いきや、実は戻り値として戻ってくるのは
指定したジョブではなくて、この RTVJOBA コマンドを実行した自分自身のジョブの
情報が戻ってくるだけである。
これには長い間気づかなかった。
指定したジョブ情報を正しく取得するには API: QUSRJOBI を使って検索しなければならない。
次は API: QUSRJOBI を使って RTVJOBA と同じ情報を戻す C/400 のサンプルである。
0001.00 #include <stdio.h>
0002.00 #include <stdlib.h>
0003.00 #include <string.h>
0004.00 #include <qusrjobi.h>
0005.00 #include <decimal.h>
0006.00 #include <QMHRTVM.h>
0007.00
0008.00 #define TRUE 0
0009.00 #define FALSE -1
0010.00 #define ID_LEN 16
0011.00 typedef struct {
0012.00 char job[10];
0013.00 char user[10];
0014.00 char jobnbr[6];
0015.00 } JOBINFO;
0016.00 JOBINFO jobinfo;
0017.00 typedef struct {
0018.00 int BYTESPRO;
0019.00 int BYTESAVL;
0020.00 char MSGID[7];
0021.00 char RESRVD;
0022.00 char EXCPDATA[100];
0023.00 } ERRSTRUCTURE; /* Define the error return structure */
0024.00 ERRSTRUCTURE errcode;/* Error Code Structure for RCVMSG */
0025.00
0026.00 /*************************************************************/
0027.00 /* 内 部 使 用 関 数 */
0028.00 /*************************************************************/
0029.00 void GetParam(int argc, char *argv[]);
0030.00 void INZSR(void);
0031.00 void ApiError(char* place, int stmno, ERRSTRUCTURE* errcode, char* pgm);
0032.00 /*************************************************************/
0033.00 /* グ ロ ー バ ル 変 数 */
0034.00 /*************************************************************/
0035.00 char job[11], user[11], jobnbr[7], outq[11], outqlib[11], date[8];
0036.00 char type[2], prtdev[11], langid[4], cntryid[3], ccsid[6];
0037.00 char dftccsid[6], cymddate[9], sbmmsgq[11], sbmmsgqlib[11];
0038.00 char jobid[ID_LEN], ascnbr[7], m_ccsid[6];
0039.00 decimal(5, 0) dftCCSID, CCSID;
0040.00
0041.00 int main(int argc, char *argv[]){
0042.00 Qwc_JOBI0300_t jobi0300;
0043.00 Qwc_JOBI0400_t jobi0400;
0044.00 char jobid[16];
0045.00
0046.00 GetParam(argc, argv); /*[ パラメータの取得 ]*/
0047.00 INZSR(); /*[ 初期設定 ]*/
0048.00
0049.00 memset(jobid, ' ', sizeof(jobid));
0050.00 QUSRJOBI(&jobi0300, sizeof(Qwc_JOBI0300_t), "JOBI0300", &jobinfo,
0051.00 jobid, &errcode);
0052.00 if(errcode.BYTESAVL != 0){/* APIERR */
0053.00 ApiError("QUSRJOBI", __LINE__, &errcode, "VT5250"); exit(-1);
0054.00 }/* APIERR */
0055.00 memcpy(jobid, jobi0300.Int_Job_ID, 16);
0056.00 memcpy(outq, jobi0300.Outq_Name, 10);
0057.00 outq[10] = 0x00;
0058.00 memcpy(outqlib, jobi0300.Outq_Lib, 10);
0059.00 outqlib[10] = 0x00;
0060.00 memcpy(date, jobi0300.Job_Date, 7);
0061.00 date[7] = 0x00;
0062.00 memcpy(prtdev, jobi0300.Prt_Dev_Name, 10);
0063.00 prtdev[10] = 0x00;
0064.00 memcpy(sbmmsgq, jobi0300.Subm_Msgq_Name, 10);
0065.00 sbmmsgq[10] = 0x00;
0066.00 memcpy(sbmmsgqlib, jobi0300.Subm_Msgq_Lib, 10);
0067.00 sbmmsgqlib[10] = 0x00;
0068.00 memcpy(cymddate, jobi0300.Date_Put_On_Jobq, 8);
0069.00 cymddate[8] = 0x00;
0070.00 memset(&jobinfo, ' ', sizeof(jobinfo));
0071.00 memcpy(jobinfo.job, "*INT ", 10);
0072.00 QUSRJOBI(&jobi0400, sizeof(Qwc_JOBI0400_t), "JOBI0400", &jobinfo,
0073.00 jobid, &errcode);
0074.00 if(errcode.BYTESAVL != 0){/* APIERR */
0075.00 ApiError("QUSRJOBI", __LINE__, &errcode, "VT5250"); exit(-1);
0076.00 }/* APIERR */
0077.00 memcpy(langid, jobi0400.Language_ID, 3);
0078.00 langid[3] = 0x00;
0079.00 memcpy(cntryid, jobi0400.Country_ID, 2);
0080.00 cntryid[2] = 0x00;
0081.00 if(jobi0400.Job_Type[0] == 'B') strcpy(type, "0");
0082.00 else strcpy(type, "1");
0083.00 sprintf(ccsid, "%05d", jobi0400.Coded_Char_Set_ID);
0084.00 CCSID = (decimal(5, 0))jobi0400.Coded_Char_Set_ID;
0085.00 sprintf(dftccsid, "%05d", jobi0400.Default_Coded_Char_Set_Id);
0086.00 dftCCSID = (decimal(5, 0))jobi0400.Default_Coded_Char_Set_Id;
0087.00
0088.00 strcpy(argv[1], job);
0089.00 strcpy(argv[2], user);
0090.00 strcpy(argv[3], jobnbr);
0091.00 strcpy(argv[4], outq);
0092.00 strcpy(argv[5], outqlib);
0093.00 strcpy(argv[6], date);
0094.00 strcpy(argv[7], type);
0095.00 strcpy(argv[8], prtdev);
0096.00 strcpy(argv[9], langid);
0097.00 strcpy(argv[10], cntryid);
0098.00 memcpy(argv[11], &CCSID, 3);
0099.00 memcpy(argv[12], &dftCCSID, 3);
0100.00 strcpy(argv[13], cymddate);
0101.00 strcpy(argv[14], sbmmsgq);
0102.00 strcpy(argv[15], sbmmsgqlib);
0103.00 return;
0104.00 }
0105.00 /*************************************/
0106.00 void GetParam(int argc, char *argv[])
0107.00 /*************************************/
0108.00 {
0109.00 memcpy(job, argv[1], 10);
0110.00 job[10] = 0x00;
0111.00 memcpy(user, argv[2], 10);
0112.00 user[10] = 0x00;
0113.00 memcpy(jobnbr, argv[3], 6);
0114.00 jobnbr[6] = 0x00;
0115.00 }
0116.00 /****************/
0117.00 void INZSR(void)
0118.00 /****************/
0119.00 {
0120.00 errcode.BYTESPRO = sizeof(errcode);
0121.00 errcode.BYTESAVL = 0;
0122.00 }
0123.00 /*********************************************************************/
0124.00 void ApiError(char* place, int stmno, ERRSTRUCTURE* errcode, char* pgm)
0125.00 /*********************************************************************/
0126.00 {
0127.00 char msgid[8], msgf[11], msgflib[11], msgdta[101], Message[512];
0128.00 int msglen, msgdtalen, pos, strpos = FALSE;
0129.00 char* ptr;
0130.00 typedef struct {
0131.00 Qmh_Rtvm_RTVM0100_t rtvm0100;
0132.00 char msg[512];
0133.00 } ERRMSG;
0134.00 ERRMSG errmsg;
0135.00
0136.00 memcpy(msgid, errcode->MSGID, 7);
0137.00 msgid[7] = 0x00;
0138.00 if(msgid[0] == 0x00 || msgid[0] == ' '){/*msgid なし */
0139.00 perror("APIERROR");
0140.00 printf(" at %s, STMNO=%d\n", place, stmno);
0141.00 getchar();
0142.00 return;
0143.00 }/*msgid なし */
0144.00 memcpy(msgdta, errcode->EXCPDATA, 100);
0145.00 msgdta[100] = 0x00;
0146.00 msglen = sizeof(ERRMSG);
0147.00 msgdtalen = strlen(msgdta);
0148.00 memset(&errmsg, 0, sizeof(ERRMSG));
0149.00 QMHRTVM(&errmsg, msglen, "RTVM0100", msgid, "QCPFMSG *LIBL ",
0150.00 msgdta, msgdtalen, "*YES ", "*YES ", errcode);
0151.00 memset(Message, 0, sizeof(Message));
0152.00 memcpy(Message, errmsg.msg, 512);
0153.00 ptr = strstr(Message, "&N");
0154.00 while(ptr != NULL){/*while*/
0155.00 pos = (int)(ptr - Message);
0156.00 if(strpos == FALSE) strpos = pos;
0157.00 Message[pos] = 0x15; pos ++;
0158.00 Message[pos] = ' ';
0159.00 ptr = strstr(&Message[pos], "&N");
0160.00 }/*while*/
0161.00 if(strpos != FALSE) Message[strpos] = 0x00;
0162.00 printf("PGM-%s:APIERR %s-%s\n", pgm, msgid, Message);
0163.00 printf(" AT %s, STMNO=%d\n", place, stmno);
0164.00 printf(" MSGDTA =%s\n", msgdta);
0165.00 }
API: QUSRJOBI の JOBI0300 と JOBI0400 の2つの機能による呼び出しによって
コマンド : RTVJOBA と同じ機能を再現しようととているのであるが
0081.00 if(jobi0400.Job_Type[0] == 'B') strcpy(type, "0"); 0082.00 else strcpy(type, "1");
にも注意して頂きたい。API: QUSRJOBI による実行ジョブのタイプを取得すると
バッチ・ジョブの場合は「B」が入り、対話式ジョブの場合は「I」が入る。
これに対して RTVJOBA コマンドの場合は、バッチ・ジョブの場合は「0」が入り、
対話式ジョブの場合は「1」が入る。
従って QUSRJOBI の戻り値をうっかりそのまま信用してしまうと、ここでも
「落とし穴」にはまってしまうようである。
使用頻度が最も高いと思われる RTVJOBA コマンドには、このように
いくつもの盲点が潜んでいる。自分自身のジョブしか検索することはできない、とは
IBM マニュアルのどこにも書かれていないので、これはバグと言えるものでは
ないだろうか。