NAME
    Net::AOLIM - Object-Oriented interface to the AOL Instant
    Messenger TOC client protocol

SYNOPSIS
    The really short form:

        use Net::AOLIM;
        $aim = Net::AOLIM->new('username' => $user,
                               'password' => $pass,
                               'callback' => \&handler);

        $aim->signon;

        $aim->toc_send_im($destuser, $message);

NOTES
    Error conditions will be stored in $main::IM_ERR, with any
    arguments to the error condition stored in $main::IM_ERR_ARGS.

    The hash %Net::AOLIM::ERROR_MSGS contains english translations
    of all of the error messages that are either internal to the
    module or particular to the TOC protocol.

    Errors may take arguments indicating a more specific failure
    condition. In this case, they will either be stored in
    $main::IM_ERR_ARGS or they will come from the server ERROR
    message. To insert the arguments in the proper place, use a
    construct similar to:

        $ERROR = $Net::AOLIM::ERROR_MSGS{$IM_ERR};
        $ERROR =~ s/\$ERR_ARG/$IM_ERR_ARGS/g;

    This assumes that the error code is stored in $IM_ERR and the
    error argument is stored in $IM_ERR_ARGS.

    All methods will return undef on error, and will set
    $main::IM_ERR and $main::IM_ERR_ARGS as appropriate.

DESCRIPTION
    This section documents every member function of the Net::AOLIM
    class.

  $Net::AOLIM->new()

    This is the Net::AOLIM Constructor.

    It should be called with following arguments (items with default
    values are optional):

        'username' => login
        'password' => password
        'callback' => \&callbackfunction
        'server' => servername (default toc.oscar.aol.com)
        'port' => port number (default 1234)
        'allow_srv_settings' => <1 | 0> (default 1)
        'login_server' => login server (default login.oscar.aol.com)
        'login_port' => login port (default 5198)
        'login_timeout' => timeout in seconds to wait for a response to the
                           toc_signon packet.  Default is 0 (infinite)
        'aim_agent' => agentname (max 200 char) 
                    Default is AOLIM:$Version 1.1$
                    There have been some reports that changing this 
                    may cause TOC servers to stop responding to signon 
                    requests

    callback is the callback function that handles incoming data
    from the server (already digested into command plus args). This
    is the meat of the client program.

    allow_srv_settings is a boolean that dictates whether the object
    should modify the user configuration on the server. If
    allow_srv_settings is false, the server settings will be ignored
    and will not be modified. Otherwise, the server settings will be
    read in and parsed, and will be modified by calls that modify
    the buddy list.

    aim_agent is the name of the client program as reported to the
    TOC server

    Returns a blessed instantiation of Net::AOLIM.

  $aim->signon()

    Call this after calling `new()' and after setting initial buddy
    listings with `add_buddies()', `im_permit()', `im_deny()',
    `im_permit_all()', and `im_deny_all()' as necessary.

    Returns undef on failure, setting $main::IM_ERR and
    $main::IM_ERR_ARGS as appropriate. Returns 0 on success.

    This function is also called every time we receive a SIGN_ON
    packet from the server. This is because we are required to react
    in a specific way to the SIGN_ON packet, and this method
    contains all necessary functionality. We should only receive
    SIGN_ON while connected if we have first received a PAUSE (see
    the TOC(7) documentation included with this package for details
    of how PAUSE works).

  $aim->read_sflap_packet()

    This method returns data from a single waiting SFLAP packet on
    the server socket. The returned value is the payload section of
    the SFLAP packet which is completely unparsed.

    Most users will never need to call this method.

    For more information, see ROLLING YOUR OWN below and the TOC(7)
    manpage.

  $aim->send_sflap_packet($type, $data, $formatted, $noterm)

    This method sends an SFLAP packet to the server.

    `$type' is one of the SFLAP types (see TOC(7)).

    `$data' is the payload to send.

    If `$formatted' evaluates to true, the data is assumed to be the
    completely formed payload of the SFLAP packet; otherwise, the
    payload will be packed as necessary. This defaults to 0. In
    either case, the header is prepended to the payload.

    If `$noterm' evaluates to true, the payload will not be
    terminated with a '\0'. Otherwise, it will be terminated. If
    `$formatted' is true, this option is ignored and no null is
    appended. This defaults to 0.

    Most users will never need to use this method.

    For more information, see TOC(7) and ROLLING YOUR OWN below.

  $aim->srv_socket()

    This method returns a reference to the socket to which the
    server is connected. It must be dereferenced before it can be
    used. Thus:

    `$foo = $aim->srv_socket();' `recv($$foo, $recv_buffer, $length,
    $flags);'

    Most users will never need to directly access the server socket.

    For more information, see the TOC(7) manpage and ROLLING YOUR
    OWN below.

  $aim->pw_roast($password)

    This method returns the 'roasted' version of a password. A
    roasted password is the original password XORed with the roast
    string 'Tic/Toc' (which is repeated until the length is the same
    as the password length).

    This method is called automatically in $aim->signon. Most users
    will never need this method.

    For more information, see the TOC(7) manpage and ROLLING YOUR
    OWN below.

  $aim->norm_uname($username)

    This method returns the 'normalized' version of a username. A
    normalized username has all spaces removed and is all lowercase.
    All usernames sent to the server should be normalized first if
    they are an argument to a TOC command.

    All methods in this class automatically normalize username
    arguments to the server; thus, most users will never use this
    method.

    For more information, see the TOC(7) manpage and ROLLING YOUR
    OWN below.

  $aim->toc_format_msg($command[, $arg1[, arg2[, ...]]])

    This method formats a message properly for sending to the TOC
    server. That is, it is escaped and quoted, and the fields are
    appended with spaces as specified by the protocol.

    Note that all methods in this class automatically format
    messages appropriately; most users will never need to call this
    method.

    See TOC(7) and ROLLING YOUR OWN below.

  $aim->toc_send_im($uname, $msg, $auto)

    This method sends an IM message `$msg' to the user specified by
    `$uname'. The third argument indicates whether or not this IM
    should be sent as an autoreply, which may produce different
    behavior from the remote client (but has no direct effect on the
    content of the IM).

  $aim->add_buddies($group, $buddy1[, $buddy2[, ...]])

    This method, which should only be called before signon(), adds
    buddies to the initial local buddy list in group `$group'. Once
    `signon()' is called, use add_online_buddies instead.

  $aim->add_online_buddies($group, $buddy1[, $buddy2[, ...]])

    This method takes the same arguments as `add_buddies()', but is
    intended for use after `signon()' has been called.

    If allow_srv_settings is true (see `new()'), it will also set
    the settings on the server to the new settings.

  $aim->remove_online_buddies($buddy1[, $buddy2[, ...]])

    Removes all arguments from the buddy list (removes from all
    groups).

    If allow_srv_settings is true (see `new()'), it will also set
    the settings on the server to the new settings.

  $aim->current_buddies(\%buddyhash)

    This method fills the hash referenced by `\%buddyhash' with the
    currently stored buddy information. Each key in the returned
    hash is the name of a buddy group, and the corresponding value
    is a list of the members of that group.

  $aim->current_permits()

    This method takes no arguments. It returns the current 'permit'
    list.

  $aim->current_denies()

    This method takes no arguments. It returns the current 'deny'
    list.

  $aim->im_permit($user1[, $user2[, ...]])

    This method should only be called before signon(). It adds all
    arguments to the current permit list and deletes the current
    deny list. It also sets the permit mode to 'permit some'.

    If you would like to do this while online, use the
    `add_im_permit()' method instead.

  $aim->im_deny($user1[, $user2[, ...]])

    This method should only be called before signon(). It adds all
    arguments to the current deny list and deletes the current
    permit list. It also sets the permit mode to 'deny some'.

    If you would like to do this while online, use the
    `add_im_permit()' method instead.

  $aim->add_im_permit($user1[, $user2[, ...]])

    This is the method that should be called if you are online and
    wish to add users to the permit list. It will, as a consequence,
    delete the current deny list and set the current mode to 'permit
    some'.

  $aim->add_im_deny($user1[, $user2[, ...]])

    This is the method that should be used if you are online and
    wish to add users to the deny list. It will, as a consequence,
    delete the current permit list and set the current mode to 'deny
    some'.

  $aim->im_deny_all()

    This method should be called only before signon(). It will
    delete both the permit and deny list and set the mode to 'deny
    all'.

  $aim->im_permit_all()

    This method should be called only before signon(). It will
    delete both the permit and deny list and set the mode to 'permit
    all'.

  $aim->add_im_deny_all()

    This is the method that should be used if you are online and
    wish to go into 'deny all' mode. It will also delete both the
    permit and deny lists.

  $aim->add_im_permit_all()

    This is the method that should be used if you are online and
    wish to go into 'permit all' mode. It will also delete both the
    permit and deny lists.

  $aim->toc_evil($user, $anon)

    This method will apply 'evil' to the specified user `$user'. If
    `$anon' evaluates to true, the evil will be done anonymously.

  $aim->toc_chat_join($exchange, $room_name)

    This method will join the chat room specified by `$exchange' and
    `$room_name'. Currently, the only valid value for `$exchange' is
    4.

    See the TOC(7) manpage included with this package for more
    information on chatting.

  $aim->toc_chat_send($roomid, $message)

    This method will send the message `$message' to the room
    `$roomid' (which should be the room ID provided by the server in
    response to a toc_chat_join or toc_accept_invite).

    You will receive this message back from the server as well, so
    your UI does not have to handle this message in a special way.

  $aim->toc_chat_whisper($roomid, $dstuser, $message)

    This method sends the message `$message' to `$dstuser' in the
    room `$roomid'.

    The server will not send you a copy of this message, so your
    user interface should have a special case for displaying
    outgoing whispers.

  $aim->toc_chat_evil($roomid, $dstuser, $anon)

    This will apply evil to the user `$dstuser' in room `$room'. If
    `$anon' evaluates to true, it will be applied anonymously.

    Please note that this functionality is currently disabled by the
    TOC servers.

  $aim->toc_chat_invite($roomid, $msgtext, $buddy1[, $buddy2[, ...]])

    This method will invite all users `$buddy1..$buddyN' to room
    `$roomid' with invitation text `$msgtext'.

  $aim->toc_chat_leave($roomid)

    This method will notify the server that you have left room
    `$roomid'.

  $aim->toc_chat_accept($roomid)

    This method accepts a chat invitation to room `$roomid'. You do
    not have to send a `toc_chat_join()' message if you have been
    invited and accept with this method.

  $aim->toc_get_info($username)

    This method requests info on user `$username'. See TOC(7) for
    more information on what the server returns.

  $aim->toc_set_info($info)

    This method sets the information for the current user to the
    ASCII text (HTML formatted) contained in `$info'.

  $aim->toc_set_away($msg)

    This method sets or unsets the away message. If `$msg' is
    undefined, away is unset. Otherwise, away is set with the
    message in `$msg'.

  $aim->toc_get_dir($username)

    This method sends a request to the server for directory
    information on `$username'. See TOC(7) for information on what
    the server will return.

  $aim->toc_set_dir($userinfo)

    This method sets the information on the current user to the
    string provided as `$userinfo'. See TOC(7) for more information
    on the format of the `$userinfo' string.

  $aim->toc_dir_search($searchstr)

    This method will search the directory using `$searchstr'. See
    TOC(7) for more information on how this string should look.

  $aim->toc_set_idle($seconds)

    This method sets the number of seconds that the client has been
    idle. If it is 0, the idle is cleared. Otherwise, the idle is
    set and the server will continue to count up the idle time
    (thus, you need only call `idle()' once in order to become
    idle).

  $aim->ui_add_fh($filehandle, \&callback)

    This method will add a filehandle to the `select()' loop that
    will be called with `ui_dataget()'. If information is found to
    be on that filehandle, the callback will be executed. It is the
    responsibility of the callback to read the data off the socket.

    Please be sure to set autoflushing on all filehandles passed to
    this method!

  $aim->ui_del_fh($filehandle)

    The filehandle `$filehandle' will be removed from the `select()'
    loop and it will no longer be checked for input nor its callback
    activated.

  $aim->ui_all_fh()

    This method returns a list of all filehandles currently in the
    `select()' loop.

  $aim->ui_exists_fh($filehandle)

    This method will return true if `$filehandle' is in the select
    loop. Otherwise, it will return undefined.

  $aim->ui_set_callback(\&callback)

    This method will change the callback function for the server
    socket to the method referenced by \&callback. This allows you
    to change the callback from the one specified when the object
    was created. (Imagine the possibilities--dynamically created
    callback functions using `eval()'... mmmm...)

  $aim->ui_get_callback($filehandle)

    This method returns a reference to the callback associated with
    $filehandle, or the callback associated with the server socket
    if $filehandle is undefined.

  $aim->ui_dataget($timeout)

    This is the workhorse method in this object. When this method is
    called, it will go through a single `select()' loop to find if
    any filehandles are ready for reading. If $timeout is defined,
    the `select()' timeout will be that number of seconds (fractions
    are OK). Otherwise, `select()' will block.

    For each filehandle that is ready for reading, this function
    will call the appropriate callback function. It is the
    responsibility of the callback to read the data off the
    filehandle and handle it appropriately. The exception to this
    rule is the server socket, whose data will be read and passed to
    the server socket callback function. All pasrsing of data from
    the server into edible chunks will be done for you before the
    server socket callback function is called. From there, it is up
    to to the client program to parse the server responses
    appropriately. They will be passed such that each field in the
    server response is one argument to the callback (the number of
    arguments will be correct). For more information on the
    information coming from the server, see TOC(7).

    This method returns undef on an error (including errors from
    callbacks, which should be signified by returning undef) and
    returns the number of filehandles that were read otherwise.

ROLLING YOUR OWN
    This section deals with usage that deals directly with the
    server connection and bypasses the ui_* interface and/or the
    toc_* interface. If you are happy calling ui_dataget et al., do
    not bother reading this section. If, however, you plan not to
    use the provided interfaces, or if you want to know more of what
    is going on, continue on.

    First of all, if you do not plan to use the provided interface
    to the server socket, you will need to be able to access the
    server socket directly. In order to do this, use $aim-
    >srv_socket:

        $srv_sock = $aim->srv_socket;

    This will return a pointer to the socket. You will need to
    dereference it in order to use it.

    In general, however, even if you are rolling your own, you will
    probably not need to use `recv()' or the like.
    `read_sflap_packet()' will handle unwrapping the data coming
    from the server and will return the payload of the packet as a
    single scalar. Using this will give you the data coming from the
    server in a form that you can `split()' to get the message and
    its arguments. In order to facilitate such splitting,
    `%Net::AOLIM::SERVER_MSG_ARGS' is supplied. For each valid
    server message, `$Net::AOLIM::SERVER_MSG_ARGS{$msg}' will return
    one less than the proper number of splits to perform on the data
    coming from the server. The intended use is such:

        ($msg, $rest) = split(/:/, $aim->read_sflap_packet(), 2);
        @msg_args = split(/:/, $rest, $Net::AOLIM::SERVER_MSG_ARGS{$msg});

    Now you have the server message in `$msg' and the arguments in
    `@msg_args'.

    To send packets to the server without having to worry about
    making SFLAP packets, use `send_sflap_packet()'. If you have a
    string to send to the server (which is not formatted), you would
    use:

        $aim->send_sflap_packet($SFLAP_TYPE_DATA, $message, 0, 0);

    The SFLAP types (listed in TOC(7) are:

        $SFLAP_TYPE_SIGNON
        $SFLAP_TYPE_DATA
        $SFLAP_TYPE_ERROR
        $SFLAP_TYPE_SIGNOFF
        $SFLAP_TYPE_KEEPALIVE

    Most of the time you will use $SFLAP_TYPE_DATA.

    If you want to roll your own messages, read the code for
    `send_sflap_packet()' and you should be able to figure it out.
    Note that the header is always supplied by
    `send_sflap_packet()'. Specifying `formatted' will only make
    `send_sflap_data()' assume that `$message' is a preformatted
    payload. Specifying `$noterm' will prevent `send_sflap_packet()'
    from adding a trailing '\0' to the payload. If it is already
    formatted, `send_sflap_packet' will ignore `$noterm'.

    Messages sent to the server should be escaped and formatted
    properly as defined in TOC(7). `$aim->toc_format_msg' will do
    just this; supply it with the TOC command and the arguments to
    the TOC command (each as separate strings) and it will return a
    single string that is formatted appropriately.

    All usernames sent as TOC command arguments must be normalized
    (see TOC(7)). `$aim->norm_uname()' will do just this. Make sure
    to normalize usernames before passing them as arguments to
    `$aim->toc_format_msg()'.

    `pw_roast' performs roasting as defined in TOC(7). It is not
    very exciting. I do not see why it is that you would ever need
    to do this, as `$aim->signon()' handles this for you (and the
    roasted password is stored in `$aim->{'roastedp'}'). However, if
    you want to play with it, there it is.

EXAMPLES
    See the file example.pl for an example of how to interact with
    this class.

FILES
    example.pl A sample client that demonstrates how this object
    could be used.

SEE ALSO
    See also TOC(7).

AUTHOR
    Copyright (C) 2000 Riad Wahby <rsw@mit.edu> All rights reserved
    This program is free software. You may redistribute it and/or
    modify it under the same terms as Perl itself.

HISTORY
    0.01 Initial Beta Release. (7/7/00)

    0.1 First public (CPAN) release. (7/14/00)

    0.11 Re-release under a different name with minor changes to the
    documentation. (7/16/00)

    0.12 Minor modification to fix a condition in which the server's
    connection closing could cause an infinite loop.

    1.0 Changed the client agent string to TOC1.0 to fix a problem
    where connections were sometimes ignored. Also changed the
    default signon port to 5198 and the login port to 1234.

