FTX

0.はじめに
FTXは Kris Jamsa,ph.D. の著作 Internet Programming ,1995 のWinSock用FTPプロトコルを基にLinux/UNIX 用に改訂した作品である。
この著作は、Windows3.1の時代にインターネットプログラムの記述の方法をC言語とVBを利用して説明した専門書であるが、内容の利用に制限は無く今回のような改訂にも問題は無いと考えられる。（私はPDSであると確信している）
元々のプログラムは Windows用C言語とVisual Basic で記述されていたため、それに変更加筆し、C++で記述し直してクラス化し、PopMsg クラス ListBox クラスと OpenFileListBoxクラスを新たに追加したものである。
また、FTX はC言語とC++言語から呼び出せるようクラスライブラリ化されている。
frmSockFTPクラスにあるネイティブなFTPプロトコルコードは Kris Jamsa,ph.D. の記述したコードに様々なLinux 用のコードを追加したが、本当は、彼に敬意を表する意味においてブラックボックス化すべきであろうが、あえて未だ未熟な私のコードには到らぬところが多々あると所存するが今回そのコードを公開することにする。
2009年8月2日　Shigeki Ono


1.  ローカルミニファイラー

'X'と 'S' でローカルミニファイラーを起動し SEND(STOR)を実行出来る。
ローカルミニファイラーからは TAB で複数選択し、'' で送信を行う。
ローカルミニファイラーから 'p' で単独フィルの送信を行う。
その他の機能は cw の LocalTreeクラス、AseEditorクラス、FTXのOpenFileListBoxクラスとFrmSockFTPクラスを除いてほぼ準じる。

ローカミニルファイラー

	 H  ヘルプを表示
	 v  ファイルを表示
	 e  ファイルを編集
	 f  EUC -> SHIFT-JIS
	 TABキーでファイルを選択
	 p  ファイルを送信
	^P  選択ファイルを送信
	 m  ディレクトリを作成
	 r  ディレクトリを削除
	^R  ファイルを削除
	^W^W  選択したファイルを削除
	 c  ディレクトリを移動
	^O  移動ディレクトリ入力
	 F  SHIFT-JIS -> EUC
	 M  ファイル移動/名前変更
	^A  属性を変更
	^B  MiniFiler を起動した場所に
	^H  $HOME に戻る
	 -  以前に移動した場所に移動
	 +  以前に移動した場所から移動
	 n  検索を開始。入力は '/' で

	 i  ひとつ上へ",
	 S  画面の更新",
	^E  vi の実行",
	 t  画面の先頭へ",
	 g  最後尾に",
	 !  シェルモードに",
	 2  アクセス時刻表示",
	 9  作成年月表示",
	 0  作成時刻表示",
	 1  メニュー表示切替",
	 u  半画面上に",
	 d  半画面下に",
	 j  一行下に",
	 k  一行上に",
	 G  画面最後尾に",
	 :  .ファイルの非表示",
	 \\ カレントツリー",
	^K  ブックマークに位置を保存
	 ~  ブックマークメニューを開く
	 T  tar -xzf を実行
	 ^T tar -czf を実行
	 ^Y 複数選択で tar -czf を実行
	 q で終了


2.  リモートファイラー

	'x''x' キーダブルで再接続
	'X''S' キーダブルでローカルファイラーに変身しTABにて選択したファイルを送信
		送信キーは ^P で行う 'p' だとカーソル位置のファイルだけを送信する。
	'X''E' キーダブルで hosts.ftx を vi で編集
	'X''R' キーダブルでTABにて複数選択したファイルを受信
	'W''W' キーダブルでTABにて複数選択したファイルを削除
	TAB でファイルを選択（ディレクトリは選択出来ない）
	'R' でファイルの受信を行う。（選択しているファイルのみ）
	'c' でディレクトリを移動
	'i' でひとつ上のディレクトリに移動
	'e' でファイルを編集
	'v' で画像ファイルを表示（拡張子によってはブラウザを表示）
	'^A' でファイルの属性変更
	'^R' でファイルの削除。
	'r' でディレクトリの削除
	'm' でディレクトリの作成
	'M' でファイル名の変更
	'L' でイミディエイトウインドウに移動（'q'で戻る）
	'/' でファイル検索、'n' で再検索
	'S' でファイルの送信（ファイル名入力の送信）
	'j' と 'k' キーでファイラーカーソルの移動
	'g' で画面最下行へ移動",
	't' で画面トップに移動"
	'q' で終了


3.FTXクラスライブラリ

基底クラス PopMsg から派成する FrmSockFTP クラスがFTX の基本クラスといって良いだろう。
このクラスには private なFTPプロトコルメンバー関数の他、インターフェースとして public なFTP通信用関数を定義した。public なこれら intDo お呼び strDo で始まる FTP コマンドを送信する関数はこのクラスライブラリの外から利用可能である。
つまり、本ライブラリは C言語、C++言語の他様々な言語から利用可能となっている。

	FTPプロトコルを使用して通信を行う。直接呼出が可能な関数。(ftpcom.cc)
--------------------------------------------------------------------------------
	int intDoFirstConnect(void);

	最初の接続を行う関数
	失敗：1
	成功：0
	返り値：サーバ応答コードが class PopMsg の ImmediateMsgバッファに保存され、ImmediateListBox に AddItem() される。
	この関数は intDoUSERCommand()のサーバ戻り値331の後IntDoPASSCommand()を実行する。 この戻り値が230だった場合、strDOSYSTCommand()を実行してからintDoListCommand()の実行で終了する。

--------------------------------------------------------------------------------
	int intDoReConnect(char *strDirectory);

	再接続を行う関数 strDirectory にはカレントディレクトリを格納する
	失敗：1
	成功：0
	返り値：サーバ応答コードが class PopMsg の ImmediateMsgバッファに保存され、ImmediateListBox に AddItem() される。
	この関数は intDoUSERCommand()のサーバ戻り値331の後IntDoPASSCommand()を実行する。 この戻り値が230だった場合、strDOSYSTCommand()を実行してからintDoListCommand()の実行で終了する。
	intDoFirstConnect()と違うのは、再接続時切断前のディレクトリに戻れることである。

--------------------------------------------------------------------------------
    int intDoDisconnect(void);

	QUIT コマンドを送信する関数
	成功：0
	返り値：サーバ応答コードが class PopMsg の ImmediateMsgバッファに保存され、ImmediateListBox に AddItem() される。

--------------------------------------------------------------------------------
	u_int intDoListCommand(char *strListCommand);

	LIST コマンドを送信して結果を LIST.CMD というファイルで受け取る
	この時PASVモードの場合は2番目のソケット hDataSocke はサーバからの接続受付はしないでクライアント側からの接続として hDataSocket を使用する。
	返り値：サーバ応答コードが class PopMsg の ImmediateMsgバッファに保存され、ImmediateListBox に AddItem() される。
	この関数は内部でデータ接続用のソケットを作成する private な CreateListenSocket() 関数を呼び出し、そのソケットを元に データ転送用のデータソケットを作成する。
	この時、PASSIVE な接続の指定が (FTXファイラーの場合は /home/cms/etc/hosts.ftx 等で)あったなら、受け側ポート番号を指定せずサーバーに PASV コマンドを送信する。
	そのサーバーからの応答にあるポート番号を利用して、データソケットからサーバーへの接続を行う。
	接続指定が ACTIVE な場合は待ち受けソケットにてサーバーからの受信を待つ。
	PASSIVE,ACTIVE共、サーバとの接続が完了したならデータ転送用データチャネル(PORT)にファイルリストの受信を行う。受信されたファイルリストは public な txtTmpDirListFile バッファに格納されたディレクトリに保存される。
	この関数では終了までに必ず作成された待ち受けソケットとデータソケットはクローズされる。


--------------------------------------------------------------------------------
	u_int intDoRMFILECommand(char *strDirName);

	DELE コマンドを送信する。strFileName には削除するファイル名を入れる。
	返り値：サーバ応答コードが ImmediateListBox に AddItem() される。
	完了応答コード：250

--------------------------------------------------------------------------------
	u_int intDoRMDIRCommand(char *strDirName);

	RMD コマンドを送信する。strDirName には削除するディレクトリ名を入れる。
	返り値：サーバ応答コードが ImmediateListBox に AddItem() される。
	完了応答コード：250

--------------------------------------------------------------------------------
	u_int intDoMKDIRCommand(char *strDirName);

	MKD コマンドを送信する。strDirName には作成するディレクトリ名を入れる。
	返り値：サーバ応答コードが ImmediateListBox に AddItem() される。
	完了応答コード：230

--------------------------------------------------------------------------------
	u_int intDoRNFRCommand(char *strDirName);

	このコマンドは mv (rename)を行う。RNTOと併用して実行しなければならない。
	RNFR コマンドを送信する。strDirName には作成するディレクトリ名を入れる。
	返り値：サーバ応答コードが ImmediateListBox に AddItem() される。
	完了応答コード：350

--------------------------------------------------------------------------------
	u_int intDoRNTOCommand(char *strDirName);

	このコマンドは mv (rename)を行う。RFNRと併用して実行しなければならない。
	MKD コマンドを送信する。strDirName には作成するディレクトリ名を入れる。
	返り値：サーバ応答コードが ImmediateListBox に AddItem() される。
	完了応答コード：250

--------------------------------------------------------------------------------
	u_int intDoPASSCommand(void);

	PASS コマンドを送信する。この時 class frmSockFTP の txtPassword バッファにはパスワードが格納されている必要がある。
	返り値：サーバ応答コードが ImmediateListBox に AddItem() される。
	完了応答コード：250
	ログイン失敗応答コード：530

--------------------------------------------------------------------------------
	u_int intDoRETRCommand(char *strFileName, int optImage);

	RETR コマンドを送信する。strFileName には受信するファイル名を入れる。
	この関数は内部的に strTransferGetFile() でローカルファイルを同じ名前でオープン(write)する。受信は　1024 バイトで行われる。失敗した場合はファイルは途中でクローズされ、エラーメッセージを表示する。
	この時PASVモードの場合は2番目のソケット hDataSocke はサーバからの接続受付はしないでクライアント側からの接続として hDataSocket を使用する。
	返り値：サーバ応答コードが class PopMsg の ImmediateMsgバッファに保存され、ImmediateListBox に AddItem() される。
	また、この関数は intDoListCommand() の動作と良く似ている。最も違うのは intDoListCommand() がテンポラリにファイルを作成するのに対してこの関数ではカレントディレクトリに受信するファイルを作成することである。

--------------------------------------------------------------------------------
	u_int intDoSTORCommand(char *strFileName, int optImage);

	STOR コマンドを送信する。strFileName には受信するファイル名を入れる。int optImage には 0:ASCII 1:BINALY を入れる。
	この関数は内部的に strTransferPutFile() でローカルファイルを同じ名前でオープン(read)する。送信は　512 バイトで行われる。失敗した場合はファイルはクローズされ、エラーメッセージを表示する。
	処理的に、送信するファイルが存在しないファイル名であっても送信してしまう（零1バイトのファイルを）ので、送信時、送信するファイルが本当にあるのかどうかをチェックする処理が必要になる。
	この時PASVモードの場合は2番目のソケット hDataSocke はサーバからの接続受付はしないでクライアント側からの接続として hDataSocket を使用する。
	返り値：サーバ応答コードが class PopMsg の ImmediateMsgバッファに保存され、ImmediateListBox に AddItem() される。

--------------------------------------------------------------------------------
	u_int intDoEDITCommand(char *strFileName, char *strEditFileName, int optImage);

	この関数は intDoRETRCommand() と intDoSTORCommand() を併用して使用する関数である。	
	この関数の処理が違うのは、受信時に書き込まれるファイル名をテンポラリファイルとして設定していることである。関数の第一引数 strFileName は受信するサーバー側のファイル名であり、第二引数 strEditDir は class frmSockFTP の txtEditDir バッファのコピーを利用する。使用方法のサンプルは ftpfrm.cc にある。

--------------------------------------------------------------------------------
	u_int intDoVIEWCommand(char *strFileName, char *strViewFileName);

	この関数も intDoRETRCommand() と intDoSTORCommand() を併用して使用する関数である。違うのはバイナリ表示を行うためにバイナリのみの受信を行う。
	使用方法のサンプルは ftpfrm.cc にある。

--------------------------------------------------------------------------------
	u_int intDoUSERCommand(void);

	USER コマンドを送信する。class frmSockFTP の txtUserId バッファにはユーザIDを入れる。
	返り値：サーバ応答ストリングが ImmediateListBox に AddItem() される。
	完了応答コード：331

--------------------------------------------------------------------------------
	char *strDoCDUPCommand(void);

	CDUP コマンドを送信する。
	返り値：サーバ応答ストリングが ImmediateListBox に AddItem() される。
	完了応答コード：250

--------------------------------------------------------------------------------
	char *strDoXCUPCommand(void);

	XCUP コマンドを送信する。
	返り値：サーバ応答ストリングが ImmediateListBox に AddItem() される。
	完了応答コード：250

--------------------------------------------------------------------------------
	char *strDoSITECommand(char *siteCommand,char *strMode,char *strFileName);

	SITE コマンドを送信する。第一引数がコマンド、第二引数は属性(644 755 等)、第三引数は対象ファイルの名前である。
	返り値：サーバ応答ストリングが ImmediateListBox に AddItem() される。
	完了応答コード：200

--------------------------------------------------------------------------------
	char *strDoCWDCommand(char *strDirectory);

	CWD コマンドを送信する。第一引数は移動するディレクトリ名である。パスでも指定出来る。
	返り値：サーバ応答ストリングが ImmediateListBox に AddItem() される。
	完了応答コード：250

--------------------------------------------------------------------------------
	char *strDoPWDCommand(void);

	PWD コマンドを送信する。
	返り値：サーバ応答ストリングが ImmediateListBox に AddItem() される。
	完了応答コード：257
	サンプルソースの ftpfrm.cc では、このコマンドはファイラーウインドウのタイトルに現在のパス名を表示するために利用されている。

--------------------------------------------------------------------------------
	char *strDoSYSTCommand(void);

	SYST コマンドを送信する。
	返り値：サーバ応答ストリングが ImmediateListBox に AddItem() される。
	完了応答コード：215

--------------------------------------------------------------------------------
	int intDoNOOPCommand(void);

	NOOP コマンドを送信する。
	返り値：200	正常
	それ以外は切断されています。

[参考]
AddItem()はリストボックスクラスのメンバ関数である。 ImmediateListBox  や FilerListBox に文字列を追加する。
クラス内で利用出来るデータは ftx.h の中の frmSockFTP クラスに説明文があるので、それを参照されたし。
利用方法は ftpfrm.cc を参照すること。

4.ホスト定義パスワードファイル

サンプルプログラム FTX はホスト定義ファイルを利用している。
以下がその見本である。
コロンで区切られた内容は以下になる。

ホスト名:ユーザID:パスワード:接続時移動するディレクトリ名:リストコマンドとオプション:イメージタイプ(ascii-0 bynaly-1) :アクティブFTPかパッシブFTPか:サーバへの再接続時間（秒）:テキストエディタを設定:画像ビューワーを設定:ブラウザを設定:

localhost:cms:******:/:LIST -aL:1:Active:600::::
127.0.0.1:cms:******:/:LIST:1:Active:300::::
hp.vector.co.jp:VA005185:**********:/:LIST -aL:1:PASSIVE:300:emacs:::
upload.vector.co.jp:anonymous:xkgpm804@ybb.ne.jp:pack/incoming:LIST -aL:1:ACTIVE:400:vi::icewiasel:
ftp.22.pro.tok2.com:prowler:********:/public_html:LIST:1:passive:300::::

※ hosts.ftx ファイルのパスワードは暗号化されておりません。セキュリティーは cms へのログインパスワードだけになっていますので、このファイルのパーミッションは必ず 600 としておいてください。


