Tools

66. IFS を別のサーバーに BACKUP する SAVUSRIFS

ここで紹介する SAVUSRIFS コマンドはユーザー IFS だけを
BACKUP して別の PC サーバーに転送する。
先にライブラリーを BACKUP する SAVUSRLIB コマンドを紹介したが
Web 化の時代とあっては IFS の BACKUP も絶対に必要である。

SAVUSRIFS はテープ装置ではなく PC サーバーへの FTP での転送であるので
テープ装置も必要なく媒体の劣化を気にする必要もない
当然、テープ装置への BACKUP に比べると速度も速くて時間も短くて済む

i5/OS を含むフル・バックアップはテープ装置へバックアップするのであるが
これはバックアップ漏れのないように人での監視のもとで行う。
しかし日常、活動しているライブラリーに関しては毎日、深夜に
無人で漏れなく行うことが必要である。
このときテープ装置へのバックアップであると毎日のことなので
繰り返しているとテープ装置の劣化や損傷を招くことがある。
Ftp 転送であれば PC サーバーなどへのハード・ディスクへのコピーなので
繰り返していてもその心配はない。

  • バックアップは ADDJOBSCDE *WEEKLY によって
    毎日、深夜に自動実行される。
  • この SAVUSRIFS コマンドが実際に株式会社オフィスクアトロで
    運用されていものである。
  • ライブラリーは実行ジョブの QTEMP 上の *SAVF に保管したものを
    バックアップする。
  • Ftp はライブラリー・システムは読むことはできないので
    ライブラリーを IFS の FILE に CPYTOSTMF で *SAVF をコピーしたものを
    転送する。
  • 当然、PC サーバー側では Ftp が起動されていなければならない。
  • SAVUSRIFS コマンドは *ALL を指定すればすべてのユーザー IFS を
    保管できるが、個別に IFS を指定して保管することもできる。
  • SAVUSRIFS は頭文字が英大文字( A~Z )から始まる 10 桁以内の名前の
    IFS だけを保管の対象としている。
    IBM 提供の IFS はほとんどが英小文字から始まる名前であるので
    ユーザー IFS は英大文字から始まる名前として命名しておけば
    簡単に区別することができる。
    これ以外の IFS を保管したい場合はソースを変更すればできる。
    他にも TEST や _ となどを名前の文字列に含む IFS は保管されない。
    個人用 IFS も保管の対象からは外される。
    英字から始まる 10 桁の名前が求められるのは同じ名前の *SAVF を
    作成するためである。
    しかし 10 桁以上の名前であっても保管/復元は可能である。

    このあたりは法人の事情によって異なるのでソースを自社の事情に合うよう
    適切な形に修正して欲しい。
  • SAVUSRIFS に対応する復元コマンド: RSTUSRIFS も後に紹介を予定している。
【 SAVUSRIFS の実行の様子 】
                          ユーザー IFS 保存  (SAVUSRIFS)                        
                                                                                
  選択項目を入力して,実行キーを押してください。                                
                                                                                
                                    *ALL                                        
                                                                                
                 値の続きは+                                                   
                                                                                
  出力オプション  . . . . . . . . > *SEND         *NONE, *SEND, *PRINT          
  ホスト IP アドレス  . . . . . .   '*DFT'                                      
  相手先 IP アドレス  . . . . . .   '192.168.1.8'                               
  相手先ファイル・パス  . . . . .   '/TEST'                       
                                                                                
                                                                                
  遠隔ユーザー ID . . . . . . . .   QUATTRO                                     
  遠隔パスワード  . . . . . . . .                  文字値 , *NONE               
  ログ表示  . . . . . . . . . . .   *YES          *YES, *NO                                                                                      
【 解説 】
出力オプション ・・・・・ *SEND: FTP で相手先へ転送する
ホスト IP アドレス ・・・・・ 自分自身のこの IBM i の IP アドレス。
*DFT と指定しておけば自動的に検出される。
相手先ファイル・パス ・・・・・ 相手先 PC の保管ディレクトリーを指定する。
遠隔ユーザー ID ・・・・・ 相手先 PC に Ftp でログインするための
ユーザー名
遠隔パスワード ・・・・・ そのパスワード。
バスワードは入力しても表示されない。
ログ表示 ・・・・・ FTP の状況をログ表示するかどうか指定する。
最初のテストは問題のあったときの
原因追求のときにはログ *YES を指定し、
通常のバッチ・ジョブではログ *NO を
指定するとよい。
【 コマンド: SAVUSRIFS 】
0001.00              CMD        PROMPT(' ユーザー IFS 保存 ')                         
0002.00              PARM       KWD(IFS) TYPE(*PNAME) LEN(256) DFT(*ALL) +            
0003.00                           SPCVAL((*ALL)) MAX(50)                              
0004.00              PARM       KWD(OPTION) TYPE(*CHAR) LEN(6) RSTD(*YES) +           
0005.00                           DFT(*NONE) VALUES(*NONE *SEND *PRINT) +             
0006.00                           PROMPT(' 出力オプション ')                          
0007.00  SEND:       PMTCTL     CTL(OPTION) COND((*EQ *SEND))                         
0008.00              PARM       KWD(FRMADDRESS) TYPE(*CHAR) LEN(15) +                 
0009.00                           DFT('*DFT') PMTCTL(SEND) +                          
0010.00                           PROMPT(' ホスト IP アドレス ')                      
0011.00              PARM       KWD(TOADDRESS) TYPE(*CHAR) LEN(15) +                  
0012.00                           DFT('192.168.1.8') PMTCTL(SEND) +                   
0013.00                           PROMPT(' 相手先 IP アドレス ')                      
0014.00              PARM       KWD(TOPASS) TYPE(*CHAR) LEN(128) +                    
0015.00                           DFT('/TEST/SAVUSRLIB.SAV') CASE(*MIXED) +           
0016.00                           PMTCTL(SEND) PROMPT(' 相手先ファイル・パス ')       
0017.00              PARM       KWD(USER) TYPE(*CHAR) LEN(13) DFT(QUATTRO) +          
0018.00                           SPCVAL((*NONE)) CASE(*MIXED) PMTCTL(SEND) +         
0019.00                           PROMPT(' 遠隔ユーザー ID')                          
0020.00              PARM       KWD(PASSWORD) TYPE(*CHAR) LEN(13) DFT(*NONE) +        
0021.00                           SPCVAL((*NONE)) CASE(*MIXED) +                      
0022.00                           DSPINPUT(*NO) PMTCTL(SEND) +                        
0023.00                           INLPMTLEN(*PWD) PROMPT(' 遠隔パスワード ')          
0024.00              PARM       KWD(LOG) TYPE(*CHAR) LEN(4) RSTD(*YES) +   
0025.00                           DFT(*YES) VALUES(*YES *NO) PMTCTL(SEND) +
0026.00                           PROMPT(' ログ表示 ')                     
0027.00  PRINT:      PMTCTL     CTL(OPTION) COND((*EQ *PRINT))             
【 CLP: SAVUSRIFSC 】
0001.00              PGM        PARM(&PASR &OPTION &FROMIP &TOIP &TODIR +            
0002.00                           &USER &PASSWRD &LOG)                               
0003.00 /*-------------------------------------------------------------------*/      
0004.00 /*   SAVUSRIFSC :   ユーザー IFS 保存                                */      
0005.00 /*                                                                   */      
0006.00 /*   2018/09/21  作成                                                */      
0007.00 /*-------------------------------------------------------------------*/      
0008.00              DCL        VAR(&PASR) TYPE(*CHAR) LEN(12802)                    
0009.00              DCL        VAR(&INZPAS) TYPE(*CHAR) LEN(256)                    
0010.00              DCL        VAR(&OPTION) TYPE(*CHAR) LEN(6)                      
0011.00              DCL        VAR(&FLD2) TYPE(*CHAR) LEN(2)                        
0012.00              DCL        VAR(&SAVSU) TYPE(*DEC) LEN(4 0)                      
0013.00              DCL        VAR(&LIB) TYPE(*CHAR) LEN(10)                        
0014.00              DCL        VAR(&INZLIB) TYPE(*CHAR) LEN(10)                     
0015.00              DCL        VAR(&MSG) TYPE(*CHAR) LEN(132)                       
0016.00              DCL        VAR(&MSGID) TYPE(*CHAR) LEN(7)                       
0017.00              DCL        VAR(&MSGF) TYPE(*CHAR) LEN(10)                       
0018.00              DCL        VAR(&MSGFLIB) TYPE(*CHAR) LEN(10)                    
0019.00              DCL        VAR(&MSGDTA) TYPE(*CHAR) LEN(132)                    
0020.00              DCL        VAR(&TYPE) TYPE(*CHAR) LEN(1)                        
0021.00              DCL        VAR(&TOPGMQ) TYPE(*CHAR) LEN(10)                     
0022.00              DCL        VAR(&MSGTYPE) TYPE(*CHAR) LEN(10) +                  
0023.00                           VALUE('*ESCAPE   ')                                
0024.00              DCL        VAR(&APIERR) TYPE(*CHAR) LEN(116) +                    
0025.00                           VALUE(X'000074') /* 2 進数  */                       
0026.00              DCL        VAR(&NULL4) TYPE(*CHAR) LEN(4) +                       
0027.00                           VALUE(X'00000000')                                   
0028.00              DCL        VAR(&N) TYPE(*DEC) LEN(8 0) VALUE(1) /* WORK */        
0029.00              DCL        VAR(&POS) TYPE(*DEC) LEN(4 0)                          
0030.00              DCL        VAR(&ERR) TYPE(*CHAR) LEN(1)                           
0031.00              /*( SNDFTP 送信のための変数 )*/                                   
0032.00              DCL        VAR(&FROMMBR) TYPE(*CHAR) LEN(128) +                   
0033.00                           VALUE('/QSYS.LIB/IFSLIB.LIB')                        
0034.00              DCL        VAR(&FROMIP) TYPE(*CHAR) LEN(15)                       
0035.00              DCL        VAR(&FROMPASS) TYPE(*CHAR) LEN(128)                    
0036.00              DCL        VAR(&TOIP) TYPE(*CHAR) LEN(15)                         
0037.00              DCL        VAR(&TODIR) TYPE(*CHAR) LEN(128)                       
0038.00              DCL        VAR(&TOPASS) TYPE(*CHAR) LEN(128)                      
0039.00              DCL        VAR(&USER) TYPE(*CHAR) LEN(13)                         
0040.00              DCL        VAR(&PASSWRD) TYPE(*CHAR) LEN(13)                      
0041.00              DCL        VAR(&LOG) TYPE(*CHAR) LEN(4)                           
0042.00              DCL        VAR(&TEXT) TYPE(*CHAR) LEN(50)                         
0043.00              MONMSG     MSGID(CPF0000) EXEC(GOTO CMDLBL(ERROR))                
0044.00                                                                                
0045.00 /*( 環境の取得 )*/                                                             
0046.00              RTVJOBA    TYPE(&TYPE)                                            
0047.00              IF         COND(&TYPE *EQ '0') THEN(DO) /*  バッチ  */            
0048.00              CHGVAR     VAR(&TOPGMQ) VALUE('*SYSOPR   ')                     
0049.00              ENDDO      /*  バッチ  */                                       
0050.00              ELSE       CMD(DO) /*  対話式  */                               
0051.00              CHGVAR     VAR(&TOPGMQ) VALUE('*TOPGMQ   ')                     
0052.00              ENDDO      /*  対話式  */                                       
0053.00                                                                              
0054.00 /*( パラメータの取得 )*/                                                     
0055.00              CHGVAR     VAR(&FLD2) VALUE(%SST(&PASR 1 2))                    
0056.00              CHGVAR     VAR(&SAVSU) VALUE(%BIN(&FLD2))                       
0057.00              CHGVAR     VAR(&INZPAS) VALUE(%SST(&PASR 3 256))                
0058.00              IF         COND(&OPTION *EQ '*SEND ') THEN(DO) /* +             
0059.00                            送信  */                                          
0060.00              IF         COND(%SST(&PASSWRD 1 5) *EQ '*NONE') THEN(DO)        
0061.00              CHGVAR     VAR(&MSG) +                                          
0062.00                           VALUE(' パスワードが指定されていません。 ')        
0063.00              GOTO       SNDMSG                                               
0064.00              ENDDO                                                           
0065.00              ENDDO      /*  送信  */                                         
0066.00                                                                              
0067.00              IF         COND(%SST(&INZPAS 1 4) *EQ '*ALL') THEN(DO) +        
0068.00                           /* *ALL */                                         
0069.00              CALL       PGM(QUATTRO/SAVUSRIFS) PARM(&OPTION &ERR +           
0070.00                           &MSG &FROMIP &TOIP &TODIR &USER &PASSWRD)          
0071.00              IF         COND(&ERR *EQ ' ') THEN(DO)                          
0072.00              CHGVAR     VAR(&MSGTYPE) VALUE('*DIAG     ')             
0073.00              ENDDO                                                    
0074.00              IF         COND(&MSG *NE ' ') THEN(DO)                   
0075.00              GOTO       SNDMSG                                        
0076.00              ENDDO                                                    
0077.00              ENDDO      /* *ALL */                                    
0078.00              RETURN                                                   
0079.00                                                                       
0080.00  APIERR:                                                              
0081.00              CHGVAR     VAR(&MSGID) VALUE(%SST(&APIERR 9 7))          
0082.00              CHGVAR     VAR(&MSGDTA) VALUE(%SST(&APIERR 17 100))      
0083.00              CHGVAR     VAR(&MSGF) VALUE('QCPFMSG   ')                
0084.00              CHGVAR     VAR(&MSGFLIB) VALUE('QSYS      ')             
0085.00              GOTO       SNDMSG                                        
0086.00                                                                       
0087.00  ERROR:      RCVMSG     MSGTYPE(*LAST) RMV(*NO) MSG(&MSG) +           
0088.00                           MSGDTA(&MSGDTA) MSGID(&MSGID) MSGF(&MSGF) + 
0089.00                           MSGFLIB(&MSGFLIB)                           
0090.00  SNDMSG:     IF         COND(&MSGID *EQ ' ') THEN(DO)                 
0091.00              SNDPGMMSG  MSGID(CPF9897) MSGF(QCPFMSG) MSGDTA(&MSG) +   
0092.00                           TOMSGQ(&TOPGMQ) MSGTYPE(&MSGTYPE)           
0093.00              MONMSG     MSGID(CPF2400) EXEC(RETURN)                   
0094.00              ENDDO                                                    
0095.00              ELSE       CMD(DO)                                       
0096.00              SNDPGMMSG  MSGID(&MSGID) MSGF(&MSGFLIB/&MSGF) + 
0097.00                           MSGDTA(&MSGDTA) TOMSGQ(&TOPGMQ) +  
0098.00                           MSGTYPE(&MSGTYPE)                  
0099.00              MONMSG     MSGID(CPF2400) EXEC(RETURN)          
0100.00              ENDDO                                           
0101.00              ENDPGM                                          
【 解説 】

CLP: SAVUSRIFSC の実体は

0069.00              CALL       PGM(QUATTRO/SAVUSRIFS) PARM(&OPTION &ERR +           
0070.00                           &MSG &FROMIP &TOIP &TODIR &USER &PASSWRD)

に示されているように SAVUSRIFS という C/400 による C 言語の
プログラムである。
IFS の処理はやはり C/400 のほうが簡潔にできるので C/400 を使った。

【 C/400: SAVUSRIFS 】
0001.00 /********************************************************************/           
0002.00 /*                                                                  */           
0003.00 /*   SAVUSRIFS   :   ユーザー IFS 保存                              */           
0004.00 /*                                                                  */           
0005.00 /*          Office Quattro Co,.Ltd 2018/09/21 13:43:00 created      */           
0006.00 /*                                                                  */           
0007.00 /*                                                                  */           
0008.00 /********************************************************************/           
0009.00 #pragma comment(COPYRIGHT, "as400-net.com EnterpriseServer (C) CopyRight        
0010.00 Office Quattro.Corp. 2018- All right reserved. Users Restricted                 
0011.00 Rights - Use, duplication or disclosure restricted by Office Quattro            
0012.00 Corp. Licenced Materials-Property of Office Quattro.")                           
0013.00 #include                                                                
0014.00 #include                                                               
0015.00 #include                                                               
0016.00 #include  /* triml */                                                
0017.00 #include                                                                
0018.00 #include                                                               
0019.00 #include                                                               
0020.00 #include                                                             
0021.00 #include                                                             
0022.00                                                                                  
0023.00 #define TRUE         0                                                           
0024.00 #define FALSE       -1                                                       
0025.00 #define ERROR        1                                                       
0026.00 int    bLR = FALSE;                                                          
0027.00 typedef struct {                                                             
0028.00    int  BYTESPRO;                                                            
0029.00    int  BYTESAVL;                                                            
0030.00    char MSGID[7];                                                            
0031.00    char RESRVD;                                                              
0032.00    char EXCPDATA[100];                                                       
0033.00 } ERRSTRUCTURE;     /* Define the error return structure            */       
0034.00 ERRSTRUCTURE  errcode;/* Error Code Structure for RCVMSG      */             
0035.00 volatile _INTRPT_Hndlr_Parms_T ca;                                           
0036.00                                                                              
0037.00 /*************************************************************/              
0038.00 /*       内 部 使 用  関  数                          */              
0039.00 /*************************************************************/              
0040.00 void  GetParam(int argc, char *argv[]);                                      
0041.00 void  INZSR(void);                                                           
0042.00 void  saveIFS(char* name, char* type, int size);                             
0043.00 void SendMessage(char* Message, char* Status, char* Pgmque);                 
0044.00 void  LRRTN(char* argv[]);                                                   
0045.00                                                                              
0046.00 /*************************************************************/              
0047.00 /*       IMPORT  関  数                            */              
0048.00 /*************************************************************/               
0049.00 /*************************************************************/               
0050.00 /*       IMPORT  変  数                            */               
0051.00 /*************************************************************/               
0052.00 /*************************************************************/               
0053.00 /*       外 部 呼 出 し  関  数                      */               
0054.00 /*************************************************************/               
0055.00 void MonitorMSG(_INTRPT_Hndlr_Parms_T ca, char* ref);                         
0056.00 #pragma linkage(MonitorMSG, OS)                                               
0057.00 #pragma map(MonitorMSG, "ASNET.COM/MONMSG")                                   
0058.00 /*************************************************************/               
0059.00 /*        グ ロ ー バ ル 変 数                         */               
0060.00 /*************************************************************/               
0061.00   /*------( 受取りパラメータ値 )----------*/                                  
0062.00   char OPTION[7], FROMIP[16], TOIP[16], TODIR[129], USER[14], PASSWRD[14];    
0063.00   /*------( 受取りパラメータ値 )----------*/                                  
0064.00   char ref[133];                                                              
0065.00 char handle[9];                                                               
0066.00 char listopt[5];                                                              
0067.00 char lsthnd[5];                                                               
0068.00 char home[50], msg[132], ERR[2];                                              
0069.00 int  saveSU = 0;                                                              
0070.00 /********************************************************************/        
0071.00 /*            m  a  i  n --- main module of this pgm                */        
0072.00 /*                                                                  */         
0073.00 /*           1. OPTION                                   */         
0074.00 /*                      2. ERR                                      */         
0075.00 /*                      3. MSG                                      */         
0076.00 /*                                                                  */         
0077.00 /*------------------------------------------------------------------*/         
0078.00                                                                                
0079.00 int  main(int argc, char *argv[]){                                             
0080.00     DIR *dir;                                                                  
0081.00     struct dirent *entry;                                                      
0082.00     char path[257];                                                            
0083.00     struct stat info;                                                          
0084.00     char objtype[11];                                                          
0085.00     int size;                                                                  
0086.00     int bUSER = TRUE;                                                          
0087.00     int len;                                                                   
0088.00                                                                                
0089.00    #pragma exception_handler(MONMSG, ca, 0, _C2_MH_ESCAPE,                    
0090.00                                             _CTLA_HANDLE)                      
0091.00    GetParam(argc, argv);  /*[ パラメータの取得 ]*/                             
0092.00    INZSR();               /*[ 初期設定 ]*/                                     
0093.00                                                                                
0094.00     if((dir = opendir(home)) == NULL){/* オープン・エラー */                   
0095.00       printf("%sn", home);                                                    
0096.00       perror("opendir errorn");                                 
0097.00       getchar();                                                 
0098.00       exit(0);                                                   
0099.00     }/* オープン・エラー */                                      
0100.00     else{/* 正常 */                                              
0101.00       while((entry = readdir(dir)) != NULL){/*while*/            
0102.00         if(strncmp(entry->d_name, ".", 1) == 0) continue;        
0103.00         if(bUSER == TRUE){/*USER*/                               
0104.00            if(strncmp(entry->d_name, "Q", 1) == 0 &&             
0105.00               strncmp(entry->d_name, "QATMHSTOUT", 6) != 0)      
0106.00            /* strncmp(entry->d_name, "QOpenSys", 8) != 0) */     
0107.00            continue;                                             
0108.00         }/*USER*/                                                
0109.00         sprintf(path, "%s/%s", home, entry->d_name);             
0110.00         if(stat(path, &info) != TRUE)                            
0111.00            memset(objtype, ' ', sizeof(objtype));                
0112.00         else  sprintf(objtype, "%s", info.st_objtype);           
0113.00         if(strncmp(&objtype[1], "DIR", 3) == 0 ||                
0114.00            strncmp(&objtype[1], "LIB", 3) == 0 ||                
0115.00            strncmp(&objtype[1], "FLR", 3) == 0){/*DIR*/          
0116.00           size = 0;                                              
0117.00         }/*DIR*/                                                 
0118.00         else{/*STMF*/                                            
0119.00           size = (int)info.st_allocsize;                         
0120.00         }/*STMF*/                                                          
0121.00         if(strncmp(entry->d_name, "A", 1) >= 0 &&                          
0122.00            strncmp(entry->d_name, "Z", 1) <= 0 &&                          
0123.00            strncmp(&objtype[1], "DIR", 3) == 0){/* 英大文字 */             
0124.00           if(strstr(entry->d_name, "TEST") != NULL) continue;              
0125.00           if(strlen(entry->d_name) > 10 &&                                 
0126.00              strncmp(entry->d_name, "AS400-NET.USR ", 14) == 0) continue;  
0127.00           if(strchr(entry->d_name, '_') != NULL) continue;                 
0128.00           if(strncmp(entry->d_name, "PROJECT", 7) == 0) continue;          
0129.00           if(strncmp(entry->d_name, "OOTAKE",  6) == 0) continue;          
0130.00           if(strncmp(entry->d_name, "WORK.ZIP",  8) == 0) continue;        
0131.00           if(strncmp(entry->d_name, "YOGI",  4) == 0) continue;            
0132.00           if(strncmp(entry->d_name, "PTF",  3) == 0) continue;             
0133.00           if(strncmp(entry->d_name, "JPN",  3) == 0) continue;             
0134.00           if(strncmp(entry->d_name, "TAAAWBLIB",  9) == 0) continue;       
0135.00           saveIFS(entry->d_name, &objtype[1], size);                       
0136.00         }/* 英大文字 */                                                    
0137.00       }/*while*/                                                           
0138.00       closedir(dir);                                                       
0139.00     }/* 正常 */                                                            
0140.00     sprintf(msg, "%d 個の IFS を保管しました。 ", saveSU);                 
0141.00                                                                            
0142.00    LRRTN(argv);                                                            
0143.00    exit(0);                                                                
0144.00                                                  
0145.00 MONMSG:                                          
0146.00    #pragma disable_handler                       
0147.00    strcpy(ref, "SAVUSRIFS");                     
0148.00    MonitorMSG(ca, ref);                          
0149.00                                                  
0150.00    exit(0);                                      
0151.00 }                                                
0152.00 /*************************************/          
0153.00 void  GetParam(int argc, char *argv[])           
0154.00 /*************************************/          
0155.00 {                                                
0156.00   int  len;                                      
0157.00                                                  
0158.00   memcpy(OPTION, argv[1], 6);                    
0159.00   OPTION[6] = 0x00;                              
0160.00   memcpy(FROMIP, argv[4], 15);                   
0161.00   FROMIP[15] = 0x00;                             
0162.00   len = triml(FROMIP, ' ');                      
0163.00   if(len > 0) FROMIP[len] = 0x00;                
0164.00   memcpy(TOIP, argv[5], 15);                     
0165.00   TOIP[15] = 0x00;                               
0166.00   len = triml(TOIP, ' ');                        
0167.00   if(len > 0) TOIP[len] = 0x00;                  
0168.00   memcpy(TODIR, argv[6], 128);                   
0169.00   TODIR[128] = 0x00;                             
0170.00   len = triml(TODIR, ' ');                       
0171.00   if(len > 0) TODIR[len] = 0x00;                 
0172.00   memcpy(USER, argv[7], 13);                     
0173.00   USER[13] = 0x00;                               
0174.00   len = triml(USER, ' ');                        
0175.00   if(len > 0) USER[len] = 0x00;                  
0176.00   memcpy(PASSWRD, argv[8], 13);                  
0177.00   PASSWRD[13] = 0x00;                            
0178.00   len = triml(PASSWRD, ' ');                     
0179.00   if(len > 0) PASSWRD[len] = 0x00;               
0180.00 }                                                
0181.00 /****************/                               
0182.00 void  INZSR(void)                                
0183.00 /****************/                               
0184.00 {                                                
0185.00    errcode.BYTESPRO = 160;                       
0186.00    errcode.BYTESAVL = 0;                         
0187.00    strcpy(home, "/");                            
0188.00    strcpy(ERR, " ");                             
0189.00 }                                                
0190.00 /*********************************************/  
0191.00 void saveIFS(char* name, char* type, int size)   
0192.00 /*********************************************/                    
0193.00 {                                                                  
0194.00    char ifs[21], obj[11], cmd[256], msgtxt[132];                   
0195.00    int  len;                                                       
0196.00                                                                    
0197.00    strcpy(ifs, name);                                              
0198.00    len = triml(ifs, ' ');                                          
0199.00    if(len > 0) ifs[len] = 0x00;                                    
0200.00    if(strncmp(ifs, "AS400-NET.USR", 13) == 0){/*AS400-NET.USR*/    
0201.00      strcpy(obj, "ASNETUSR");                                      
0202.00    }/*AS400-NET.USR*/                                              
0203.00    else{/* 通常 */                                                 
0204.00      strcpy(obj, ifs);                                             
0205.00    }/* 通常 */                                                     
0206.00    sprintf(msgtxt, "/%s を保管中です。 ", obj);                    
0207.00    SendMessage(msgtxt, "*STATUS   ",  "*EXT      ");               
0208.00    sprintf(cmd, "CHKOBJ  OBJ(IFSLIB/%s) OBJTYPE(*FILE)", obj);     
0209.00    if(system(cmd) == ERROR){/* エラー */                           
0210.00      sprintf(cmd, "CRTSAVF FILE(IFSLIB/%s) AUT(*ALL)", obj);       
0211.00      system(cmd);                                                  
0212.00    }/* エラー */                                                   
0213.00    /*( IFSLIB に *SAVF を作成する )*/                              
0214.00    sprintf(cmd, "CLRSAVF FILE(IFSLIB/%s)", obj);                   
0215.00    system(cmd);                                                    
0216.00    /*( IFSLIB の保管ファイルに IFS を保存する )*/                         
0217.00    sprintf(cmd, "SAV DEV('/QSYS.LIB/IFSLIB.LIB/%s.FILE') OBJ('/%s/*')",   
0218.00         obj, ifs);                                                        
0219.00    system(cmd);                                                           
0220.00    if(strncmp(OPTION, "*SEND", 5) == 0){/*FTP 転送 */                     
0221.00      /*( IFS に保管ファイルを転送する )*/                                 
0222.00      sprintf(cmd,                                                         
0223.00      "CPYTOSTMF FROMMBR('/QSYS.LIB/IFSLIB.LIB/%s.FILE')                  
0224.00  TOSTMF('/TEST/%s.FILE') STMFOPT(*REPLACE)", obj, obj);                   
0225.00      system(cmd);                                                         
0226.00      /*( FTP でファイルを転送する )*/                                     
0227.00      memset(cmd, 0, sizeof(cmd));                                         
0228.00      sprintf(cmd,                                                         
0229.00       "SPOOLWTR/SNDFTP FRMADDRESS('*DFT')                                
0230.00  FROMFILE('/TEST/%s.FILE') TOADDRESS('192.168.1.8')                      
0231.00   TOFILE('/TEST/%s.IFS') USER('%s') PASSWORD('%s')                       
0232.00      CONVERT(*NO) LOG(*NO)", obj, obj, USER, PASSWRD);                    
0233.00      system(cmd);                                                         
0234.00    }/*FTP 転送 */                                                         
0235.00    /*( IFS のファイルを削除する )*/                                       
0236.00    sprintf(cmd, "RMVLNK OBJLNK('/TEST/%s.FILE')", obj);                   
0237.00    system(cmd);                                                           
0238.00    saveSU ++;                                                             
0239.00 }                                                                         
0240.00 /**********************************************************/   
0241.00 void SendMessage(char* Message, char* Status, char* Pgmque)    
0242.00 /**********************************************************/   
0243.00 {                                                              
0244.00   char msg_id[7];                                              
0245.00   char msg_fl_name[20];                                        
0246.00   char msg_data[3000];                                         
0247.00   int msg_data_len;                                            
0248.00   char msg_type[10];                                           
0249.00    int  pgm_stk_cnt;                                           
0250.00   char msg_key[4];                                             
0251.00    char pgm_que[10];                                           
0252.00                                                                
0253.00     memset(msg_id, 0, sizeof(msg_id));                         
0254.00     strcpy(msg_id, "CPF9897");                                 
0255.00     memset(msg_fl_name, 0, sizeof(msg_fl_name));               
0256.00     strcpy(msg_fl_name, "QCPFMSG   QSYS      ");               
0257.00     memset(msg_data, 0, sizeof(msg_data));                     
0258.00     strcpy(msg_data, Message);                                 
0259.00     msg_data_len = triml(Message, ' ');                        
0260.00     strcpy(msg_type, Status);                                  
0261.00     strcpy(pgm_que, Pgmque);                                   
0262.00     if(strncmp(Pgmque, "*EXT      ", 10) == 0)                 
0263.00       pgm_stk_cnt = 0;                                         
0264.00     else pgm_stk_cnt = 1;                                             
0265.00     memset(msg_key, 0x40, sizeof(msg_key));                           
0266.00     errcode.BYTESPRO = errcode.BYTESAVL = 0;                          
0267.00     QMHSNDPM(msg_id, msg_fl_name, msg_data, msg_data_len, msg_type,   
0268.00          pgm_que, pgm_stk_cnt, msg_key, &errcode);                    
0269.00 }                                                                     
0270.00 /***********************/                                             
0271.00 void  LRRTN(char* argv[])                                             
0272.00 /***********************/                                             
0273.00 {                                                                     
0274.00    if(bLR == TRUE) return;                                            
0275.00    bLR = TRUE;                                                        
0276.00    strcpy(argv[2], ERR);                                              
0277.00    strcpy(argv[3], msg);                                              
0278.00 }                                                                     
【 解説 】

コンパイルは

CRTBNDC PGM(MYLIB/SAVUSRIFS) SRCFILE(MYSRCLIB/QCSRC) AUT(*ALL)

のようにして行う。

SAVUSRIFS はディレクトリー( DIR )だけを保管の対象としている。
ストリーム・ファイル( stmf )は保管の対象とはしていないが
保管することもできる。

0135.00           saveIFS(entry->d_name, &objtype[1], size);

という saveIFS 関数で保管を行っている。

まず最初に

0208.00    sprintf(cmd, "CHKOBJ  OBJ(IFSLIB/%s) OBJTYPE(*FILE)", obj);     
0209.00    if(system(cmd) == ERROR){/* エラー */                           
0210.00      sprintf(cmd, "CRTSAVF FILE(IFSLIB/%s) AUT(*ALL)", obj);       
0211.00      system(cmd);                                                  
0212.00    }/* エラー */
0213.00    /*( IFSLIB に *SAVF を作成する )*/                              
0214.00    sprintf(cmd, "CLRSAVF FILE(IFSLIB/%s)", obj);                   
0215.00    system(cmd);

でライブラリー: IFSLIB (これを予め作っておくこと)に *SAVF を作成して
CLRSAVF で消去しておく。

次に SAV コマンドを使って

0216.00    /*( IFSLIB の保管ファイルに IFS を保存する )*/                         
0217.00    sprintf(cmd, "SAV DEV('/QSYS.LIB/IFSLIB.LIB/%s.FILE') OBJ('/%s/*')",   
0218.00         obj, ifs);                                                        
0219.00    system(cmd);

のようにして *SAVF に IFS を保管する。
変数 ifs とは IFS の名前( 10桁以上も可 )、
obj とはそれを 10 桁以内の変数として決めたものである。

さらに

0221.00      /*( IFS に保管ファイルを転送する )*/                                 
0222.00      sprintf(cmd,                                                         
0223.00      "CPYTOSTMF FROMMBR('/QSYS.LIB/IFSLIB.LIB/%s.FILE')                  
0224.00  TOSTMF('/TEST/%s.FILE') STMFOPT(*REPLACE)", obj, obj);                   
0225.00      system(cmd);  

によって *SAVF を IFS にコピーしから

0226.00      /*( FTP でファイルを転送する )*/                                     
0227.00      memset(cmd, 0, sizeof(cmd));                                         
0228.00      sprintf(cmd,                                                         
0229.00       "SPOOLWTR/SNDFTP FRMADDRESS('*DFT')                                
0230.00  FROMFILE('/TEST/%s.FILE') TOADDRESS('192.168.1.8')                      
0231.00   TOFILE('/TEST/%s.IFS') USER('%s') PASSWORD('%s')                       
0232.00      CONVERT(*NO) LOG(*NO)", obj, obj, USER, PASSWRD);                    
0233.00      system(cmd)

で SpoolライターVer5.0 の SNDFTP コマンドによって PC サーバーに
Ftp 転送する。

弊社では 17 個の IFS をわずか 6 分間で PC サーバーへ Ftp 転送している。
テープ装置へのバックアップに比べれば圧倒的に速い。

※ SNDFTP コマンド SNDFTP コマンドは SpoolライターVer5.0 に付属している
ユーティリティーとなるコマンドである。
SpoolライターVer5.0 では CVTSPLF ( =スプールファイルの変換 )コマンドで
印刷スプールを PDF に変換して別の PC サーバーに転送することができるが
この CVTSPLF コマンドに組み込まれているのが SNDFTP コマンドである。
IBM i にも FTP コマンドが用意されているが IBM i どうしの FTP 転送を前提と
しているので PC サーバーへの転送には不向きである。