sig
  exception FTP_protocol_error of exn
  exception FTP_protocol_violation of string
  type cmd_state =
    [ `Failure
    | `Init
    | `Pass_acct_seq
    | `Preliminary
    | `Proto_error
    | `Rename_seq
    | `Restart_seq
    | `Success
    | `User_acct_seq
    | `User_pass_seq ]
  type port =
    [ `Active of string * int * Unix.file_descr
    | `Passive of string * int
    | `Unspecified ]
  type form_code = [ `ASA | `Non_print | `Telnet ]
  type representation =
    [ `ASCII of Ftp_client.form_code option
    | `EBCDIC of Ftp_client.form_code option
    | `Image ]
  type structure = [ `File_structure | `Record_structure ]
  type transmission_mode = [ `Block_mode | `Stream_mode ]
  type state = {
    cmd_state : Ftp_client.cmd_state;
    ftp_connected : bool;
    ftp_data_conn : bool;
    ftp_user : string option;
    ftp_password : string option;
    ftp_account : string option;
    ftp_logged_in : bool;
    ftp_port : Ftp_client.port;
    ftp_repr : Ftp_client.representation;
    ftp_structure : Ftp_client.structure;
    ftp_trans : Ftp_client.transmission_mode;
    ftp_dir : string list;
  }
  type cmd =
    [ `ACCT of string
    | `ALLO of int * int option
    | `APPE of string * (Ftp_client.state -> Ftp_data_endpoint.local_sender)
    | `CDUP
    | `CWD of string
    | `Connect
    | `DELE of string
    | `HELP of string option
    | `LIST of
        string option *
        (Ftp_client.state -> Ftp_data_endpoint.local_receiver)
    | `MKD of string
    | `MODE of Ftp_client.transmission_mode
    | `NLST of
        string option *
        (Ftp_client.state -> Ftp_data_endpoint.local_receiver)
    | `NOOP
    | `PASS of string
    | `PASV
    | `PORT
    | `PWD
    | `QUIT
    | `REIN
    | `REST of string
    | `RETR of
        string * (Ftp_client.state -> Ftp_data_endpoint.local_receiver)
    | `RMD of string
    | `RNFR of string
    | `RNTO of string
    | `SITE of string
    | `SMNT of string
    | `STAT of string option
    | `STOR of string * (Ftp_client.state -> Ftp_data_endpoint.local_sender)
    | `STOU of unit -> Ftp_data_endpoint.local_sender
    | `STRU of Ftp_client.structure
    | `SYST
    | `TYPE of Ftp_client.representation
    | `USER of string ]
  type reply = int * string
  class ftp_client_pi :
    ?event_system:Unixqueue.event_system ->
    ?onempty:(Ftp_client.state -> unit) ->
    ?onclose:(unit -> unit) ->
    Unix.file_descr ->
    object
      method add_cmd :
        ?onreply:(Ftp_client.state -> Ftp_client.reply -> unit) ->
        Ftp_client.cmd -> unit
      method run : unit -> unit
      method send_abort : unit -> unit
      method state : Ftp_client.state
    end
  class type ftp_method =
    object
      method connect : (string * int) option
      method execute : Ftp_client.ftp_client_pi -> Ftp_client.state -> unit
    end
  exception FTP_method_failure of int * string
  class connect_method : host:string -> ?port:int -> unit -> ftp_method
  class login_method :
    user:string ->
    get_password:(unit -> string) ->
    get_account:(unit -> string) -> unit -> ftp_method
  class get_method :
    file:string ->
    representation:Ftp_client.representation ->
    store:(Ftp_client.state -> Ftp_data_endpoint.local_receiver) ->
    unit -> ftp_method
  class ftp_client :
    ?event_system:Unixqueue.event_system ->
    ?onempty:(unit -> unit) ->
    unit ->
    object
      method add :
        ?onsuccess:(unit -> unit) ->
        ?onerror:(exn -> unit) -> Ftp_client.ftp_method -> unit
      method run : unit -> unit
    end
end