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 を利用することが
できる。
------------------------------------------------------------------------------------ 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(' ログ表示 ') ------------------------------------------------------------------------------------
----------------------------------------------------------------------------------- 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 #include0019.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 ユーザーに役立ちそうなソースはこれからも公開していく予定である。