Tools

38. SAVF を物理ファイルに変換する CPYSAVF

SAVF の中身を正確に調べたいときに、DSPSAVF コマンドによって
SAVF にどのようなオブジェクトが保管されているかは知ることはできるのだが
直接、SAVF をダンプすることはできない。
SAVF のダンプを調査するような高度な解析を行なうときに便利な解析ツールとなるのが
ここで紹介する CPYSAVF コマンドである。
CPYSAVF コマンドは SAVF を物理ファイルにコピーするだけでなく、逆のパターンとして
物理ファイルから SAVF へコピーすることもできる。
もちろん SAVF 同士をコピーし合うこともできる。

SAVF とは実は 528 バイト長の単なる物理ファイルである。
しかし CPYF コマンドを始めとする ユーティリティーを使って SAVF を操作することはできない。
DSPPFM コマンドを使って SAVF をダンプすることもできない。
そこでここで紹介する CPYSAVF コマンドを使って 528 バイトの物理ファイルにコピーしてしまえば
DSPPFM コマンド等を使って自由に SAVF の内容を解析することができるようになる。

【コマンド : CPYSAVF】
001.00              CMD        PROMPT('*SAVF コピー ')            
002.00              PARM       KWD(FRMFILE) TYPE(FRMFILE) +       
003.00                           PROMPT(' 取出しファイル ')       
004.00  FRMFILE:    QUAL       TYPE(*NAME) LEN(10) MIN(1)         
005.00              QUAL       TYPE(*NAME) LEN(10) DFT(*LIBL) +   
006.00                           SPCVAL((*LIBL) (*CURLIB)) +      
007.00                           PROMPT(' ライブラリー ')         
008.00              PARM       KWD(TOFILE) TYPE(TOFILE) +         
009.00                           PROMPT(' 受入れファイル ')       
010.00  TOFILE:     QUAL       TYPE(*NAME) LEN(10) MIN(1)         
011.00              QUAL       TYPE(*NAME) LEN(10) DFT(*LIBL) +   
012.00                           SPCVAL((*LIBL) (*CURLIB)) +      
013.00                           PROMPT(' ライブラリー ')         
		
【コンパイル】
CRTCMD CMD(MYLIB/CPYSAVF) PGM(MYLIB/CPYSAVFCL) SRCFILE(MYSRCLIB/QCMDSRC) AUT(*ALL)
【CL プログラム : CPYSAVFCL】
0001.00              PGM        PARM(&FRMFILLIB &TOFILLIB)                                 
0002.00 /*---------------------------------------------------------*/                      
0003.00 /*   CPYSAVF  :  *SAVF コピー                              */                      
0004.00 /*---------------------------------------------------------*/                      
0005.00              DCL        VAR(&MSG) TYPE(*CHAR) LEN(80)                              
0006.00              DCL        VAR(&FRMFILLIB) TYPE(*CHAR) LEN(20)                        
0007.00              DCL        VAR(&FRMFIL) TYPE(*CHAR) LEN(10)                           
0008.00              DCL        VAR(&FRMLIB) TYPE(*CHAR) LEN(10)                           
0009.00              DCL        VAR(&TOFILLIB) TYPE(*CHAR) LEN(20)                         
0010.00              DCL        VAR(&TOFIL) TYPE(*CHAR) LEN(10)                            
0011.00              DCL        VAR(&TOLIB) TYPE(*CHAR) LEN(10)                            
0012.00              DCL        VAR(&OBJATR) TYPE(*CHAR) LEN(10)                           
0013.00              DCL        VAR(&STSMSG) TYPE(*CHAR) LEN(128)                          
0014.00              MONMSG     MSGID(CPF0000 RNX9000 CEE9900) EXEC(GOTO +                 
0015.00                           CMDLBL(ERROR))                                           
0016.00                                                                                    
0017.00              CHGVAR     VAR(&FRMFIL) VALUE(%SST(&FRMFILLIB 1 10))                  
0018.00              CHGVAR     VAR(&FRMLIB) VALUE(%SST(&FRMFILLIB 11 10))                 
0019.00              CHGVAR     VAR(&TOFIL) VALUE(%SST(&TOFILLIB 1 10))                    
0020.00              CHGVAR     VAR(&TOLIB) VALUE(%SST(&TOFILLIB 11 10))                   
0021.00              RTVOBJD    OBJ(&TOLIB/&TOFIL) OBJTYPE(*FILE) +                        
0022.00                           OBJATR(&OBJATR)                                          
0023.00              IF         COND(&OBJATR *EQ 'SAVF      ') THEN(DO)                    
0024.00              CLRSAVF    FILE(&TOLIB/&TOFIL)                                      
0025.00              ENDDO                                                               
0026.00              IF         COND(&OBJATR *EQ 'PF        ') THEN(DO)                  
0027.00              CLRPFM     FILE(&TOLIB/&TOFIL)                                      
0028.00              ENDDO                                                               
0029.00              CHGVAR     VAR(&STSMSG) VALUE(&FRMLIB *TCAT '/' *CAT +              
0030.00                           &FRMFIL *TCAT ' をコピー中です。 ')                    
0031.00              SNDPGMMSG  MSGID(CPF9897) MSGF(QCPFMSG) MSGDTA(&STSMSG) +           
0032.00                           TOPGMQ(*EXT) MSGTYPE(*STATUS)                          
0033.00              OVRDBF     FILE(FRMSAVF) TOFILE(&FRMLIB/&FRMFIL) +                  
0034.00                           OVRSCOPE(*JOB)                                         
0035.00              OVRDBF     FILE(TOSAVF) TOFILE(&TOLIB/&TOFIL) +                     
0036.00                           OVRSCOPE(*JOB)                                         
0037.00              CALL       PGM(CPYSAVF)                                             
0038.00              DLTOVR     FILE(FRMSAVF) LVL(*JOB)                                  
0039.00              DLTOVR     FILE(TOSAVF) LVL(*JOB)                                   
0040.00              SNDPGMMSG  MSG(&FRMLIB *TCAT '/' *CAT &FRMFIL *TCAT +               
0041.00                           ' から ' *CAT &TOLIB *TCAT '/' *CAT +                  
0042.00                           &TOFIL *TCAT +                                         
0043.00                           ' へのコピーが完了しました。 ') +                      
0044.00                           MSGTYPE(*DIAG)                                         
0045.00              RETURN                                                              
0046.00                                                                                  
0047.00  ERROR:      RCVMSG     MSGTYPE(*LAST) RMV(*NO) MSG(&MSG)                        
0048.00  SNDMSG:     SNDPGMMSG  MSG(&MSG) MSGTYPE(*DIAG)   
0049.00              ENDPGM                                
		
【コンパイル】
CRTCLPGM PGM(MYLIB/CPYSAVFCL) SRCFILE(MYSRCLIB/QCLSRC) AUT(*ALL)
【RPGプログラム : CPYSAVF】
0001.00 H DFTNAME(CPYSAVF) DATEDIT(*YMD/)                                                  
0002.00 F********** *SAVF コピー  ****************************************                
0003.00 FFRMSAVF   IP   F  528        DISK                                                
0004.00 F                                     INFDS(INFDSF)                               
0005.00 FTOSAVF    O    F  528        DISK                                                
0006.00 F                                     INFSR(*PSSR)                                
0007.00 F*****************************************************************                
0008.00 D INFDSF          DS                                                              
0009.00 D*  RECRRN: 入出力レコードの RRN                                                  
0010.00 D  RECRRN               397    400B 0                                             
0011.00 D MSGE            C                   CONST(' でエラーがあった。 ')               
0012.00 D DSP40           S             40                                                
0013.00 IFRMSAVF   AA  01                                                                 
0014.00 I                                  1  528  DATA                                   
0015.00                                                                                   
0016.00 C******************************************************                           
0017.00 C     *PSSR         BEGSR                                                         
0018.00 C******************************************************                           
0019.00 C                   Z-ADD     RECRRN        DSPRRN            4 0                 
0020.00 C                   MOVE      DSPRRN        DSPRRN_C          4                   
0021.00 C                   EVAL      DSP40 = 'RRN=' + DSPRRN_C + MSGE                    
0022.00 C     DSP40         DSPLY                   ANS               1                   
0023.00 C                   ENDSR     '*CANCL'                                            
0024.00 OTOSAVF    D    01                               
0025.00 O                       DATA               528   
		
【解説】

RPG : CPYSAVF は 528 バイトのファイルを 528 バイトのファイルへデータを
コピーしているだけに過ぎない。
ただし簡単なプログラムの割には *PSSR サブルーチンによってエラーを厳しく監視しているのは
物理ファイルから SAVF にコピーする場合、SAVF としての論理的な整合性に問題があった場合は
レコードが書き込まれると同時に OS/400 によってエラーと扱われるからである。
CPYSAVF は、エラーが発生したときの RRN を報告することができるように記述されている。