                             IP Socket Interface
                             ===================
Overview
--------
  In order to communicate with other internet applications (which may or may
not be on remote machines) Rabbit provides scritps with an inteface to TCP
stream sockets. A socket can be considered a virtual 2 way communication port.

   Currently Rabbit only provides an interface to "stream" and "listening"
sockets, other types such as UDP are not supported. Rabbit does however provide
different classifications for stream sockets, this is purely internal and has
nothing to do with the underlying interface.


Technical details
-----------------
   A stream socket to a reote host is established using either create_socket()
or create_socket_nonblock(). The latter differs only in that it does not freeze
the machine while the connection attempt is made. It should generally be used
in preference to create_socket(). Once the socket has been established its
internal type must be set before any data can be transferred. This is
accomplished by one of the define_socket_to_<type>() commands. If the socket is
closed by the remote host this is reported to the script via the socket_closed
entry point.

   A listening socket it extablished using create_listening_socket().
Connection attempts to the socket's local port will then be reported to the
script via the socket_connection_attempted entry point, which reports the handle of the socket resulting from the connection to the script. This handle can then be used exactly like one returned by create_socket.

   Should a socket call fail for any reason, then -1 is returned instead of a
socket handle (which will always be positive).


Commands
--------

int create_socket(int ip; int port)

   * Parameters:

       ip         - The remote IP address to which to attempt the connection.
       port       - The port number on the remote host.


   * Returns: Socket handle

   attempts to establish a socket to the specified IP address on the specified
port and does not return until this has been successfully accomplished or
failed. This can often take quite some time, during which the entire WIMP will
freeze. Therefore create_socket_nonblock() should be used in preference to this
command.


int create_socket_nonblock(int ip; int port)

   * Parameters:

       ip         - The remote IP address to which to attempt the connection.
       port       - The port number on the remote host.


   * Returns: Socket handle

   identical to create_socket except it returns immediately without the
connection having been established. Once it has been established it is reported
to the script via the socket_connection_attempted entry point. The Socket handle returned
by this call cannot be used for communication until that has occurred.

int create_listening_socket(var int port)

   * Parameters:

       port       - The local port number on which to listen for incoming
                    connections.
                    If this is 0 on entry any free port numbered 1024 or
                    greater will be used and port will set to the one actually
                    used on exit.

   * Returns: Socket handle

   creates a listening socket on the local machine. Incoming connection
attempts are reported via the socket_connection_attempted entry point.

int define_socket_to_text(int handle;   string terminator;
                          int termsize; int    flags)

   * Parameters:

       handle     - Socket handle
       terminator - One or more characters which are to be interpreted as a
                    line terminator (3 characters max).
       termsize   - The number of characters in the terminator (overrides the
                    string length if that is greater)
       flags      - Text mode socket flags:

                      Bit 0: Allow any one of the characters specified in
                             terminator as a line terminator rather than all of
                             together.

   * Returns: Non-zero for success, 0 for failure.

   prepares a socket for line based text communication. Incoming data is queued
until a valid line terminator is encountered, at which point the line excluding
the terminator is passed to the script via the line_from_socket entry point.
Data is sent to the socket using line_to_socket() described below.


int define_socket_to_get_file(int handle; string filename)

   * Parameters:

       handle     - Socket handle
       filename   - The full pathname of the output file

   * Returns: Non-zero for success, 0 for failure.

   directs all incoming data from a socket to a file. When the socket is closed either by the remote host or the script, then so too is the file. No data will ever be sent to the remote host.


int define_socket_to_dcc_get(int handle, string filename)

   * Parameters:

       handle     - Socket handle.
       filename   - The full pathname of the output file.

   * Returns: Non-zero for success, 0 for failure.

   identical to define_socket_to_get_file() except that the DCC protocol used by IRC clients is used to conduct the transfer.


int define_socket_to_send_file(int handle, string filename)

   * Parameters:

       handle     - Socket handle.
       filename   - The full pathname of the file to be sent.

   * Returns: Non-zero for success, 0 for failure.

   sends the contents of th specified file to the socket. Incoming data on the socket is ignored. This command can be used for IRC clients to DCC send files, therefore there is no need to a define_socket_to_dcc_send() command.

int define_socket_to_raw(int handle)

   * Parameters:

       handle     - Socket handle.

   * Returns: Non-zero for success, 0 for failure.

   causes all incoming data to be immediately reported via the data_from_socket entry point. Data is sent using the data_to_socket command. No characters in eitehr direction have any special meaning.


int define_sockets_to_proxy(int handle0; int handle1; int flags)

   * Parameters:

       handle0    - Socket handle.
       handle1    - Socket handle.
       flags      - Proxying flags.

                      Bit 0: Report traffic via the data_on_proxy entry point.

                    all other bits are reserved and must be 0.

   * Returns: Non-zero for success, 0 for failure.

   relays all data arriving on each socket to the other. It bit0 of the flags is set, then the script is notified of any data being relayed in this manner.

void line_to_socket(int handle, string line)

   * Parameters:

       handle     - Socket handle.
       line       - The line to send.

   sends a line of text to a text socket. If bit 0 of te flags was unset in the call to define_socket_to_text, then the line terminator is automatically appended. If not then it is the script's responsibility to do so if necessary.

void data_to_socket(int handle; string data)

   * Parameters:

       handle     - Socket handle.
       data       - The data to send.

   Similar to line_to_socket, but for "raw" rather than "text" sockets. The data string can contain any characters appropriate for the connection, including nulls or other control codes.

void close_socket(int handle)

   * Parameters:

       handle     - Socket handle

   closes a previously created socket.


Entry Points
------------

void socket_connection_attempted(int handle; int reason)

   * Parameters:

       handle     - Socket handle (as returned fromcreate_socket_nonblock).
       reason     - A code indicating success or reason for failure (currently
                    only <= 0 for failure, >0 for success)

   reports the completion non-blocking connection attempt. If reason >0, then the handle can be used for communication otherwise it is invalid.

void line_from_socket(int handle; string line)

   * Parameters:

       handle     - Socket handle.
       line       - The incoming line without the terminator

   reports an incoming line on a text socket to the script. Line can be null in which case a terminator with no preceding data will havebeen received


void data_from_socket(int handle; string data)

   * Parameters:

       handle     - Socket handle.
       line       - The incoming line without the terminator

   reports an incoming data on a data socket to the script.

void data_on_proxy(int handle0; int handle1; string data)

   * Parameters:

       handle0    - Handle of the socket on which the data arrived.
       handle1    - Handle of the socket to which it was relayed.
       data       - The relayed data.
   
   informs the script of data being relayed on a proxying socket pair. There is no need for the script to do anything in response to this, this entry point is called only becuasethe script has requested to be informed of traffic on the proxy by setting bit 0 of the flags (see the define_sockets_to_proxy() command).

NOTE: The order of teh socket handles passed to this entry point is determined
      by the direction of travel of this particular packet of data, *not* by
      the order in which they were passed to define_sockets_to_proxy().
