Tools

28. IFS ファイルを送信する SNDFTP

Tools の「8. SNDFTPF iSeries から PCサーバーへのファイル転送」を紹介したが
以前の SNDFTPF コマンドはライブラリー・システムのデータ・ベースを
Ftp によって転送する Ftpクライアントであった。
しかし、実際のところ IFS に保管したPDF ファイルを転送する等々のように
IFS ファイルを PCサーバーへ転送するほうが機会として多いのかも知れない。
そこで今回は、弊社製品「Spoolライター Ver4.0」に実際に実装されていて
ユーティリティーとしても使用されている「SNDFTP」コマンドを紹介する。
SNDFTP コマンドは製品に使われている以上、現実的であり、エラー・チェックや
モニター・ログ等の実用レベルに達している。

読者がコンパイルすれば、直ちに実用レベルとして使用することができる。
System i にも FTPコマンドが用意されているがユーザー名が 10桁以下であることなどを
見ても PCサーバー相手に考えられたものではないようである。
そこでやはり PCサーバーを相手とする Ftpクライアントが必要となってくる。
今回、紹介する SNDFTP コマンドの実行プログラム : SNDFTP は「オーム社開発局出版:
TCP/IP Java ネットワークプログラミング」に紹介されていた Java ソースを参考にして
筆者が ANSI-C 言語で書き直して、さらに実用レベルに改良を加えたものである。
C言語がわからない人であってもコンパイルさえすれば直ちに SNDFTP を利用することが
できる。

【 コマンド : SNDFTP 】
------------------------------------------------------------------------------------
0001.00              CMD        PROMPT('FTP ファイル送信 ')                         
0002.00              PARM       KWD(FRMADDRESS) TYPE(*CHAR) LEN(15) +               
0003.00                           DFT('192.168.1.1') +                              
0004.00                           PROMPT(' ホスト IP アドレス ')                    
0005.00              PARM       KWD(FROMFILE) TYPE(*CHAR) LEN(128) +                
0006.00                           CASE(*MIXED) PROMPT(' ホストファイル・パス ')     
0007.00              PARM       KWD(TOADDRESS) TYPE(*CHAR) LEN(15) +                
0008.00                           DFT('192.168.1.1') +                              
0009.00                           PROMPT(' 相手先 IP アドレス ')                    
0010.00              PARM       KWD(TOFILE) TYPE(*CHAR) LEN(128) +                  
0011.00                           CASE(*MIXED) PROMPT(' 相手先ファイル・パス ')     
0012.00              PARM       KWD(USER) TYPE(*CHAR) LEN(13) DFT(*NONE) +          
0013.00                           SPCVAL((*NONE)) CASE(*MIXED) +                    
0014.00                           PROMPT(' 遠隔ユーザー ID')                        
0015.00              PARM       KWD(PASSWORD) TYPE(*CHAR) LEN(13) DFT(*NONE) +      
0016.00                           SPCVAL((*NONE)) CASE(*MIXED) +                    
0017.00                           PROMPT(' 遠隔パスワード ')                        
0018.00              PARM       KWD(CMD) TYPE(*CHAR) LEN(3) RSTD(*YES) +            
0019.00                           DFT(PUT) VALUES(GET PUT) +                        
0020.00                           PROMPT(' 送信または受信 ')                        
0021.00              PARM       KWD(CONVERT) TYPE(*CHAR) LEN(4) RSTD(*YES) +        
0022.00                           DFT(*NO) VALUES(*YES *NO) PMTCTL(*PMTRQS) +       
0023.00                           PROMPT(' データの EBCDIC/ASCII 変換 ')            
0024.00              PARM       KWD(LOG) TYPE(*CHAR) LEN(4) RSTD(*YES) +   
0025.00                           DFT(*YES) VALUES(*YES *NO) +             
0026.00                           PMTCTL(*PMTRQS) PROMPT(' ログ表示 ')     
------------------------------------------------------------------------------------
【 C : SNDFTP 】
-----------------------------------------------------------------------------------
0001.00 /***********************************************************************/  
0002.00 /*                                                                     */  
0003.00 /*   SNDFTP : Send a IFS file to PC via Ftp.                           */  
0004.00 /*                                                                     */  
0005.00 /*            Office Quattro Co.ltd 2003.10.13 13:55:38 created        */  
0006.00 /*                                                                     */  
0007.00 /*            SNDFTP は FTP クライアントとして IFS のファイルを        */  
0008.00 /*            PC や PC サーバーに送信します。                          */  
0009.00 /*                                                                     */  
0010.00 /*  create :  CRTCMOD  ASNET.MOD/SNDFTP                                */  
0011.00 /*            CRTPGM   SPOOLWTR/SNDFTP                                 */  
0012.00 /*                                                                     */  
0013.00 /***********************************************************************/  
0014.00 #pragma comment(COPYRIGHT, "Panel-Worker Spool-Writer      (C) CopyRight \ 
0015.00 Office Quattro.Corp. 2003- All right reserved. Users Restricted \          
0016.00 Rights - Use, duplication or disclosure restricted by Office Quattro \     
0017.00 Corp. Licenced Materials-Property of Office Quattro.")                     
0018.00 #include                                                          
0019.00 #include <stdlib.h>                                                        
0020.00 #include <string.h>                                                        
0021.00 #include <QMHSNDPM.h>                                                      
0022.00 #include <xxcvt.h>                                                         
0023.00 #include <micomput.h> /* triml */                                          
0024.00 #include <sys/socket.h>                                               
0025.00 #include <sys/types.h>                                                
0026.00 #include <netinet/in.h>                                               
0027.00 #include <netinet/tcp.h>                                              
0028.00 #include <arpa/inet.h>                                                
0029.00 #include <QDCXLATE.h>                                                 
0030.00 #include <ctype.h>                                                    
0031.00 #include <sys/stat.h>                                                 
0032.00 #include <fcntl.h>                                                    
0033.00 #include <xxdtaa.h>                                                   
0034.00                                                                       
0035.00 #define TRUE         0                                                
0036.00 #define FALSE       -1                                                
0037.00 #define FTP_PORT 21                                                   
0038.00 #define DTA_PORT 3100                                                 
0039.00 #define RCVBUF_LEN 25600                                              
0040.00 #define TCP_BUFFSIZ 1492                                              
0041.00 /* _HEAP_SIZE = 2097152;    Set size of fast heap to 2048K */         
0042.00 #define HP256 262144                                                  
0043.00 #define  MAX_HEAP_SIZE  16711600                                      
0044.00 /*******************************************************************/ 
0045.00 /*    define Functions                                             */ 
0046.00 /*******************************************************************/ 
0047.00 int  GetFtpConnection(char ipaddress[16], char user[14],              
0048.00                                           char password[14]);          
0049.00 int  Check(void);                                                      
0050.00 int  OpenGetFile(char* ToFile, char type, char* cmd);                  
0051.00 int  TransferFile(char* FromFile);                                     
0052.00 int Read(int nCount, char* cStep);                                     
0053.00 int GetReply(char* cStep, int bResponse);                              
0054.00 int ReadCtl(int nCount, char* cStep);                                  
0055.00 int Send(char* buff, int length, char* cStep);                         
0056.00 void CloseFtp(void);                                                   
0057.00 void CloseDataSocket(void);                                            
0058.00 void SendMessage(char* Message, char* Status, char* Pgmque);           
0059.00 typedef _Packed struct {                                               
0060.00    int  BytesPro;                                                      
0061.00    int  BytesAvl;                                                      
0062.00    char ExcpID??(7??);                                                 
0063.00    char pad;                                                           
0064.00    char ExcpData??(512??);                                             
0065.00 } ERRSTRUCTURE;     /* Define the error return structure            */ 
0066.00  ERRSTRUCTURE errcode;                                                 
0067.00  char fromaddress[16];                                                 
0068.00  char toaddress[16];                                                   
0069.00  char fromfile[129];                                                   
0070.00  char tofile[129];                                                     
0071.00  char user[14];                                                        
0072.00  char password[14];                                                       
0073.00  char cmd[4];                                                             
0074.00  char convert[5];                                                         
0075.00  char dsplog[5];                                                          
0076.00  unsigned char g_RcvBuf[RCVBUF_LEN];                                      
0077.00  char m_buf[RCVBUF_LEN];                                                  
0078.00  int m_rcvlen;                                                            
0079.00  int  sockfd;                                                             
0080.00  int  datafd;                                                             
0081.00  int  newfd;                                                              
0082.00  char m_cCRLF[] = {0x0d, 0x0a, 0x00};                                     
0083.00  int m_bFtp;                                                              
0084.00  int  dta_port;                                                           
0085.00  char host_ipaddress[16];                                                 
0086.00  int  bDataTransform;                                                     
0087.00                                                                           
0088.00 /********************************************************************/    
0089.00 /*                                                                  */    
0090.00 /*   SNDFTP  :   パラメータの記述                                   */    
0091.00 /*                                                                  */    
0092.00 /*   main:  parm 1. fromaddress[15]                                 */    
0093.00 /*          parm 2. fromfile[128]                                   */    
0094.00 /*          parm 3. toaddress[15]                                   */    
0095.00 /*          parm 4. tofile[128]                                     */    
096.00 /*          parm 5. user[13]                                        */
097.00 /*          parm 6. password[13]                                    */
098.00 /*          parm 7. cmd[3]                                          */
099.00 /*          parm 8. convert[4]                                      */
100.00 /*          parm 9. dsplog[4]                                       */
101.00 /*                                                                  */
102.00 /********************************************************************/
103.00                                                                       
104.00 void main(int argc, char *argv[]){                                    
105.00    char rtncod[7], licdta[20];                                        
106.00    char msg[512];                                                     
107.00    int length;                                                        
108.00                                                                       
109.00    system("ADDLIBLE SPOOLWTR");                                       
110.00    /*[ 入力パラメータを取得 ]*/                                       
111.00     memset(fromaddress, 0, sizeof(fromaddress));                      
112.00     memcpy(fromaddress, argv[1], 15);                                 
113.00     fromaddress[15] = 0x00;                                           
114.00     memset(fromfile, 0, sizeof(fromfile));                            
115.00     memcpy(fromfile, argv[2], 128);                                   
116.00     fromfile[128] = 0x00;                                             
117.00     memset(toaddress, 0, sizeof(toaddress));                          
118.00     memcpy(toaddress, argv[3], 15);                                   
119.00     toaddress[15] = 0x00;                                             
0120.00     memset(tofile, 0, sizeof(tofile));                 
0121.00     memcpy(tofile, argv[4], 128);                      
0122.00     tofile[128] = 0x00;                                
0123.00     memset(user, 0, sizeof(user));                     
0124.00     memcpy(user, argv[5], 13);                         
0125.00     user[13] = 0x00;                                   
0126.00     memset(password, 0, sizeof(password));             
0127.00     memcpy(password, argv[6], 13);                     
0128.00     password[13] = 0x00;                               
0129.00     memset(cmd, 0, sizeof(cmd));                       
0130.00     memcpy(cmd, argv[7], 3);                           
0131.00     cmd[3] = 0x00;                                     
0132.00     memset(convert, 0, sizeof(convert));               
0133.00     memcpy(convert, argv[8], 4);                       
0134.00     convert[4] = 0x00;                                 
0135.00     memset(dsplog, 0, sizeof(dsplog));                 
0136.00     memcpy(dsplog, argv[9], 4);                        
0137.00     dsplog[4] = 0x00;                                  
0138.00     /*[ 初期設定 ]*/                                   
0139.00      m_bFtp = FALSE;                                   
0140.00      bDataTransform = FALSE;                           
0141.00      if(Check() == FALSE){                             
0142.00        return;                                         
0143.00      }                                                 
144.00                                                                 
145.00     /*[ Ftp 開始 ]*/                                            
146.00     if(GetFtpConnection(toaddress, user, password) == FALSE){   
147.00        CloseFtp();                                              
148.00        getchar();                                               
149.00        return;                                                  
150.00     }                                                           
151.00     /*[ ファイルのオープン ]*/                                  
152.00     if(OpenGetFile(tofile, 'B', cmd) == FALSE){                 
153.00        CloseDataSocket();                                       
154.00        CloseFtp();                                              
155.00        getchar();                                               
156.00        return;                                                  
157.00     }                                                           
158.00     /*[ ファイルの転送 ]*/                                      
159.00     if(TransferFile(fromfile) == FALSE){                        
160.00        CloseDataSocket();                                       
161.00        CloseFtp();                                              
162.00        getchar();                                               
163.00        return;                                                  
164.00     }                                                           
165.00    /*  CloseDataSocket(); */                                    
166.00     CloseFtp();                                                 
167.00    if(strncmp(dsplog, "*YES", 4 ) == 0){                        
168.00        SendMessage(" ",  "*STATUS   ", "*EXT      ");         
169.00        printf(" ファイル転送が完了しました。 \n");            
170.00        printf(" 実行キーを押して終了してください。 \n");      
171.00     getchar();                                                
172.00     }                                                         
173.00      if(strncmp(cmd, "PUT", 3) == 0){/*PUT*/                  
174.00         length = triml(fromfile, ' ');                        
175.00         if(length > 0) fromfile[length] = 0x00;               
176.00         sprintf(msg, " ファイル %s の送信が完了しました。 ",  
177.00             fromfile);                                        
178.00         SendMessage(msg, "*COMP     ", "*PGMBDY   ");         
179.00      }/*PUT*/                                                 
180.00      else{/* 一般 GET, DIR */                                 
181.00         length = triml(tofile, ' ');                          
182.00         if(length > 0) tofile[length] = 0x00;                 
183.00         sprintf(msg, " ファイル %s の受信が完了しました。 ",  
184.00             tofile);                                          
185.00         SendMessage(msg, "*COMP     ", "*PGMBDY   ");         
186.00      }/* 一般 GET, DIR */                                     
187.00 }                                                             
                       :
                       :
                   ( 略 )
-----------------------------------------------------------------------------------
【 コンパイル 】
CRTBNDC MYLIB/SNDFTP SRCFILE(MYSRCLIB/QCSRC) AUT(*ALL)
【 解説 】

GetFtpConnection 関数で Ftp 接続を相手と開始して、指定されたローカル・ファイルを
OpenGetFile 関数でオープンしてから、TransferFile関数によってファイルを送信して
最後には CloseFtp関数で Socket を閉じている。
Ftp では Ftpプロトコルは PORT=21 で行われるが、実際のデータは PORT=3100 からを使用している。
PORT=3100 が他のクライアントによって使用中であれば次々と +1 して 3101, 3102, ... のようにして
空き PORT を探すように配慮されている。
SNDFTP のような例はもちろん IBM マニュアルにも載っていないが、弊社製品の機能で
IBM ユーザーに役立ちそうなソースはこれからも公開していく予定である。