Tools

25. コマンド・ソースを検索する RTVCMDSRC

CLP に対しては RTVCLSRC(*YES) でコンパイルしておくと、RTVCLSRC によって元のCLPソースを
生成できることは良く知られているが コマンドに対する RTVCMDSRC なるものはこれまでなかった。
コマンドを自作するときに OS400 のコマンドはどのようにして作成されているのかを
知りたいと思ったことはないだろうか ?
そこで禁断のコマンド・ソースを検索する RTVCMDSRC を紹介しよう。
RTVCMDSRC は、どのようなコマンドに対しても元のソースを生成するリバース・エンジニアリング機能を
提供する。そんなことができるとは大抵の人は思っていないだろう。
もちろん System i で提供されている OS400 のコマンドであっても、弊社製品のコマンドであっても
コマンド・オブジェクトから元のソースを生成することができる。

今回、紹介する手法はあくまでも学習用にして頂くためのものと考えて欲しい。
コマンド・ソースを検索したからといってオブジェクトのプロバイダーにとって大きな問題となることは
ないだろうと判断して紹介することにした。

【 コマンド: RTVCMDSRC 】
----------------------------------------------------------------------------------------
0001.00              CMD        PROMPT(' コマンド・ソース検索 ')                        
0002.00              PARM       KWD(CMD) TYPE(CMD) MIN(1) PROMPT(' コマンド ')          
0003.00              PARM       KWD(SRCFILE) TYPE(SRC) +                                
0004.00                           PROMPT(' ソース・ファイル ')                          
0005.00              PARM       KWD(SRCMBR) TYPE(*NAME) DFT(*CMD) +                     
0006.00                           SPCVAL((*CMD)) PROMPT(' ソース・メンバー ')           
0007.00              PARM       KWD(PROMPT) TYPE(*CHAR) LEN(5) RSTD(*YES) +             
0008.00                           DFT(*TEXT) SPCVAL((*TEXT) (*MSG)) +                   
0009.00                           PROMPT(' プロンプト・テキスト OR MSGID')              
0010.00  CMD:        QUAL       TYPE(*NAME) LEN(10)                                     
0011.00              QUAL       TYPE(*NAME) LEN(10) DFT(*LIBL) +                        
0012.00                           SPCVAL((*LIBL) (*CURLIB)) +                           
0013.00                           PROMPT(' ライブラリー ')                              
0014.00  SRC:        QUAL       TYPE(*NAME) LEN(10) +                                   
0015.00                           DFT(QCMDSRC)                                          
0016.00              QUAL       TYPE(*NAME) LEN(10) DFT(*LIBL) +                        
0017.00                           SPCVAL((*LIBL) (*CURLIB)) +                           
0018.00                           PROMPT(' ライブラリー ')                              
0019.00              PARM       KWD(COMPILE) TYPE(*CHAR) LEN(4) RSTD(*YES) +            
0020.00                           DFT(*NO) VALUES(*YES *NO) PMTCTL(*PMTRQS) +           
0021.00                           PROMPT(' コンパイル・テキスト ')                      
----------------------------------------------------------------------------------------
【 コンパイル 】
CRTCMD CMD(MYLIB/RTVCMDSRC) PGM(MYLIB/RTVCMDSRCC) SRCFILE(MYSRCLIB/QCMDSR) AUT(*ALL)
【 実行CPP-CLP 】
--------------------------------------------------------------------------------------
0001.00              PGM        PARM(&CMDLIB &OFILLIB &OMBR &TXT &COMPILE)         
0002.00 /*---------------------------------------------------------*/              
0003.00 /*   RTVCMDSRCC  :   コマンド・ソース検索                  */              
0004.00 /*---------------------------------------------------------*/              
0005.00              DCL        VAR(&CMDLIB) TYPE(*CHAR) LEN(20)                   
0006.00              DCL        VAR(&OFILLIB) TYPE(*CHAR) LEN(20)                  
0007.00              DCL        VAR(&OMBR) TYPE(*CHAR) LEN(10)                     
0008.00              DCL        VAR(&TXT) TYPE(*CHAR) LEN(5)                       
0009.00              DCL        VAR(&COMPILE) TYPE(*CHAR) LEN(4)                   
0010.00                                                                            
0011.00              DCL        VAR(&CMDNM) TYPE(*CHAR) LEN(10)                    
0012.00              DCL        VAR(&CMDLI) TYPE(*CHAR) LEN(10)                    
0013.00              DCL        VAR(&MCMDLIB) TYPE(*CHAR) LEN(20)                  
0014.00              DCL        VAR(&OFILE) TYPE(*CHAR) LEN(10)                    
0015.00              DCL        VAR(&OLIBR) TYPE(*CHAR) LEN(10)                    
0016.00              DCL        VAR(&CURLIB) TYPE(*CHAR) LEN(10)                   
0017.00              DCL        VAR(&MSGORTXT) TYPE(*CHAR) LEN(2) VALUE('-M')      
0018.00              DCL        VAR(&CMDTEXT) TYPE(*CHAR) LEN(50)                  
0019.00              DCL        VAR(&LIN) TYPE(*CHAR) LEN(132)                     
0020.00              DCL        VAR(&USNAMLIB) TYPE(*CHAR) LEN(20)                 
0021.00              DCL        VAR(&PROTOS) TYPE(*CHAR) LEN(10) +                 
0022.00                           VALUE('RTVCMDS')                                 
0023.00              DCL        VAR(&USRSPC) TYPE(*CHAR) LEN(10) +                 
0024.00                           VALUE('RTVCMDSPC')                         
0025.00                                                                      
0026.00              DCL        VAR(&ERRORSW) TYPE(*LGL)                     
0027.00              DCL        VAR(&EMSGID) TYPE(*CHAR) LEN(7)              
0028.00              DCL        VAR(&EMSGDTA) TYPE(*CHAR) LEN(100)           
0029.00              DCL        VAR(&EMSGF) TYPE(*CHAR) LEN(10)              
0030.00              DCL        VAR(&EMSGFLIB) TYPE(*CHAR) LEN(10)           
0031.00              DCL        VAR(&OS400) TYPE(*CHAR) LEN(6)               
0032.00              DCL        VAR(&APIERR) TYPE(*CHAR) LEN(4) +            
0033.00                           VALUE(X'00000000') /* 2 進数  */           
0034.00              DCL        VAR(&INZSIZ) TYPE(*CHAR) LEN(4)              
0035.00              MONMSG     MSGID(CPF0000) EXEC(GOTO CMDLBL(ERROR))      
0036.00                                                                      
0037.00              RTVDTAARA  DTAARA(QGPL/QSS1MRI (1 6)) RTNVAR(&OS400)    
0038.00              RTVJOBA    CURLIB(&CURLIB)                              
0039.00              CHGVAR     VAR(&CMDNM) VALUE(%SST(&CMDLIB 1 10))        
0040.00              CHGVAR     VAR(&CMDLI) VALUE(%SST(&CMDLIB 11 10))       
0041.00              CHGVAR     VAR(&OFILE) VALUE(%SST(&OFILLIB 1 10))       
0042.00              CHGVAR     VAR(&OLIBR) VALUE(%SST(&OFILLIB 11 10))      
0043.00                                                                      
0044.00 /*------------------------------------------------*/                 
0045.00      IF (&OMBR = *DUMPCMD) THEN(GOTO DUMPCMD)                        
0046.00 /*------------------------------------------------*/                 
0047.00                                                                      
0048.00      IF COND(&TXT = *TEXT) THEN(CHGVAR VAR(&MSGORTXT) VALUE('-T'))        
0049.00      IF COND(&OMBR = *CMD) THEN(CHGVAR VAR(&OMBR) VALUE(&CMDNM))          
0050.00                                                                           
0051.00      IF COND(&CMDLI *EQ *CURLIB) THEN(DO)                                 
0052.00        IF COND(&CURLIB *EQ *NONE) THEN(CHGVAR VAR(&CMDLI) VALUE(QGPL))    
0053.00          ELSE CMD(CHGVAR VAR(&CMDLI) VALUE(&CURLIB))                      
0054.00      ENDDO                                                                
0055.00                                                                           
0056.00      CHGVAR VAR(%SST(&MCMDLIB 1 10)) VALUE(&CMDNM)                        
0057.00      CHGVAR VAR(%SST(&MCMDLIB 11 10)) VALUE(&CMDLI)                       
0058.00                                                                           
0059.00      IF COND(&OLIBR *EQ *CURLIB) THEN(DO)                                 
0060.00        IF COND(&CURLIB *EQ *NONE) THEN(CHGVAR VAR(&OLIBR) VALUE(QGPL))    
0061.00          ELSE CMD(CHGVAR VAR(&OLIBR) VALUE(&CURLIB))                      
0062.00      ENDDO                                                                
0063.00                                                                           
0064.00 /* コマンドの権限を検査 */                                                
0065.00      CHKOBJ OBJ(&CMDLI/&CMDNM) OBJTYPE(*CMD) AUT(*USE)                    
0066.00      RTVOBJD OBJ(&CMDLI/&CMDNM) OBJTYPE(*CMD) TEXT(&CMDTEXT)              
0067.00                                                                           
0068.00 /* ソース・ファイルの使用権限を検査  */                                   
0069.00      CHKOBJ OBJ(&OLIBR/&OFILE) OBJTYPE(*FILE) AUT(*CHANGE)                
0070.00                                                                           
0071.00 /* ソース・タイプ CMD をコピー */                                         
0072.00      RMVM FILE(&OLIBR/&OFILE) MBR(&OMBR)                                      
0073.00      MONMSG MSGID(CPF0000)                                                    
0074.00              CPYF       FROMFILE(ASNET.COM/&PROTOS) +                         
0075.00                           TOFILE(&OLIBR/&OFILE) FROMMBR(CMD) +                
0076.00                           TOMBR(&OMBR) MBROPT(*REPLACE) FMTOPT(*NOCHK)        
0077.00      MONMSG MSGID(CPF0000)                                                    
0078.00      CLRPFM FILE(&OLIBR/&OFILE) MBR(&OMBR)                                    
0079.00      MONMSG MSGID(CPF0000)                                                    
0080.00      CHGPFM FILE(&OLIBR/&OFILE) MBR(&OMBR) TEXT(&CMDTEXT)                     
0081.00                                                                               
0082.00 /* ユーザー・スペースにコピー */                                              
0083.00      DLTUSRSPC USRSPC(QTEMP/&USRSPC)                                          
0084.00      MONMSG MSGID(CPF0000)                                                    
0085.00              IF         COND(&OS400 *GE 'V5R3M0') THEN(DO) /* +               
0086.00                           V5R3M0 以上ダンプ  */                               
0087.00              CHGVAR     VAR(%BIN(&INZSIZ)) VALUE(32767)                       
0088.00              CALL       PGM(QUSCRTUS) PARM('RTVCMDSPC QTEMP     ' +           
0089.00                           'PF        ' &INZSIZ X'00' '*ALL      ' +           
0090.00                           'RTVCMDSRC 用ユーザー空間 ' '*YES      ' +          
0091.00                           &APIERR)                                            
0092.00              MONMSG     CPF9870                                               
0093.00              CALL       PGM(ASNET.COM/RTVCMDSRCC) PARM(&CMDLIB +              
0094.00                           &OFILLIB *DUMPCMD &TXT &COMPILE)                    
0095.00              ENDDO      /* V5R3M0 以上ダンプ  */                              
0096.00              ELSE       CMD(DO) /* V5R2M0 以下は MI */               
0097.00              CALL       PGM(ASNET.COM/RTVCMDM) PARM(&MCMDLIB)        
0098.00              ENDDO      /* V5R2M0 以下は MI */                       
0099.00                                                                      
0100.00 /*  コマンド・ソースの検索 */                                        
0101.00              OVRDBF     FILE(SRC) TOFILE(&OLIBR/&OFILE) MBR(&OMBR) + 
0102.00                           SECURE(*YES) OVRSCOPE(*JOB)                
0103.00      CALL PGM(ASNET.COM/RTVCMD) PARM( +                              
0104.00        '-N'  &CMDNM +                                                
0105.00        '-L'  &CMDLI +                                                
0106.00        '-SF' &OFILE +                                                
0107.00        '-SL' &OLIBR +                                                
0108.00        '-SM' &OMBR +                                                 
0109.00        '-X'  &CMDTEXT +                                              
0110.00        '-C'  &COMPILE +                                              
0111.00              &MSGORTXT)                                              
0112.00                                                                      
0113.00   /* CALL       PGM(ASNET.COM/ADDLBL)     ラベルを訂正 */            
0114.00              DLTOVR     FILE(SRC) LVL(*JOB)                          
0115.00      DLTUSRSPC USRSPC(QTEMP/&USRSPC)                                 
0116.00      MONMSG MSGID(CPF0000)                                           
0117.00      DLTF FILE(QTEMP/RTVCMDSF)                                       
0118.00      MONMSG MSGID(CPF0000)                                           
0119.00      RCLRSC              
0120.00      MONMSG MSGID(CPF0000)                                          
0121.00      RMVMSG PGMQ(*ALLINACT) CLEAR(*ALL)                             
0122.00      RMVMSG CLEAR(*ALL)                                             
0123.00              SNDPGMMSG  MSG(' コマンド ' *CAT &CMDLI *TCAT '/' +    
0124.00                           *CAT &CMDNM *TCAT +                       
0125.00                           ' のソースを検索しました ') MSGTYPE(*DIAG)
0126.00      GOTO CMDLBL(ENDPGM)                                            
0127.00 /*------------------------------------*/                            
0128.00 /*   コマンド・オブジェクトのダンプ   */                            
0129.00 /*------------------------------------*/                            
0130.00 DUMPCMD:                                                            
0131.00              CRTPF      FILE(QTEMP/RTVCMDSF) RCDLEN(132) +          
0132.00                           IGCDTA(*YES) SIZE(*NOMAX)                 
0133.00      MONMSG MSGID(CPF7302) EXEC(DO)                                 
0134.00        CLRPFM FILE(QTEMP/RTVCMDSF)                                  
0135.00      ENDDO                                                          
0136.00              OVRPRTF    FILE(QPSRVDMP) HOLD(*YES) LVLCHK(*NO) +     
0137.00                           SECURE(*YES) OVRSCOPE(*JOB)               
0138.00      DMPOBJ OBJ(&CMDLI/&CMDNM) OBJTYPE(*CMD)                        
0139.00              DLTOVR     FILE(QPSRVDMP) LVL(*JOB)                    
0140.00      CPYSPLF FILE(QPSRVDMP) TOFILE(QTEMP/RTVCMDSF) +                
0141.00        SPLNBR(*LAST)                                                
0142.00      DLTSPLF FILE(QPSRVDMP) SPLNBR(*LAST)                           
0143.00                                                                     
0144.00 /*  スプールをユーザー・スペースへコピー */                                 
0145.00      CHGVAR VAR(&USNAMLIB) VALUE(&OFILLIB)                                  
0146.00              CHGVAR     VAR(&USNAMLIB) VALUE('RTVCMDSPC QTEMP     ') +      
0147.00                           /* QTR */                                         
0148.00              OVRDBF     FILE(RTVCMDSF) TOFILE(QTEMP/RTVCMDSF) +             
0149.00                           SECURE(*YES) OVRSCOPE(*JOB) SEQONLY(*YES 25)      
0150.00              CALL       PGM(ASNET.COM/RTVCMDR) PARM(&LIN &USNAMLIB +        
0151.00                           'COPYSPLF')                                       
0152.00              DLTOVR     FILE(RTVCMDSF) LVL(*JOB)                            
0153.00      GOTO CMDLBL(ENDPGM)                                                    
0154.00 /*-----------------------------------------------------------------*/       
0155.00  ERROR:                                                                     
0156.00              IF         COND(&ERRORSW) THEN(SNDPGMMSG MSGID(CPF9999) +      
0157.00                           MSGF(QCPFMSG) MSGTYPE(*ESCAPE))                   
0158.00              CHGVAR     &ERRORSW '1' /* Set to fail if error occurs */      
0159.00  RCVMSG:     RCVMSG     MSGTYPE(*DIAG) MSGDTA(&EMSGDTA) MSGID(&EMSGID) +    
0160.00                           MSGF(&EMSGF) MSGFLIB(&EMSGFLIB)                   
0161.00              IF         (&EMSGID *EQ '       ') GOTO NXTMSG                 
0162.00              SNDPGMMSG  MSGID(&EMSGID) MSGF(&EMSGFLIB/&EMSGF) +             
0163.00                           MSGDTA(&EMSGDTA) TOPGMQ(*PRV *) +                 
0164.00                           MSGTYPE(*DIAG)                                    
0165.00              GOTO       CMDLBL(RCVMSG)                                      
0166.00  NXTMSG:     RCVMSG     MSGTYPE(*EXCP) MSGDTA(&EMSGDTA) MSGID(&EMSGID) +    
0167.00                           MSGF(&EMSGF) MSGFLIB(&EMSGFLIB)                   
0168.00              SNDPGMMSG  MSGID(&EMSGID) MSGF(&EMSGFLIB/&EMSGF) +       
0169.00                           MSGDTA(&EMSGDTA) TOPGMQ(*PRV *) +           
0170.00                           MSGTYPE(*ESCAPE)                            
0171.00 /*-----------------------------------------------------------------*/ 
0172.00 ENDPGM:                                                               
0173.00              ENDPGM                                                          
--------------------------------------------------------------------------------------
【 コンパイル 】
    CRTCLPGM PGM(MYLIB/RTVCMDSRCC) SRCFILE(MYSRCLIB/QCLSRC) AUT(*ALL)
【 MI : RTVCMDM 】
------------------------------------------------------------------------------
0001.00          ENTRY  EXENTRY(EXENTOL) EXT;                                 
0002.00          DCL SPCPTR PARM1P PARM;                                      
0003.00          DCL OL EXENTOL (PARM1P) EXT PARM MIN(1);                     
0004.00                                                                       
0005.00 /* パラメータ */                                                      
0006.00          DCL SPC $PARMS BAS(PARM1P);                                  
0007.00          DCL DD $CMDNM   CHAR(10) DEF($PARMS) POS( 1);                
0008.00          DCL DD $CMDLI   CHAR(10) DEF($PARMS) POS(11);                
0009.00                                                                       
0010.00          DCL CON CUSPNAME CHAR(10) INIT('RTVCMDSPC');                 
0011.00          DCL CON CUSPLIBR CHAR(10) INIT('QTEMP');                     
0012.00          DCL CON SKIP     CHAR(2) INIT(X'3000');                      
0013.00          DCL CON HANDLE   CHAR(2) INIT(X'B000');                      
0014.00          DCL CON OP2ISCON CHAR(1) INIT(X'01');                        
0015.00                                                                       
0016.00          DCL SYSPTR QTEMPPTR BASPCO POS(65);                          
0017.00          DCL SYSPTR WORKSYP AUTO;                                     
0018.00          DCL SYSPTR CMDLSYP AUTO;                                     
0019.00          DCL SYSPTR CMDSYP AUTO;                                      
0020.00          DCL SPCPTR USPSPP AUTO;                                      
0021.00                                                                       
0022.00          DCL DD UCMDLI CHAR(10) AUTO;                                 
0023.00          DCL DD CMDSIZE BIN(4) AUTO BDRY(4) INIT(0);                  
0024.00                                                                       
0025.00 /* RSLVSP  テンプレート */                                            
0026.00          DCL DD OBJDESC CHAR(34) AUTO;                                
0027.00          DCL DD TYPESUB CHAR(2)  DEF(OBJDESC) POS(1);                 
0028.00          DCL DD OBJNAM  CHAR(30) DEF(OBJDESC) POS(3);                 
0029.00          DCL DD *       CHAR(2)  DEF(OBJDESC) POS(33) INIT(X'0000');  
0030.00                                                                       
0031.00 /* MATPTR 用出力テンプレート */                                       
0032.00          DCL SPCPTR MTPTRPTR AUTO INIT(MTPTR);                        
0033.00          DCL DD MTPTR CHAR(84) AUTO;                                  
0034.00          DCL DD MTPPROV  BIN(4) DEF(MTPTR) POS(1) INIT(84);           
0035.00          DCL DD MTPTYPE CHAR(1) DEF(MTPTR) POS(9) INIT(X'01') /* syp*/
0036.00          DCL DD MTPSPEC CHAR(75) DEF(MTPTR) POS(10);                  
0037.00          DCL DD MTSYCTXN CHAR(30) DEF(MTPSPEC) POS(3);                
0038.00                                                                       
0039.00 /* MATS 用出力テンプレート */                                         
0040.00          DCL SPCPTR MATSTMPP AUTO INIT(MATSTMP);                      
0041.00          DCL DD MATSTMP CHAR(96) AUTO BDRY(16);                       
0042.00          DCL DD MATSPRV  BIN(4) DEF(MATSTMP) POS( 1) INIT(96);        
0043.00          DCL DD MATSSIZ  BIN(4) DEF(MATSTMP) POS(49);                 
0044.00                                                                       
0045.00          DCL DD ERRCODE CHAR( 96) AUTO BDRY(4);                       
0046.00          DCL DD ERRPROV  BIN(  4) DEF(ERRCODE) POS( 1) INIT(96);      
0047.00          DCL DD ERRAVAL  BIN(  4) DEF(ERRCODE) POS( 5);               
         :
                (省略)
                  :
------------------------------------------------------------------------------
【 コンパイル 】
CRTMI PGM(MYLIB/RTVCMDM) SRCFILE(MYSRCLIB/QMISRC)

CRTMI というコマンドは存在していないので、この Tools にある「MIコンパイラー」によって作成すること。

【 解説 】

ソースを検索する原理はコマンドのダンプ・リストをスプールに出力して
それを MI (マシンインターフェース ) によって解析してソースを抽出している。
下記に RTVCMDSRC の実行の様子を紹介する。

RTVCMDSRC の実行の様子