(************************************************************ ftp.ml Created : Thu Oct 2 00:26:01 2003 Last modified: Tue Oct 07 13:36:41 2003 Compile: ocamlc -g unix.cma str.cma mytcp.ml ftp.ml -o ftp # FTP Directory: sources/ocaml # ************************************************************) (** @author Takashi Masuyama ftp://ftp.turbolinux.co.jp/pub/TurboLinux/stable/tested/Workstation/7/i586 サーバーからの返答は 数字,スペースまたは-,メッセージ からなる。 数字のあとが - のときは返答が複数行にわたることを意味する。 メッセージは同じ数字から始まり、数字のあとがスペースで ある行で終る *) open Mytcp let hostname = "ftp.turbolinux.co.jp" let dir = "/pub/TurboLinux/stable/tested/Workstation/7/i586" let port = 21 let ack_regexp = Str.regexp ".*logged in." let passive_regexp = Str.regexp "\\([0-9]+\\),\\([0-9]+\\),\\([0-9]+\\),\\([0-9]+\\),\\([0-9]+\\),\\([0-9]+\\)" let end_line_regexp = Str.regexp "^[0-9]+ " let receive_ftp_message socket = let rec iter m = let line = receive_one_line socket in if Str.string_match end_line_regexp line 0 then m^line else iter (m^line) in iter "" ;; let login ~user ~password ~cmdsocket = let user_message = "USER " ^ user ^ "\r\n" in let password_message = "PASS " ^ password ^ "\r\n" in begin ignore (receive_ftp_message cmdsocket); ignore (send_string cmdsocket user_message); ignore (receive_ftp_message cmdsocket); ignore (send_string cmdsocket password_message); let ack = receive_ftp_message cmdsocket in Str.string_match ack_regexp ack 0 end ;; open Unix let get_passive_connection ~cmdsocket = begin ignore (send_string cmdsocket "PASV\n\r"); let target = receive_one_line cmdsocket in ignore (Str.search_forward passive_regexp target 0); let ipstr = (Str.matched_group 1 target)^"."^(Str.matched_group 2 target) ^"."^(Str.matched_group 3 target)^"."^(Str.matched_group 4 target) in let fst = Str.matched_group 5 target in let snd = Str.matched_group 6 target in let port = ((int_of_string fst) * 256) + (int_of_string snd) in let addr = inet_addr_of_string ipstr in try let resultsock = Unix.socket PF_INET SOCK_STREAM 0 in Unix.connect resultsock (ADDR_INET(addr, port)); resultsock with Unix.Unix_error (m, _, _) -> print_endline (Unix.error_message m); exit 1 end ;; let list_passive ~directory ~cmdsocket = let datasocket = get_passive_connection cmdsocket in ignore (send_string cmdsocket ("LIST "^directory^"\r\n")); receive_all datasocket ;; let quit ~cmdsocket = ignore (send_string cmdsocket "QUIT\r\n") ;; (*let _ = *) (* let user = "anonymous" in*) (* let password = "mamewo@dk9.so-net.ne.jp" in*) (* let cmdsocket = Mytcp.connect hostname port in*) (* begin*) (* ignore (login ~user ~password ~cmdsocket);*) (* print_endline (list_passive ~directory:dir ~cmdsocket)*) (*(* else*)*) (*(* print_endline "failed"*)*) (* end*)