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