Tools

17. IFS のファイルの存在チェックを行う CHKIFS

IFS へストリーム・ファイルを CPY コマンドによってコピーしようとすると、コピー先のファイルが既に
存在しているとエラーとなってしまう。
しかし CPY コマンドには CPYF のように REPLACE = *YES という置き換えのパラメータは
存在しないのである。
そこで IFSファイルの存在を検査して、既存であれば IFSファィルを削除してからコピーするように
すればよいのであるが、IFS のファイルの存在を検査するコマンドも OS400 には提供されて
いない。
そこでここでは CHKIFS という名前の IFSファイルの存在を検査する *PGM を作成してみた。

最初に CHKIFS を使用している場面のソースを紹介する。

              :
             DCL        VAR(&FULLPH) TYPE(*CHAR) LEN(128)
             DCL        VAR(&BACKUP) TYPE(*CHAR) LEN(128)
              :
             ASNET.COM/CHKIFS DIR(&BACKUP)                    
             MONMSG     MSGID(CPF9800) EXEC(GOTO CMDLBL(COPY))
             RMVLNK     OBJLNK(&BACKUP)                       
 COPY:       CPY        OBJ(&FULLPH) TOOBJ(&BACKUP)           
              :
【 解説 】

目的は &FULLPH というパス名の IFSファイルを &BACKUP という名前の IFS に
CPY コマンドを使って複製することである。
そこで事前に CHKIFS を使って &BACKUP の存在を検査している。
&BACUP がもし見つからなければ CPF9800 というエラー・メッセージが戻るので
MONMSG によって判定しているのである。

【 CMD: CHIFS 】
             CMD        PROMPT('IFS 検査 ')                         
             PARM       KWD(DIR) TYPE(*CHAR) LEN(256) CASE(*MIXED) +
                          PROMPT(' 登録簿 (/)')
【 コンパイル 】
CRTCMD CMD(MYLIB/CHKIFS) PGM(MYLIB/CHKIFS) SRCFILE(MYSRCLIB/QCMDSRC)   AUT(*ALL)
【 C/400: CHKIFS 】
/********************************************************************** 
/*                                                                      
/*   CHKIFS : Check IFS File if exists.                                 
/*                                                                      
/*            Office Quattro Co.ltd 02.11.09 15:04:03 created           
/*            this program will be called by cmd CHKIFS.                
/*                                                                      
/*   create : CRTBNDC ASNET.COM/CHKIFS                                  
/*                                                                      
/********************************************************************** 
#pragma comment(COPYRIGHT, "as400-net.com EnterpriseServer (C) CopyRigh 
Office Quattro.Corp. 2002- All right reserved. Users Restricted        
Rights - Use, duplication or disclosure restricted by Office Quattro   
Corp. Licenced Materials-Property of Office Quattro.")                  
#include <stdio.h>                                                     
#include <stdlib.h>                                                    
#include <string.h>                                                     
#include <fcntl.h>                                                      
#include <QMHSNDPM.h>                                                   
#include <errno.h>                                                      
                                                                       
#define TRUE         0                                                 
#define FALSE       -1                                                 
typedef struct {                                                       
   int  BYTESPRO;                                                      
   int  BYTESAVL;                                                      
   char MSGID[7];                                                      
   char RESRVD;                                                        
   char EXCPDATA[100];                                                 
} ERRSTRUCTURE;     /* Define the error return structure            */ 
ERRSTRUCTURE  errcode;/* Error Code Structure for RCVMSG      */       
                                                                       
void SndMsg(char msg_id[7], char msg_fl_name[20], char msg_data[128],  
            int msg_data_len, char msg_type[10], char msg_queue[20]);  
/********************************************************************/ 
/*                                                                  */ 
/*   main : parm 1. dir name[256]                                   */ 
/*                                                                  */ 
/********************************************************************/ 
void main(int argc, char *argv[]){                                     
    char dir[257];                                                     
   struct stat info;                          
   char* ptr;                                 
   int pos;                                   
   int fildes;                                
  char msg_id[7] = "CPF9897";                 
  char msgf[10] = "QCPFMSG   ";               
  char msglib[10] = "QSYS      ";             
  char msg_fl_name[20];                       
  char msg_data[132];                         
  int msg_data_len;                           
  char msg_type[10];                          
  char msg_queue[20];                         
   int len;                                   
                                              
    memset(dir, 0, sizeof(dir));              
    memcpy(dir, argv[1], 256);                
    dir[256] = 0x00;                          
    dir[50] = 0x00;                           
    system("CHGJOB CCSID(5035)");             
   ptr = strchr(dir, ' ');                    
   if(ptr != NULL){                           
     pos = (int)(ptr - dir);                                 
     dir[pos] = 0x00;                                        
   }                                                         
   if((fildes = open(dir, O_RDONLY)) == FALSE){              
    system("CHGJOB CCSID(5026)");                            
    system("CHGJOB CCSID(65535)");                           
   memset(msg_data, 0, sizeof(msg_data));                    
   sprintf(msg_data, "%s が見つからない ", dir);             
   msg_data_len = strlen(msg_data);                          
  memset(msg_fl_name, 0, sizeof(msg_fl_name));               
  memcpy(msg_fl_name, msgf, 10);                             
  memcpy(&msg_fl_name[10], msglib, 10);                      
  memset(msg_type, 0, sizeof(msg_type));                     
  strcpy(msg_type, "*ESCAPE   ");                            
  memset(msg_queue, 0, sizeof(msg_queue));                   
  strcpy(msg_queue, "*PGMQ     ");                           
  SndMsg(msg_id, msg_fl_name, msg_data, msg_data_len,        
                 msg_type, msg_queue);                       
   return;                                                   
   }                                                         
   else{                                                     
     close(fildes);                                                   
   }                                                                  
    system("CHGJOB CCSID(5026)");                                     
    system("CHGJOB CCSID(65535)");                                    
    exit(0);                                                          
    return;                                                           
}                                                                     
/********************************************************************/
void SndMsg(char msg_id[7], char msg_fl_name[20], char msg_data[128], 
            int msg_data_len, char msg_type[10], char msg_queue[20])  
/********************************************************************/
{                                                                     
   int  pgm_stk_cnt;                                                  
   char pgm_que[10];                                                  
   char msg_key[4];                                                   
                                                                      
    strncpy(msg_type, "*ESCAPE   ", 10);                              
    pgm_stk_cnt = 1;                                                  
    strncpy(pgm_que, "*PGMBDY   ", 10);                               
  errcode.BYTESPRO = errcode.BYTESAVL = 0;                            
    QMHSNDPM(msg_id, msg_fl_name, msg_data, msg_data_len, msg_type,   
         pgm_que, pgm_stk_cnt, msg_key, &errcode);
}
【 コンパイル 】
CRTBNDC PGM(MYLIB/CHKIFS) SRCFILE(MYSRCLIB/QCSRC) AUT(*ALL)
【 解説 】

原理としては非常に簡単であり <fcntl.h> による fopen 関数によってIFS ファイルのオープン
を試みてエラーとなれば、QMHSNDPM によって CPF9897*ESCAPE メッセージを戻す
だけである。
同じことを RPG でも作成することができるが C/400 のほうが自然な形で検査することができる。

【 参考 】

EnterpriseServer Ver4.0 では GoSanta! という名前の HTML編集ツールが搭載された。
GoSanta! を使うと IFS 上の HTMLファイルをブラウザ上で編集することができるのであるが、
このとき編集対象の HTML は編集都度、直前の状態が BACKUP として保存される。
編集結果を元に戻したいときはオプションによって、直前の状態に戻すことができる機能が
備わっている。
この UnDo のために内部では自動的に BACKUP が保存されているのであるが、Backup の
ために上記のように CHKIFS による存在検査が使用されているのである。