Docs GODI Archive
Projects Blog Link DB

Search GODI:


More options
File lib/ocaml/pkg-lib/netclient/telnet_client.mli GODI Package godi-ocamlnet
Library netclient
 
   Telnet_client.html    telnet_client.cmi_pretty    telnet_client.mli    Sources  
(* $Id: telnet_client.mli 459 2006-04-30 19:49:19Z gerd $
 * ----------------------------------------------------------------------
 *
 *)

(** Telnet client
 * 
 * This is a Telnet client providing the basic Telnet services. It
 * supports sending and receiving data (asynchronously), and the
 * negotiation of Telnet options, but it does not implement any option.
 *)

exception Telnet_protocol of exn;;
(** Wrapper for exceptions that already passed the exception handler. *)


type telnet_command =
    Telnet_data of string  (** User data *)
  | Telnet_nop             (** No operation *)
  | Telnet_dm           (** data mark *)
  | Telnet_brk          (** break *)
  | Telnet_ip           (** interrupt process *)
  | Telnet_ao           (** abort output *)
  | Telnet_ayt          (** are you there? *)
  | Telnet_ec           (** erase character *)
  | Telnet_el           (** erase line *)
  | Telnet_ga           (** Go ahead *)
  | Telnet_sb of char   (** Begin of subnegotiation *)
  | Telnet_se           (** End of subnegotation *)
  | Telnet_will of char (** Acknowledges that option is in effect *)
  | Telnet_wont of char (** Acknowledges that option is rejected *)
  | Telnet_do of char   (** Requests to turn on an option *)
  | Telnet_dont of char (** Requests to turn off an option *)
  | Telnet_unknown of char (** Unknown command *)
  | Telnet_eof          (** End of file *)
  | Telnet_timeout      (** Timeout event *)
(** A [telnet_command] is the interpretation of the octets in a Telnet
 * session, i.e. it is one level above the octet stream. See RFC 854
 * for an explanation what the commands mean. [Telnet_data] represents
 * the data chunks between the commands. Note that you do not need
 * to double octets having value 255; this is done automatically.
 * [Telnet_unknown] represents any command not covered by RFC 854, for
 * example the End-of-record-mark (introduced in RFC 885) would be
 * [Telnet_unknown '\239']. [Telnet_eof] represents the end of the octet
 * stream, useable in both directions. [Telnet_timeout] is added to the
 * input queue if I/O has not been happened for the configured period
 * of time.
 *)

type telnet_options =
    { connection_timeout : float;
      verbose_connection : bool;
      verbose_input : bool;
      verbose_output : bool;
    }
(** [telnet_options]: modifies the behaviour of the client. Do not mix these
 * options up with the options negotiated with the remote side.
 *
 * - [connection_timeout]:   After this period of time (in seconds) a
 *                           [Telnet_timeout] pseudo-command is added to
 *                           the input queue, and the connection is
 *                           aborted.
 * - [verbose_connection]:   Enables printing of connection events to stderr.
 * - [verbose_input]:        Enables printing of input events to stderr.
 * - [verbose_output]:       Enables printing of output events to stderr.
 *)


type telnet_negotiated_option =
    Telnet_binary       (** see RFC 856 *)
  | Telnet_echo         (** see RFC 857 *)
  | Telnet_suppress_GA  (** see RFC 858 *)
  | Telnet_status       (** see RFC 859 *)
  | Telnet_timing_mark  (** see RFC 860 *)
  | Telnet_ext_opt_list (** see RFC 861 *)
  | Telnet_end_of_rec   (** see RFC 885 *)
  | Telnet_window_size  (** see RFC 1073 *)
  | Telnet_term_speed   (** see RFC 1079 *)
  | Telnet_term_type    (** see RFC 1091 *)
  | Telnet_X_display    (** see RFC 1096 *)
  | Telnet_linemode     (** see RFC 1184 *)
  | Telnet_flow_ctrl    (** see RFC 1372 *)
  | Telnet_auth         (** see RFC 1416 *)
  | Telnet_new_environ  (** see RFC 1572 and 1571 *)
  | Telnet_option of int   (** all other options *)
(** [telnet_negotiated_option]: names for the most common options, and
 * the generic name [Telnet_option] for other options.
 *)

type telnet_option_state =
    Not_negotiated
  | Accepted
  | Rejected  (** *)
(** An option has one of three states:
 * - [Not_negotiated]: There was no negotiation about the option. This means
 *   that the option is turned off (but this client is allowed to reject
 *   it explicitly)
 * - [Accepted]: Both sides have accepted the option.
 * - [Rejected]: One side has rejected the option. This also means that the
 *   option is off, but the client refuses to send further acknoledgements
 *   that the option is off (to avoid endless negotiation loops).
 *)


val char_of_option : telnet_negotiated_option -> char
(** Converts the option name to the character representing it on the
 * octet-stream level.
 *)

val option_of_char : char -> telnet_negotiated_option
(** Converts a character representing an option to the internal option
 * name.
 *)


type telnet_connector =
    Telnet_connect of (string * int)
  | Telnet_socket of Unix.file_descr (** *)
(** Connectors:
 * - [Telnet_connect(host,port)]: The client connects to this port.
 * - [Telnet_socket s]: The client uses an already connected socket.
 *
 * Why [Telnet_socket]? Telnet is a symmetrical protocol; client and servers
 * implement the same protocol features (the only difference is the
 * environment: a client is typically connected with a real terminal; a server
 * is connected with a pseudo terminal). This simply means that this
 * implementation of a client can also be used as a server implementation.
 * You need only to add code which accepts new connections and which passes
 * these connections over to a [telnet_session] object via [Telnet_socket].
 *)


(** A telnet session *)
class telnet_session :
  object
    (** Overwiew
     *
     * The [telnet_session] object has two queues, one for arriving data,
     * one for data to send.
     * Once the session object is attached to an event system, it connects
     * to the remote peer, and processes the queues. Input is appended to
     * the input queue; output found on the output queue is sent to the
     * other side.
     * If input arrives, a callback function is invoked.
     * You may close the output side of the socket by putting [Telnet_eof]
     * onto the output queue.
     * Once the EOF marker has been received, a [Telnet_eof] is appended to
     * the input queue, and the connection is closed (completely). The
     * session object detaches from the event system automatically in this
     * case.
     * 
     * {b Hints}
     *
     * Set an input handler as callback function in the session object.
     * The input handler is called when new input data have been arrived.
     * It should inspect the input queue, process the queue as much as
     * possible, and it should remove the processed items from the queue.
     * While processing, it may add new items to the output queue. 
     *
     * If you are not within the callback function and add items to the
     * output queue, the session object will not detect that there are
     * new items to send - unless you invoke the [update] method.
     *
     * If you want option negotiation, it is the simplest way to use
     * the special option negotiation methods. Configure the options
     * as you want (invoking [enable], [disable] etc), but do not forget
     * to modify the way input is processed. Every [Telnet_will], [_wont],
     * [_do], and [_dont] command must be passed to [process_option_command].
     *)

    method set_connection : telnet_connector -> unit
	(** Sets the host name and the port of the remote server to contact. *)

    method set_event_system : Unixqueue.event_system -> unit
	(** Sets the event system to use. By default, a private event system
	 * is used.
	 *)

    method set_callback : (bool -> unit) -> unit
	(** Sets the callback function. This function is called after new
	 * commands have been put onto the input queue. 
	 * The argument passed to the callback function indicates whether
	 * a 'Synch' sequence was received from the remote side or not.
	 *
	 * {b Note Synch:} If the client sees a data mark command it will assume
	 * that it is actually a Synch sequence. The client automatically
	 * discards any [Telnet_data] commands from the input queue (but not
	 * [Telnet_data]s inside subnegotiations). The data mark command
	 * itself remains on the queue.
	 *)

    method set_exception_handler : (exn -> unit) -> unit
	(** Sets the exception handler. Every known error condition is
	 * caught and passed to the exception handler.
	 * The exception handler can do whatever it wants to do. If it
	 * raises again an exception, the new exception is always propagated
	 * up to the caller (whoever this is). Often the caller is the
	 * event system scheduler (i.e. [Unixqueue.run]); see the documention
	 * there.
         *
	 * If you do not set the exception handler, a default handler is
	 * active. It first resets the session (see method [reset]), and
	 * then wraps the exception into the [Telnet_protocol] exception,
	 * and raises this exception again.
	 *)

    method output_queue : telnet_command Queue.t
        (** The queue of commands to send to the remote side. If you add new
	 * commands to this queue, do not forget to invoke the [update]
	 * method which indicates to the event system that new data to
	 * send is available.
	 * After commands have been sent, they are removed from the queue.
	 *)

    method input_queue : telnet_command Queue.t
        (** The queue of commands received from the remote side. This class
	 * only adds commands to the queue (and invokes the callback 
	 * function). The user of this class is responsible for removing
	 * commands from the queue which have been processed.
	 *)

    method get_options : telnet_options
        (** Get the configuration options. *)

    method set_options : telnet_options -> unit
	(** Set the configuration options. *)

    method reset : unit -> unit 
        (** Closes the connection immediately and empties all queues.
	 * All negotiated options are reset, too.
	 *)